/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11GTK.cs
C# | 4732 lines | 3616 code | 894 blank | 222 comment | 662 complexity | e0883dca3567277fc2ace0937d6d8fd2 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- // 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-2006 Novell, Inc.
- //
- // Authors:
- // Peter Bartok pbartok@novell.com
- // Alexander Olk alex.olk@googlemail.com
- //
- //
- // NOTE:
- // This driver understands the following environment variables: (Set the var to enable feature)
- //
- // MONO_XEXCEPTIONS = throw an exception when a X11 error is encountered;
- // by default a message is displayed but execution continues
- //
- // MONO_XSYNC = perform all X11 commands synchronous; this is slower but
- // helps in debugging errors
- //
- // NOT COMPLETE - WORK IN PROGRESS
- // One feature of the driver is, that PaintEventstart returns a graphics context created from a offscreen drawable (pixmap)
- // define to log Window handles and relationships to stdout
- #undef DriverDebug
- // Extra detailed debug
- #undef DriverDebugExtra
- using System;
- using System.ComponentModel;
- using System.Collections;
- using System.Diagnostics;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Net;
- using System.Net.Sockets;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading;
- // Only do the poll when building with mono for now
- #if __MonoCS__
- using Mono.Unix.Native;
- #endif
- /// X11 Version
- namespace System.Windows.Forms {
- internal class XplatUIX11GTK : XplatUIDriver {
-
- internal enum GdkWindowClass {
- GDK_INPUT_OUTPUT,
- GDK_INPUT_ONLY
- }
-
- internal enum GdkWindowType {
- GDK_WINDOW_ROOT,
- GDK_WINDOW_TOPLEVEL,
- GDK_WINDOW_CHILD,
- GDK_WINDOW_DIALOG,
- GDK_WINDOW_TEMP,
- GDK_WINDOW_FOREIGN
- }
-
- internal enum GdkWindowHints {
- GDK_HINT_POS = 1 << 0,
- GDK_HINT_MIN_SIZE = 1 << 1,
- GDK_HINT_MAX_SIZE = 1 << 2,
- GDK_HINT_BASE_SIZE = 1 << 3,
- GDK_HINT_ASPECT = 1 << 4,
- GDK_HINT_RESIZE_INC = 1 << 5,
- GDK_HINT_WIN_GRAVITY = 1 << 6,
- GDK_HINT_USER_POS = 1 << 7,
- GDK_HINT_USER_SIZE = 1 << 8
- }
-
- internal enum GdkGravity {
- GDK_GRAVITY_NORTH_WEST = 1,
- GDK_GRAVITY_NORTH,
- GDK_GRAVITY_NORTH_EAST,
- GDK_GRAVITY_WEST,
- GDK_GRAVITY_CENTER,
- GDK_GRAVITY_EAST,
- GDK_GRAVITY_SOUTH_WEST,
- GDK_GRAVITY_SOUTH,
- GDK_GRAVITY_SOUTH_EAST,
- GDK_GRAVITY_STATIC
- }
-
- internal enum GdkWindowEdge {
- GDK_WINDOW_EDGE_NORTH_WEST,
- GDK_WINDOW_EDGE_NORTH,
- GDK_WINDOW_EDGE_NORTH_EAST,
- GDK_WINDOW_EDGE_WEST,
- GDK_WINDOW_EDGE_EAST,
- GDK_WINDOW_EDGE_SOUTH_WEST,
- GDK_WINDOW_EDGE_SOUTH,
- GDK_WINDOW_EDGE_SOUTH_EAST
- }
-
- internal enum GdkWindowTypeHint {
- GDK_WINDOW_TYPE_HINT_NORMAL,
- GDK_WINDOW_TYPE_HINT_DIALOG,
- GDK_WINDOW_TYPE_HINT_MENU,
- GDK_WINDOW_TYPE_HINT_TOOLBAR,
- GDK_WINDOW_TYPE_HINT_SPLASHSCREEN,
- GDK_WINDOW_TYPE_HINT_UTILITY,
- GDK_WINDOW_TYPE_HINT_DOCK,
- GDK_WINDOW_TYPE_HINT_DESKTOP
- }
-
- internal enum GdkWindowAttributesType {
- GDK_WA_TITLE = 1 << 1,
- GDK_WA_X = 1 << 2,
- GDK_WA_Y = 1 << 3,
- GDK_WA_CURSOR = 1 << 4,
- GDK_WA_COLORMAP = 1 << 5,
- GDK_WA_VISUAL = 1 << 6,
- GDK_WA_WMCLASS = 1 << 7,
- GDK_WA_NOREDIR = 1 << 8
- }
-
- internal enum GdkEventMask {
- GDK_EXPOSURE_MASK = 1 << 1,
- GDK_POINTER_MOTION_MASK = 1 << 2,
- GDK_POINTER_MOTION_HINT_MASK = 1 << 3,
- GDK_BUTTON_MOTION_MASK = 1 << 4,
- GDK_BUTTON1_MOTION_MASK = 1 << 5,
- GDK_BUTTON2_MOTION_MASK = 1 << 6,
- GDK_BUTTON3_MOTION_MASK = 1 << 7,
- GDK_BUTTON_PRESS_MASK = 1 << 8,
- GDK_BUTTON_RELEASE_MASK = 1 << 9,
- GDK_KEY_PRESS_MASK = 1 << 10,
- GDK_KEY_RELEASE_MASK = 1 << 11,
- GDK_ENTER_NOTIFY_MASK = 1 << 12,
- GDK_LEAVE_NOTIFY_MASK = 1 << 13,
- GDK_FOCUS_CHANGE_MASK = 1 << 14,
- GDK_STRUCTURE_MASK = 1 << 15,
- GDK_PROPERTY_CHANGE_MASK = 1 << 16,
- GDK_VISIBILITY_NOTIFY_MASK = 1 << 17,
- GDK_PROXIMITY_IN_MASK = 1 << 18,
- GDK_PROXIMITY_OUT_MASK = 1 << 19,
- GDK_SUBSTRUCTURE_MASK = 1 << 20,
- GDK_SCROLL_MASK = 1 << 21,
- GDK_ALL_EVENTS_MASK = 0x3FFFFE
- }
-
- internal enum GdkEventType {
- GDK_NOTHING = -1,
- GDK_DELETE = 0,
- GDK_DESTROY = 1,
- GDK_EXPOSE = 2,
- GDK_MOTION_NOTIFY = 3,
- GDK_BUTTON_PRESS = 4,
- GDK_2BUTTON_PRESS = 5,
- GDK_3BUTTON_PRESS = 6,
- GDK_BUTTON_RELEASE = 7,
- GDK_KEY_PRESS = 8,
- GDK_KEY_RELEASE = 9,
- GDK_ENTER_NOTIFY = 10,
- GDK_LEAVE_NOTIFY = 11,
- GDK_FOCUS_CHANGE = 12,
- GDK_CONFIGURE = 13,
- GDK_MAP = 14,
- GDK_UNMAP = 15,
- GDK_PROPERTY_NOTIFY = 16,
- GDK_SELECTION_CLEAR = 17,
- GDK_SELECTION_REQUEST = 18,
- GDK_SELECTION_NOTIFY = 19,
- GDK_PROXIMITY_IN = 20,
- GDK_PROXIMITY_OUT = 21,
- GDK_DRAG_ENTER = 22,
- GDK_DRAG_LEAVE = 23,
- GDK_DRAG_MOTION = 24,
- GDK_DRAG_STATUS = 25,
- GDK_DROP_START = 26,
- GDK_DROP_FINISHED = 27,
- GDK_CLIENT_EVENT = 28,
- GDK_VISIBILITY_NOTIFY = 29,
- GDK_NO_EXPOSE = 30,
- GDK_SCROLL = 31,
- GDK_WINDOW_STATE = 32,
- GDK_SETTING = 33,
- GDK_OWNER_CHANGE = 34,
- GDK_GRAB_BROKEN = 35
- }
-
- internal enum GdkWMDecoration {
- GDK_DECOR_ALL = 1 << 0,
- GDK_DECOR_BORDER = 1 << 1,
- GDK_DECOR_RESIZEH = 1 << 2,
- GDK_DECOR_TITLE = 1 << 3,
- GDK_DECOR_MENU = 1 << 4,
- GDK_DECOR_MINIMIZE = 1 << 5,
- GDK_DECOR_MAXIMIZE = 1 << 6
- }
-
- internal enum GdkWMFunction {
- GDK_FUNC_ALL = 1 << 0,
- GDK_FUNC_RESIZE = 1 << 1,
- GDK_FUNC_MOVE = 1 << 2,
- GDK_FUNC_MINIMIZE = 1 << 3,
- GDK_FUNC_MAXIMIZE = 1 << 4,
- GDK_FUNC_CLOSE = 1 << 5
- }
-
- internal enum GdkCursorType {
- GDK_X_CURSOR = 0,
- GDK_ARROW = 2,
- GDK_BASED_ARROW_DOWN = 4,
- GDK_BASED_ARROW_UP = 6,
- GDK_BOAT = 8,
- GDK_BOGOSITY = 10,
- GDK_BOTTOM_LEFT_CORNER = 12,
- GDK_BOTTOM_RIGHT_CORNER = 14,
- GDK_BOTTOM_SIDE = 16,
- GDK_BOTTOM_TEE = 18,
- GDK_BOX_SPIRAL = 20,
- GDK_CENTER_PTR = 22,
- GDK_CIRCLE = 24,
- GDK_CLOCK = 26,
- GDK_COFFEE_MUG = 28,
- GDK_CROSS = 30,
- GDK_CROSS_REVERSE = 32,
- GDK_CROSSHAIR = 34,
- GDK_DIAMOND_CROSS = 36,
- GDK_DOT = 38,
- GDK_DOTBOX = 40,
- GDK_DOUBLE_ARROW = 42,
- GDK_DRAFT_LARGE = 44,
- GDK_DRAFT_SMALL = 46,
- GDK_DRAPED_BOX = 48,
- GDK_EXCHANGE = 50,
- GDK_FLEUR = 52,
- GDK_GOBBLER = 54,
- GDK_GUMBY = 56,
- GDK_HAND1 = 58,
- GDK_HAND2 = 60,
- GDK_HEART = 62,
- GDK_ICON = 64,
- GDK_IRON_CROSS = 66,
- GDK_LEFT_PTR = 68,
- GDK_LEFT_SIDE = 70,
- GDK_LEFT_TEE = 72,
- GDK_LEFTBUTTON = 74,
- GDK_LL_ANGLE = 76,
- GDK_LR_ANGLE = 78,
- GDK_MAN = 80,
- GDK_MIDDLEBUTTON = 82,
- GDK_MOUSE = 84,
- GDK_PENCIL = 86,
- GDK_PIRATE = 88,
- GDK_PLUS = 90,
- GDK_QUESTION_ARROW = 92,
- GDK_RIGHT_PTR = 94,
- GDK_RIGHT_SIDE = 96,
- GDK_RIGHT_TEE = 98,
- GDK_RIGHTBUTTON = 100,
- GDK_RTL_LOGO = 102,
- GDK_SAILBOAT = 104,
- GDK_SB_DOWN_ARROW = 106,
- GDK_SB_H_DOUBLE_ARROW = 108,
- GDK_SB_LEFT_ARROW = 110,
- GDK_SB_RIGHT_ARROW = 112,
- GDK_SB_UP_ARROW = 114,
- GDK_SB_V_DOUBLE_ARROW = 116,
- GDK_SHUTTLE = 118,
- GDK_SIZING = 120,
- GDK_SPIDER = 122,
- GDK_SPRAYCAN = 124,
- GDK_STAR = 126,
- GDK_TARGET = 128,
- GDK_TCROSS = 130,
- GDK_TOP_LEFT_ARROW = 132,
- GDK_TOP_LEFT_CORNER = 134,
- GDK_TOP_RIGHT_CORNER = 136,
- GDK_TOP_SIDE = 138,
- GDK_TOP_TEE = 140,
- GDK_TREK = 142,
- GDK_UL_ANGLE = 144,
- GDK_UMBRELLA = 146,
- GDK_UR_ANGLE = 148,
- GDK_WATCH = 150,
- GDK_XTERM = 152,
- GDK_LAST_CURSOR,
- GDK_CURSOR_IS_PIXMAP = -1
- }
-
- internal enum GdkPropMode {
- GDK_PROP_MODE_REPLACE,
- GDK_PROP_MODE_PREPEND,
- GDK_PROP_MODE_APPEND
- }
-
- [StructLayout (LayoutKind.Sequential)]
- internal struct GdkGeometry {
- internal int min_width;
- internal int min_height;
- internal int max_width;
- internal int max_height;
- internal int base_width;
- internal int base_height;
- internal int width_inc;
- internal int height_inc;
- internal double min_aspect;
- internal double max_aspect;
- internal GdkGravity win_gravity;
- }
-
- [StructLayout (LayoutKind.Sequential)]
- internal struct GdkWindowAttr {
- internal string title;
- internal int event_mask;
- internal int x, y;
- internal int width;
- internal int height;
- internal GdkWindowClass wclass;
- internal IntPtr visual;
- internal IntPtr colormap;
- internal GdkWindowType window_type;
- internal IntPtr cursor;
- internal string wmclass_name;
- internal string wmclass_class;
- internal bool override_redirect;
- }
-
- #region Local Variables
- // General
- static volatile XplatUIX11GTK Instance;
- private static int RefCount;
- private static object XlibLock; // Our locking object
- private static bool ThemesEnabled;
-
- // General X11
- private static IntPtr DisplayHandle; // X11 handle to display
- private static IntPtr GdkDisplayHandle; // gdk handle to display
- private static int ScreenNo; // Screen number used
- private static IntPtr GdkScreen;
- private static IntPtr DefaultColormap; // Colormap for screen
- private static IntPtr GdkDefaultColormap; // Gdk Colormap for screen
- private static IntPtr CustomVisual; // Visual for window creation
- private static IntPtr GdkCustomVisual;
- private static IntPtr CustomColormap; // Colormap for window creation
- private static IntPtr GdkCustomColormap;
- private static int VisualBestDepth;
- private static IntPtr RootWindow; // Handle of the root window for the screen/display
- private static IntPtr GdkRootWindow; // Gdk handle of the root window for the screen/display
- private static IntPtr FosterParent; // Container to hold child windows until their parent exists
- private static IntPtr GdkFosterParent; // Container to hold child windows until their parent exists
- private static XErrorHandler ErrorHandler; // Error handler delegate
- private static bool ErrorExceptions; // Throw exceptions on X errors
- private static bool PostQuitState; // True if we've got an pending exit
-
- // Clipboard
- private static IntPtr ClipMagic = new IntPtr(27051977);
- private static ClipboardStruct Clipboard; // Our clipboard
-
- // Communication
- private static int PostAtom; // PostMessage atom
- private static int AsyncAtom; // Support for async messages
-
- // Message Loop
- private static XEventQueue MessageQueue; // Holds our queued up events
- #if __MonoCS__ //
- private static Pollfd[] pollfds; // For watching the X11 socket
- #endif //
- private static X11Keyboard Keyboard; //
- private static X11Dnd Dnd;
- private static Socket listen; //
- private static Socket wake; //
- private static Socket wake_receive; //
- private static byte[] network_buffer; //
-
-
- // Focus tracking
- private static IntPtr ActiveWindow; // Handle of the active window
- private static IntPtr FocusWindow; // Handle of the window with keyboard focus (if any)
-
- // Modality support
- private static Stack ModalWindows; // Stack of our modal windows
-
- // Systray
- private static IntPtr SystrayMgrWindow; // Handle of the Systray Manager window
-
- // Cursors
- private static IntPtr LastCursorWindow; // The last window we set the cursor on
- private static IntPtr LastCursorHandle; // The handle that was last set on LastCursorWindow
- private static IntPtr OverrideCursorHandle; // The cursor that is set to override any other cursors
-
- // Caret
- private static CaretStruct Caret; //
-
- // Support for Window Styles
- private static int[] NetAtoms; // All atoms we know
-
- // mouse hover message generation
- private static HoverStruct HoverState; //
-
- // double click message generation
- private static ClickStruct ClickPending; //
-
- // Support for mouse grab
- private static GrabStruct Grab; //
-
- // State
- private static Point MousePosition; // Last position of mouse, in screen coords
- internal static MouseButtons MouseState; // Last state of mouse buttons
-
- // Timers
- private static ArrayList TimerList; // Holds SWF.Timers
-
- // 'Constants'
- private static int DoubleClickInterval; // msec; max interval between clicks to count as double click
-
- const GdkEventMask GdkSelectInputMask = GdkEventMask.GDK_BUTTON_PRESS_MASK |
- GdkEventMask.GDK_BUTTON_RELEASE_MASK |
- GdkEventMask.GDK_KEY_PRESS_MASK |
- GdkEventMask.GDK_KEY_RELEASE_MASK |
- GdkEventMask.GDK_ENTER_NOTIFY_MASK |
- GdkEventMask.GDK_LEAVE_NOTIFY_MASK |
- GdkEventMask.GDK_EXPOSURE_MASK |
- GdkEventMask.GDK_FOCUS_CHANGE_MASK |
- GdkEventMask.GDK_POINTER_MOTION_MASK |
- GdkEventMask.GDK_VISIBILITY_NOTIFY_MASK |
- GdkEventMask.GDK_SUBSTRUCTURE_MASK |
- GdkEventMask.GDK_STRUCTURE_MASK;
-
- static readonly object lockobj = new object ();
-
- static Hashtable backing_store = new Hashtable (5);
-
- #endregion // Local Variables
- #region Constructors
- private XplatUIX11GTK ()
- {
- Console.WriteLine ("XplatUIX11GTK ctor...");
- // Handle singleton stuff first
- RefCount = 0;
-
- // init gdk
- gdk_init_check (IntPtr.Zero, IntPtr.Zero);
-
- // Now regular initialization
- XlibLock = new object ();
- MessageQueue = new XEventQueue ();
- TimerList = new ArrayList ();
- XInitThreads ();
-
- ErrorExceptions = false;
-
- // X11 Initialization
- SetDisplay (gdk_x11_display_get_xdisplay (gdk_display_get_default ()));
- X11DesktopColors.Initialize ();
-
- // Handle any upcoming errors; we re-set it here, X11DesktopColor stuff might have stolen it (gtk does)
- ErrorHandler = new XErrorHandler (HandleError);
- XSetErrorHandler (ErrorHandler);
- }
- #endregion // Constructors
-
- #region Singleton Specific Code
- public static XplatUIX11GTK GetInstance ()
- {
- lock (lockobj) {
- if (Instance == null) {
- Instance = new XplatUIX11GTK ();
- }
- RefCount++;
- }
- return Instance;
- }
-
- public int Reference {
- get {
- return RefCount;
- }
- }
- #endregion
-
- #region Internal Properties
- internal static IntPtr Display {
- get {
- return DisplayHandle;
- }
-
- set {
- XplatUIX11GTK.GetInstance ().SetDisplay (value);
- }
- }
-
- internal static int Screen {
- get {
- return ScreenNo;
- }
-
- set {
- ScreenNo = value;
- }
- }
-
- internal static IntPtr RootWindowHandle {
- get {
- return RootWindow;
- }
-
- set {
- RootWindow = value;
- }
- }
-
- internal static IntPtr Visual {
- get {
- return CustomVisual;
- }
-
- set {
- CustomVisual = value;
- }
- }
-
- internal static IntPtr ColorMap {
- get {
- return CustomColormap;
- }
-
- set {
- CustomColormap = value;
- }
- }
- #endregion
-
- #region XExceptionClass
- internal class XException : ApplicationException {
- IntPtr Display;
- IntPtr ResourceID;
- IntPtr Serial;
- XRequest RequestCode;
- byte ErrorCode;
- byte MinorCode;
-
- public XException (IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode)
- {
- this.Display = Display;
- this.ResourceID = ResourceID;
- this.Serial = Serial;
- this.RequestCode = RequestCode;
- this.ErrorCode = ErrorCode;
- this.MinorCode = MinorCode;
- }
-
- public override string Message {
- get {
- return GetMessage (Display, ResourceID, Serial, ErrorCode, RequestCode, MinorCode);
- }
- }
-
- public static string GetMessage (IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode)
- {
- StringBuilder sb;
- string x_error_text;
- string error;
-
- sb = new StringBuilder (160);
- XGetErrorText (Display, ErrorCode, sb, sb.Capacity);
- x_error_text = sb.ToString ();
-
- error = String.Format ("\n Error: {0}\n Request: {1:D} ({2})\n Resource ID: 0x{3:x}\n Serial: {4}", x_error_text, RequestCode, RequestCode, ResourceID.ToInt32 (), Serial);
- return error;
- }
- }
- #endregion // XExceptionClass
-
- #region Internal Methods
- // native X display handle
- internal void SetDisplay (IntPtr display_handle)
- {
- if (display_handle != IntPtr.Zero) {
- Hwnd hwnd;
-
- if ((GdkDisplayHandle != IntPtr.Zero) && (GdkFosterParent != IntPtr.Zero)) {
- hwnd = Hwnd.ObjectFromHandle (gdk_x11_drawable_get_xid (GdkFosterParent));
- gdk_window_destroy (GdkFosterParent);
- hwnd.Dispose ();
- }
-
- if (GdkDisplayHandle != IntPtr.Zero) {
- gdk_display_close (GdkDisplayHandle);
- }
-
- DisplayHandle = display_handle;
- GdkDisplayHandle = gdk_x11_lookup_xdisplay (display_handle);
-
- // We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
- // been hacked to do this for us.
- Graphics.FromHdcInternal (DisplayHandle);
-
- // Debugging support
- if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
- XSynchronize (DisplayHandle, true);
- }
-
- if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
- ErrorExceptions = true;
- }
-
- // Generic X11 setup
- GdkScreen = gdk_screen_get_default ();
- // or gdk_x11_get_default_screen
- ScreenNo = gdk_screen_get_number (GdkScreen);
- GdkRootWindow = gdk_get_default_root_window ();
- RootWindow = gdk_x11_drawable_get_xid (GdkRootWindow);
- GdkDefaultColormap = gdk_colormap_get_system ();
- DefaultColormap = gdk_x11_colormap_get_xcolormap (GdkDefaultColormap);
-
- VisualBestDepth = gdk_visual_get_best_depth ();
- //Console.WriteLine (VisualBestDepth);
-
- // Create the foster parent
- FosterParent = XCreateSimpleWindow (DisplayHandle, RootWindow, 0, 0, 1, 1, 4, 0, 0);
- GdkFosterParent = gdk_window_foreign_new (FosterParent);
-
- if (GdkFosterParent == IntPtr.Zero) {
- Console.WriteLine ("XplatUIX11GTK Constructor failed to create FosterParent");
- }
-
- hwnd = new Hwnd ();
-
- hwnd.WholeWindow = FosterParent;
- hwnd.ClientWindow = FosterParent;
-
- // For sleeping on the X11 socket
- listen = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
- IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 0);
- listen.Bind (ep);
- listen.Listen (1);
-
- // To wake up when a timer is ready
- network_buffer = new byte [10];
-
- wake = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
- wake.Connect (listen.LocalEndPoint);
- wake_receive = listen.Accept ();
-
- #if __MonoCS__
- pollfds = new Pollfd [2];
- pollfds [0] = new Pollfd ();
- pollfds [0].fd = XConnectionNumber (DisplayHandle);
- pollfds [0].events = PollEvents.POLLIN;
- pollfds [1] = new Pollfd ();
- pollfds [1].fd = wake_receive.Handle.ToInt32 ();
- pollfds [1].events = PollEvents.POLLIN;
- #endif
-
- Keyboard = new X11Keyboard (DisplayHandle);
- Dnd = new X11Dnd (DisplayHandle);
-
- PostQuitState = false;
-
- DoubleClickInterval = 500;
-
- HoverState.Interval = 500;
- HoverState.Timer = new Timer ();
- HoverState.Timer.Enabled = false;
- HoverState.Timer.Interval = HoverState.Interval;
- HoverState.Timer.Tick += new EventHandler (MouseHover);
- HoverState.X = -1;
- HoverState.Y = -1;
-
- ActiveWindow = IntPtr.Zero;
- FocusWindow = IntPtr.Zero;
- ModalWindows = new Stack (3);
-
- MouseState = MouseButtons.None;
- MousePosition = new Point (0, 0);
-
- Caret.Timer = new Timer ();
- Caret.Timer.Interval = 500; // FIXME - where should this number come from?
- Caret.Timer.Tick += new EventHandler (CaretCallback);
-
- SetupAtoms ();
-
- // Grab atom changes off the root window to catch certain WM events
- gdk_window_set_events (GdkRootWindow, (int)GdkEventMask.GDK_PROPERTY_CHANGE_MASK);
-
- // Handle any upcoming errors
- ErrorHandler = new XErrorHandler (HandleError);
- XSetErrorHandler (ErrorHandler);
- } else {
- throw new ArgumentNullException ("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
- }
- }
- #endregion // Internal Methods
-
- #region Private Methods
- private static void SetupAtoms ()
- {
- NetAtoms = new int [(int)NA.LAST_NET_ATOM];
-
- NetAtoms [(int)NA.WM_PROTOCOLS] = XInternAtom (DisplayHandle, "WM_PROTOCOLS", false);
- NetAtoms [(int)NA.WM_DELETE_WINDOW] = XInternAtom (DisplayHandle, "WM_DELETE_WINDOW", false);
- NetAtoms [(int)NA.WM_TAKE_FOCUS] = XInternAtom (DisplayHandle, "WM_TAKE_FOCUS", false);
-
- NetAtoms [(int)NA._NET_SUPPORTED] = XInternAtom (DisplayHandle, "_NET_SUPPORTED", false);
- NetAtoms [(int)NA._NET_CLIENT_LIST] = XInternAtom (DisplayHandle, "_NET_CLIENT_LIST", false);
- NetAtoms [(int)NA._NET_NUMBER_OF_DESKTOPS] = XInternAtom (DisplayHandle, "_NET_NUMBER_OF_DESKTOPS", false);
- NetAtoms [(int)NA._NET_DESKTOP_GEOMETRY] = XInternAtom (DisplayHandle, "_NET_DESKTOP_GEOMETRY", false);
- NetAtoms [(int)NA._NET_DESKTOP_VIEWPORT] = XInternAtom (DisplayHandle, "_NET_DESKTOP_VIEWPORT", false);
- NetAtoms [(int)NA._NET_CURRENT_DESKTOP] = XInternAtom (DisplayHandle, "_NET_CURRENT_DESKTOP", false);
- NetAtoms [(int)NA._NET_DESKTOP_NAMES] = XInternAtom (DisplayHandle, "_NET_DESKTOP_NAMES", false);
- NetAtoms [(int)NA._NET_ACTIVE_WINDOW] = XInternAtom (DisplayHandle, "_NET_ACTIVE_WINDOW", false);
- NetAtoms [(int)NA._NET_WORKAREA] = XInternAtom (DisplayHandle, "_NET_WORKAREA", false);
- NetAtoms [(int)NA._NET_SUPPORTING_WM_CHECK] = XInternAtom (DisplayHandle, "_NET_SUPPORTING_WM_CHECK", false);
- NetAtoms [(int)NA._NET_VIRTUAL_ROOTS] = XInternAtom (DisplayHandle, "_NET_VIRTUAL_ROOTS", false);
- NetAtoms [(int)NA._NET_DESKTOP_LAYOUT] = XInternAtom (DisplayHandle, "_NET_DESKTOP_LAYOUT", false);
- NetAtoms [(int)NA._NET_SHOWING_DESKTOP] = XInternAtom (DisplayHandle, "_NET_SHOWING_DESKTOP", false);
-
- NetAtoms [(int)NA._NET_CLOSE_WINDOW] = XInternAtom (DisplayHandle, "_NET_CLOSE_WINDOW", false);
- NetAtoms [(int)NA._NET_MOVERESIZE_WINDOW] = XInternAtom (DisplayHandle, "_NET_MOVERESIZE_WINDOW", false);
- NetAtoms [(int)NA._NET_WM_MOVERESIZE] = XInternAtom (DisplayHandle, "_NET_WM_MOVERESIZE", false);
- NetAtoms [(int)NA._NET_RESTACK_WINDOW] = XInternAtom (DisplayHandle, "_NET_RESTACK_WINDOW", false);
- NetAtoms [(int)NA._NET_REQUEST_FRAME_EXTENTS] = XInternAtom (DisplayHandle, "_NET_REQUEST_FRAME_EXTENTS", false);
-
- NetAtoms [(int)NA._NET_WM_NAME] = XInternAtom (DisplayHandle, "_NET_WM_NAME", false);
- NetAtoms [(int)NA._NET_WM_VISIBLE_NAME] = XInternAtom (DisplayHandle, "_NET_WM_VISIBLE_NAME", false);
- NetAtoms [(int)NA._NET_WM_ICON_NAME] = XInternAtom (DisplayHandle, "_NET_WM_ICON_NAME", false);
- NetAtoms [(int)NA._NET_WM_VISIBLE_ICON_NAME] = XInternAtom (DisplayHandle, "_NET_WM_VISIBLE_ICON_NAME", false);
- NetAtoms [(int)NA._NET_WM_DESKTOP] = XInternAtom (DisplayHandle, "_NET_WM_DESKTOP", false);
- NetAtoms [(int)NA._NET_WM_WINDOW_TYPE] = XInternAtom (DisplayHandle, "_NET_WM_WINDOW_TYPE", false);
- NetAtoms [(int)NA._NET_WM_STATE] = XInternAtom (DisplayHandle, "_NET_WM_STATE", false);
- NetAtoms [(int)NA._NET_WM_ALLOWED_ACTIONS] = XInternAtom (DisplayHandle, "_NET_WM_ALLOWED_ACTIONS", false);
- NetAtoms [(int)NA._NET_WM_STRUT] = XInternAtom (DisplayHandle, "_NET_WM_STRUT", false);
- NetAtoms [(int)NA._NET_WM_STRUT_PARTIAL] = XInternAtom (DisplayHandle, "_NET_WM_STRUT_PARTIAL", false);
- NetAtoms [(int)NA._NET_WM_ICON_GEOMETRY] = XInternAtom (DisplayHandle, "_NET_WM_ICON_GEOMETRY", false);
- NetAtoms [(int)NA._NET_WM_ICON] = XInternAtom (DisplayHandle, "_NET_WM_ICON", false);
- NetAtoms [(int)NA._NET_WM_PID] = XInternAtom (DisplayHandle, "_NET_WM_PID", false);
- NetAtoms [(int)NA._NET_WM_HANDLED_ICONS] = XInternAtom (DisplayHandle, "_NET_WM_HANDLED_ICONS", false);
- NetAtoms [(int)NA._NET_WM_USER_TIME] = XInternAtom (DisplayHandle, "_NET_WM_USER_TIME", false);
- NetAtoms [(int)NA._NET_FRAME_EXTENTS] = XInternAtom (DisplayHandle, "_NET_FRAME_EXTENTS", false);
-
- NetAtoms [(int)NA._NET_WM_PING] = XInternAtom (DisplayHandle, "_NET_WM_PING", false);
- NetAtoms [(int)NA._NET_WM_SYNC_REQUEST] = XInternAtom (DisplayHandle, "_NET_WM_SYNC_REQUEST", false);
-
- NetAtoms [(int)NA._NET_SYSTEM_TRAY_S] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString (), false);
- NetAtoms [(int)NA._NET_SYSTEM_TRAY_OPCODE] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_OPCODE", false);
- NetAtoms [(int)NA._NET_SYSTEM_TRAY_ORIENTATION] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_ORIENTATION", false);
-
- NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
- NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MAXIMIZED_VERT", false);
- NetAtoms [(int)NA._NET_WM_STATE_HIDDEN] = XInternAtom (DisplayHandle, "_NET_WM_STATE_HIDDEN", false);
-
- NetAtoms [(int)NA._XEMBED] = XInternAtom (DisplayHandle, "_XEMBED", false);
- NetAtoms [(int)NA._XEMBED_INFO] = XInternAtom (DisplayHandle, "_XEMBED_INFO", false);
-
- NetAtoms [(int)NA._MOTIF_WM_HINTS] = XInternAtom (DisplayHandle, "_MOTIF_WM_HINTS", false);
-
- NetAtoms [(int)NA._NET_WM_STATE_NO_TASKBAR] = XInternAtom (DisplayHandle, "_NET_WM_STATE_NO_TASKBAR", false);
- NetAtoms [(int)NA._NET_WM_STATE_ABOVE] = XInternAtom (DisplayHandle, "_NET_WM_STATE_ABOVE", false);
- NetAtoms [(int)NA._NET_WM_STATE_MODAL] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MODAL", false);
- NetAtoms [(int)NA._NET_WM_CONTEXT_HELP] = XInternAtom (DisplayHandle, "_NET_WM_CONTEXT_HELP", false);
- NetAtoms [(int)NA._NET_WM_WINDOW_OPACITY] = XInternAtom (DisplayHandle, "_NET_WM_WINDOW_OPACITY", false);
-
- // Clipboard support
- NetAtoms [(int)NA.CLIPBOARD] = XInternAtom (DisplayHandle, "CLIPBOARD", false);
- NetAtoms [(int)NA.DIB] = (int)Atom.XA_PIXMAP;
- NetAtoms [(int)NA.OEMTEXT] = XInternAtom (DisplayHandle, "COMPOUND_TEXT", false);
- NetAtoms [(int)NA.UNICODETEXT] = XInternAtom (DisplayHandle, "UTF8_STRING", false);
- NetAtoms [(int)NA.TARGETS] = XInternAtom (DisplayHandle, "TARGETS", false);
-
- // Special Atoms
- AsyncAtom = XInternAtom (DisplayHandle, "_SWF_AsyncAtom", false);
- PostAtom = XInternAtom (DisplayHandle, "_SWF_PostMessageAtom", false);
- HoverState.Atom = XInternAtom (DisplayHandle, "_SWF_HoverAtom", false);
- }
-
- private void GetSystrayManagerWindow ()
- {
- gdk_x11_grab_server ();
- SystrayMgrWindow = XGetSelectionOwner (DisplayHandle, NetAtoms [(int)NA._NET_SYSTEM_TRAY_S]);
- gdk_x11_ungrab_server ();
- gdk_display_flush (GdkDisplayHandle);
- }
-
- private void SendNetWMMessage (IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2)
- {
- XEvent xev;
-
- xev = new XEvent ();
- xev.ClientMessageEvent.type = XEventName.ClientMessage;
- xev.ClientMessageEvent.send_event = true;
- xev.ClientMessageEvent.window = window;
- xev.ClientMessageEvent.message_type = message_type;
- xev.ClientMessageEvent.format = 32;
- xev.ClientMessageEvent.ptr1 = l0;
- xev.ClientMessageEvent.ptr2 = l1;
- xev.ClientMessageEvent.ptr3 = l2;
- XSendEvent (DisplayHandle, RootWindow, false, EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask, ref xev);
- }
-
- private void SendNetClientMessage (IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2)
- {
- XEvent xev;
-
- xev = new XEvent ();
- xev.ClientMessageEvent.type = XEventName.ClientMessage;
- xev.ClientMessageEvent.send_event = true;
- xev.ClientMessageEvent.window = window;
- xev.ClientMessageEvent.message_type = message_type;
- xev.ClientMessageEvent.format = 32;
- xev.ClientMessageEvent.ptr1 = l0;
- xev.ClientMessageEvent.ptr2 = l1;
- xev.ClientMessageEvent.ptr3 = l2;
- XSendEvent (DisplayHandle, window, false, EventMask.NoEventMask, ref xev);
- }
-
- private void DeriveStyles (IntPtr handle, int Style, int ExStyle, out FormBorderStyle border_style, out TitleStyle title_style, out int caption_height, out int tool_caption_height)
- {
-
- // Only MDI windows get caption_heights
- caption_height = 0;
- tool_caption_height = 19;
-
- if ((Style & (int) WindowStyles.WS_CHILD) != 0) {
- if ((Style & (int) WindowStyles.WS_BORDER) == 0) {
- border_style = FormBorderStyle.None;
- } else if ((ExStyle & (int) WindowStyles.WS_EX_CLIENTEDGE) != 0) {
- border_style = FormBorderStyle.Fixed3D;
- } else {
- border_style = FormBorderStyle.FixedSingle;
- }
- title_style = TitleStyle.None;
- } else {
- bool is_mdi = false;
-
- if ((ExStyle & (int) WindowStyles.WS_EX_MDICHILD) != 0) {
- caption_height = 26;
- is_mdi = true;
- }
-
- title_style = TitleStyle.None;
- if ((Style & (int)WindowStyles.WS_CAPTION) != 0) {
- if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
- title_style = TitleStyle.Tool;
- } else {
- title_style = TitleStyle.Normal;
- }
- }
-
- if (!is_mdi) {
- border_style = FormBorderStyle.None;
-
- if ((Style & (int)WindowStyles.WS_THICKFRAME) != 0) {
- if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
- border_style = FormBorderStyle.SizableToolWindow;
- } else {
- border_style = FormBorderStyle.Sizable;
- }
- } else {
- if ((ExStyle & (int)WindowStyles.WS_EX_CLIENTEDGE) != 0) {
- border_style = FormBorderStyle.Fixed3D;
- } else if ((ExStyle & (int)WindowStyles.WS_EX_DLGMODALFRAME) != 0) {
- border_style = FormBorderStyle.FixedDialog;
- } else if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
- border_style = FormBorderStyle.FixedToolWindow;
- } else if ((Style & (int)WindowStyles.WS_BORDER) != 0) {
- border_style = FormBorderStyle.Sizable;
- } else {
- border_style = FormBorderStyle.None;
- }
- }
- } else {
- if ((Style & (int) WindowStyles.WS_OVERLAPPEDWINDOW) != 0 ||
- (ExStyle & (int) WindowStyles.WS_EX_TOOLWINDOW) != 0) {
- border_style = (FormBorderStyle) 0xFFFF;
- } else {
- border_style = FormBorderStyle.None;
- }
- }
- }
- }
-
- private void SetHwndStyles (Hwnd hwnd, CreateParams cp)
- {
- DeriveStyles (hwnd.Handle, cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
- }
-
- private void SetWMStyles (Hwnd hwnd, CreateParams cp)
- {
- GdkWMDecoration decorations = GdkWMDecoration.GDK_DECOR_ALL;
-
- if ((cp.Style & (int)WindowStyles.WS_CAPTION) != 0) {
- decorations |= GdkWMDecoration.GDK_DECOR_TITLE | GdkWMDecoration.GDK_DECOR_MENU;
- }
-
- if ((cp.Style & ((int)WindowStyles.WS_THICKFRAME)) != 0) {
- decorations |= GdkWMDecoration.GDK_DECOR_BORDER | GdkWMDecoration.GDK_DECOR_RESIZEH;
- }
- if ((cp.Style & ((int)WindowStyles.WS_MINIMIZEBOX)) != 0) {
- decorations |= GdkWMDecoration.GDK_DECOR_MINIMIZE;
- }
-
- if ((cp.Style & ((int)WindowStyles.WS_MAXIMIZEBOX)) != 0) {
- decorations |= GdkWMDecoration.GDK_DECOR_MAXIMIZE;
- }
-
- // is this needed ? most window managers do not even honour any MotifFunctions...
- // if ((cp.Style & ((int)WindowStyles.WS_SYSMENU)) != 0) {
- // functions |= MotifFunctions.Close;
- // }
-
- if ((cp.ExStyle & ((int)WindowStyles.WS_EX_DLGMODALFRAME)) != 0) {
- decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
- }
-
- if ((cp.Style & ((int)WindowStyles.WS_DLGFRAME)) != 0) {
- decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
- }
-
- if ((cp.Style & ((int)WindowStyles.WS_BORDER)) != 0) {
- decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
- }
-
- if ((cp.ExStyle & ((int)WindowStyles.WS_EX_TOOLWINDOW)) != 0) {
- decorations = 0;
- }
-
- gdk_window_set_decorations (gdk_window_foreign_new (hwnd.whole_window), (int)decorations);
- }
-
- private void SetIcon (Hwnd hwnd, Icon icon)
- {
- Bitmap bitmap;
- int size;
- uint[] data;
- int index;
-
- bitmap = icon.ToBitmap ();
- index = 0;
- size = bitmap.Width * bitmap.Height + 2;
- data = new uint [size];
-
- data [index++] = (uint)bitmap.Width;
- data [index++] = (uint)bitmap.Height;
-
- for (int y = 0; y < bitmap.Height; y++) {
- for (int x = 0; x < bitmap.Width; x++) {
- data [index++] = (uint)bitmap.GetPixel (x, y).ToArgb ();
- }
- }
- XChangeProperty (DisplayHandle, hwnd.whole_window, NetAtoms [(int)NA._NET_WM_ICON], Atom.XA_CARDINAL, 32, PropertyMode.Replace, data, size);
- }
-
- private IntPtr ImageToPixmap (Image image)
- {
- return IntPtr.Zero;
- }
-
- private void WakeupMain ()
- {
- wake.Send (new byte [] { 0xFF });
- }
-
- private void TranslatePropertyToClipboard (int property)
- {
- Atom actual_atom;
- int actual_format;
- int nitems;
- int bytes_after;
- IntPtr prop = IntPtr.Zero;
-
- Clipboard.Item = null;
-
- XGetWindowProperty (DisplayHandle, FosterParent, property, 0, 0x7fffffff, true, Atom.AnyPropertyType, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
-
- if (nitems > 0) {
- if (property == (int)Atom.XA_STRING) {
- Clipboard.Item = Marshal.PtrToStringAnsi (prop);
- } else if (property == (int)Atom.XA_BITMAP) {
- // FIXME - convert bitmap to image
- } else if (property == (int)Atom.XA_PIXMAP) {
- // FIXME - convert pixmap to image
- } else if (property == NetAtoms [(int)NA.OEMTEXT]) {
- Clipboard.Item = Marshal.PtrToStringAnsi (prop);
- } else if (property == NetAtoms [(int)NA.UNICODETEXT]) {
- Clipboard.Item = Marshal.PtrToStringAnsi (prop);
- }
-
- XFree (prop);
- }
- }
-
- private void AddExpose (XEvent xevent)
- {
- Hwnd hwnd;
-
- hwnd = Hwnd.GetObjectFromWindow (xevent.AnyEvent.window);
-
- // Don't waste time
- if (hwnd == null) {
- return;
- }
-
- if (xevent.AnyEvent.window == hwnd.client_window) {
- hwnd.AddInvalidArea (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
- if (!hwnd.expose_pending) {
- MessageQueue.Enqueue (xevent);
- hwnd.expose_pending = true;
- }
- } else {
- if (!hwnd.nc_expose_pending) {
- MessageQueue.Enqueue (xevent);
- hwnd.nc_expose_pending = true;
- }
- }
- }
-
- private void InvalidateWholeWindow (IntPtr handle)
- {
- Hwnd hwnd;
-
- hwnd = Hwnd.ObjectFromHandle (handle);
-
- InvalidateWholeWindow (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height));
- }
-
- private void InvalidateWholeWindow (IntPtr handle, Rectangle rectangle)
- {
- Hwnd hwnd;
- XEvent xevent;
-
- hwnd = Hwnd.ObjectFromHandle (handle);
-
-
- xevent = new XEvent ();
- xevent.type = XEventName.Expose;
- xevent.ExposeEvent.display = DisplayHandle;
- xevent.ExposeEvent.window = hwnd.whole_window;
-
- xevent.ExposeEvent.x = rectangle.X;
- xevent.ExposeEvent.y = rectangle.Y;
- xevent.ExposeEvent.width = rectangle.Width;
- xevent.ExposeEvent.height = rectangle.Height;
-
- AddExpose (xevent);
- }
-
- private void WholeToScreen (IntPtr handle, ref int x, ref int y)
- {
- int dest_x_return;
- int dest_y_return;
- Hwnd hwnd;
-
- hwnd = Hwnd.ObjectFromHandle (handle);
-
- lock (XlibLock) {
- gdk_window_get_origin (gdk_window_lookup (hwnd.whole_window), out dest_x_return, out dest_y_return);
- }
-
- x = dest_x_return;
- y = dest_y_return;
- }
-
- private void AddConfigureNotify (XEvent xevent)
- {
- Hwnd hwnd;
-
- hwnd = Hwnd.GetObjectFromWindow (xevent.ConfigureEvent.window);
-
- // Don't waste time
- if (hwnd == null) {
- return;
- }
-
- if (xevent.ConfigureEvent.window == hwnd.whole_window) {
- if (!hwnd.reparented) {
- hwnd.x = xevent.ConfigureEvent.x;
- hwnd.y = xevent.ConfigureEvent.y;
- } else {
- int dummy_int;
-
- gdk_window_get_geometry (gdk_window_lookup (hwnd.whole_window), out hwnd.x, out hwnd.y, out dummy_int, out dummy_int, out dummy_int);
- }
-
- hwnd.width = xevent.ConfigureEvent.width;
- hwnd.height = xevent.ConfigureEvent.height;
-
- if (!hwnd.configure_pending) {
- MessageQueue.Enqueue (xevent);
- hwnd.configure_pending = true;
- }
- }
- // We drop configure events for Client windows
- }
-
- private void ShowCaret ()
- {
- if ((Caret.gc == IntPtr.Zero) || Caret.On) {
- return;
- }
- Caret.On = true;
-
- // gdk_gc_set_foreground
- // gdk_draw_line
- lock (XlibLock) {
- XDrawLine (DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
- }
- }
-
- private void HideCaret ()
- {
- if ((Caret.gc == IntPtr.Zero) || !Caret.On) {
- return;
- }
- Caret.On = false;
-
- // gdk_gc_set_foreground
- // gdk_draw_text_wc
- lock (XlibLock) {
- XDrawLine (DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
- }
- }
-
- private int NextTimeout (DateTime now)
- {
- int timeout = Int32.MaxValue;
- lock (TimerList) {
- foreach (Timer timer in TimerList) {
- int next = (int) (timer.Expires - now).TotalMilliseconds;
- if (next < 0) {
- return 0; // Have a timer that has already expired
- }
-
- if (next < timeout) {
- timeout = next;
- }
- }
- }
- if (timeout < Timer.Minimum) {
- timeout = Timer.Minimum;
- }
-
- return timeout;
- }
-
- private void CheckTimers (DateTime now)
- {
- lock (TimerList) {
- int count;
-
- count = TimerList.Count;
-
- if (count == 0) {
- return;
- }
-
- for (int i = 0; i < TimerList.Count; i++) {
- Timer timer;
-
- timer = (Timer) TimerList [i];
-
- if (timer.Enabled && timer.Expires <= now) {
- timer.Update (now);
- timer.FireTick ();
- }
- }
- }
- }
-
- private void UpdateMessageQueue ()
- {
- DateTime now;
- int pending;
-
- now = DateTime.Now;
-
- lock (XlibLock) {
- pending = XPending (DisplayHandle);
- }
-
- if (pending == 0) {
- if (Idle != null) {
- Idle (this, EventArgs.Empty);
- }
-
- lock (XlibLock) {
- pending = XPending (DisplayHandle);
- }
- }
-
- if (pending == 0) {
- int timeout;
-
- timeout = NextTimeout (now);
- if (timeout > 0) {
- #if __MonoCS__
- Syscall.poll (pollfds, (uint) pollfds.Length, timeout);
- // Clean out buffer, so we're not busy-looping on the same data
- if (pollfds[1].revents != 0) {
- wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None);
- }
- #endif
- lock (XlibLock) {
- pending = XPending (DisplayHandle);
- }
- }
- }
-
- CheckTimers (now);
-
- if (pending == 0) {
- lock (XlibLock) {
- pending = XPending (DisplayHandle);
- }
- }
-
- while (pending > 0) {
- XEvent xevent = new XEvent ();
-
- lock (XlibLock) {
- XNextEvent (DisplayHandle, ref xevent);
- }
- //Console.WriteLine("Got x event {0}", xevent);
- switch (xevent.type) {
- case XEventName.Expose:
- AddExpose (xevent);
- break;
-
- case XEventName.SelectionClear: {
- // Should we do something?
- break;
- }
-
- case XEventName.SelectionRequest: {
- if (Dnd.HandleSelectionRequestEvent (ref xevent))
- break;
- XEvent sel_event;
-
- sel_event = new XEvent ();
- sel_event.SelectionEvent.type = XEventName.SelectionNotify;
- sel_event.SelectionEvent.send_event = true;
- sel_event.SelectionEvent.display = DisplayHandle;
- sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
- sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
- sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
- sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
- sel_event.SelectionEvent.property = 0;
-
- // Seems that some apps support asking for supported types
- if (xevent.SelectionEvent.target == NetAtoms [(int)NA.TARGETS]) {
- uint[] atoms;
- int atom_count;
-
- atoms = new uint [5];
- atom_count = 0;
-
- if (Clipboard.Item is String) {
- atoms [atom_count++] = (uint)Atom.XA_STRING;
- atoms [atom_count++] = (uint)NetAtoms [(int)NA.OEMTEXT];
- atoms [atom_count++] = (uint)NetAtoms [(int)NA.UNICODETEXT];
- } else if (Clipboard.Item is Image) {
- atoms [atom_count++] = (uint)Atom.XA_PIXMAP;
- atoms [atom_count++] = (uint)Atom.XA_BITMAP;
- } else {
- // FIXME - handle other types
- }
-
- XChangeProperty (DisplayHandle, xevent.SelectionEvent.requestor, xevent.SelectionRequestEvent.property, xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
- } else if (Clipboard.Item is string) {
- IntPtr buffer;
- int buflen;
-
- buflen = 0;
-
- if (xevent.SelectionRequestEvent.target == (int)Atom.XA_STRING) {
- Byte[] bytes;
-
- bytes = new ASCIIEncoding ().GetBytes ((string)Clipboard.Item);
- buffer = Marshal.AllocHGlobal (bytes.Length);
- buflen = bytes.Length;
-
- for (int i = 0; i < buflen; i++) {
- Marshal.WriteByte (buffer, i, bytes [i]);
- }
- } else if (xevent.SelectionRequestEvent.target == NetAtoms [(int)NA.OEMTEXT]) {
- // FIXME - this should encode into ISO2022
- buffer = Marshal.StringToHGlobalAnsi ((string)Clipboard.Item);
- while (Marshal.ReadByte (buffer, buflen) != 0) {
- buflen++;
- }
- } else if (xevent.SelectionRequestEvent.target == NetAtoms [(int)NA.UNICODETEXT]) {
- buffer = Marshal.StringToHGlobalAnsi ((string)Clipboard.Item);
- while (Marshal.ReadByte (buffer, buflen) != 0) {
- buflen++;
- }
- } else {
- buffer = IntPtr.Zero;
- }
-
- if (buffer != IntPtr.Zero) {
- XChangeProperty (DisplayHandle, xevent.SelectionRequestEvent.requestor, xevent.SelectionRequestEvent.property, xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
- sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
- Marshal.FreeHGlobal (buffer);
- }
- } else if (Clipboard.Item is Image) {
- if (xevent.SelectionEvent.target == (int)Atom.XA_PIXMAP) {
- // FIXME - convert image and store as property
- } else if (xevent.SelectionEvent.target == (int)Atom.XA_PIXMAP) {
- // FIXME - convert image and store as property
- }
- }
-
- XSendEvent (DisplayHandle, xevent.SelectionRequestEvent.requestor, false, EventMask.NoEventMask, ref sel_event);
- break;
- }
-
- case XEventName.SelectionNotify: {
- if (Clipboard.Enumerating) {
- Clipboard.Enumerating = false;
- if (xevent.SelectionEvent.property != 0) {
- XDeleteProperty (DisplayHandle, FosterParent, xevent.SelectionEvent.property);
- if (!Clipboard.Formats.Contains (xevent.SelectionEvent.property)) {
- Clipboard.Formats.Add (xevent.SelectionEvent.property);
- #if DriverDebugExtra
- Console.WriteLine("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
- #endif
- }
- }
- } else if (Clipboard.Retrieving) {
- Clipboard.Retrieving = false;
- if (xevent.SelectionEvent.property != 0) {
- TranslatePropertyToClipboard (xevent.SelectionEvent.property);
- } else {
- Clipboard.Item = null;
- }
- } else {
- Dnd.HandleSelectionNotifyEvent (ref xevent);
- }
- break;
- }
-
- case XEventName.KeyPress:
- case XEventName.KeyRelease:
- case XEventName.ButtonPress:
- case XEventName.ButtonRelease:
- case XEventName.MotionNotify:
- case XEventName.EnterNotify:
- case XEventName.LeaveNotify:
- case XEventName.CreateNotify:
- case XEventName.DestroyNotify:
- case XEventName.FocusIn:
- case XEventName.FocusOut:
- case XEventName.ClientMessage:
- case XEventName.ReparentNotify:
- MessageQueue.Enqueue (xevent);
- break;
-
- case XEventName.ConfigureNotify:
- AddConfigureNotify (xevent);
- break;
-
- case XEventName.PropertyNotify:
- if (xevent.PropertyEvent.atom == NetAtoms [(int)NA._NET_ACTIVE_WINDOW]) {
- Atom actual_atom;
- int actual_format;
- int nitems;
- int bytes_after;
- IntPtr prop = IntPtr.Zero;
- IntPtr prev_active;;
-
- prev_active = ActiveWindow;
- XGetWindowProperty (DisplayHandle, RootWindow, NetAtoms [(int)NA._NET_ACTIVE_WINDOW], 0, 1, false, Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
- if ((nitems > 0) && (prop != IntPtr.Zero)) {
- ActiveWindow = Hwnd.GetHandleFromWindow ((IntPtr)Marshal.ReadInt32 (prop));
- XFree (prop);
-
- if (prev_active != ActiveWindow) {
- if (prev_active != IntPtr.Zero) {
- PostMessage (prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
- }
- if (ActiveWindow != IntPtr.Zero) {
- PostMessage (ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
- }
- }
- if (ModalWindows.Count == 0) {
- break;
- } else {
- // Modality handling, if we are modal and the new active window is one
- // of ours but not the modal one, switch back to the modal window
-
- if (NativeWindow.FromHandle (ActiveWindow) != null) {
- if (ActiveWindow != (IntPtr)ModalWindows.Peek ()) {
- Activate ((IntPtr)ModalWindows.Peek ());
- }
- }
- break;
- }
- }
- }
- break;
-
- }
-
- lock (XlibLock) {
- pending = XPending (DisplayHandle);
- }
- }
- }
-
- private IntPtr GetMousewParam (int Delta)
- {
- int result = 0;
-
- if ((MouseState & MouseButtons.Left) != 0) {
- result |= (int)MsgButtons.MK_LBUTTON;
- }
-
- if ((MouseState & MouseButtons.Middle) != 0) {
- result |= (int)MsgButtons.MK_MBUTTON;
- }
-
- if ((MouseState & MouseButtons.Right) != 0) {
- result |= (int)MsgButtons.MK_RBUTTON;
- }
-
- Keys mods = ModifierKeys;
- if ((mods & Keys.Control) != 0) {
- result |= (int)MsgButtons.MK_CONTROL;
- }
-
- if ((mods & Keys.Shift) != 0) {
- result |= (int)MsgButtons.MK_SHIFT;
- }
-
- result |= Delta << 16;
-
- return (IntPtr)result;
- }
- private IntPtr XGetParent (IntPtr handle)
- {
- return gdk_x11_drawable_get_xid (gdk_window_get_parent (gdk_window_lookup (handle)));
- }
-
- private int HandleError (IntPtr display, ref XErrorEvent error_event)
- {
- if (ErrorExceptions) {
- throw new XException (error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code);
- } else {
- Console.WriteLine ("X11 Error encountered: {0}{1}\n", XException.GetMessage (error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code), Environment.StackTrace);
- }
- return 0;
- }
-
- private void DestroyChildWindow (Control c)
- {
- Hwnd hwnd;
- int i;
- Control[] controls;
-
- if (c != null) {
- controls = c.Controls.GetAllControls ();
-
- for (i = 0; i < controls.Length; i++) {
- if (controls [i].IsHandleCreated) {
- hwnd = Hwnd.ObjectFromHandle (controls [i].Handle);
- SendMessage (controls [i].Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
- hwnd.Dispose ();
- }
- DestroyChildWindow (controls [i]);
- }
- }
- }
-
- #endregion // Private Methods
-
- #region Callbacks
- private void MouseHover (object sender, EventArgs e)
- {
- if ((HoverState.X == MousePosition.X) && (HoverState.Y == MousePosition.Y)) {
- XEvent xevent;
-
- HoverState.Timer.Enabled = false;
-
- if (HoverState.Window != IntPtr.Zero) {
- xevent = new XEvent ();
-
- xevent.type = XEventName.ClientMessage;
- xevent.ClientMessageEvent.display = DisplayHandle;
- xevent.ClientMessageEvent.window = (IntPtr)HoverState.Window;
- xevent.ClientMessageEvent.message_type = (IntPtr)HoverState.Atom;
- xevent.ClientMessageEvent.format = 32;
- xevent.ClientMessageEvent.ptr1 = (IntPtr) (HoverState.Y << 16 | HoverState.X);
-
- MessageQueue.EnqueueLocked (xevent);
-
- WakeupMain ();
- }
- }
- }
-
- private void CaretCallback (object sender, EventArgs e)
- {
- if (Caret.Paused) {
- return;
- }
- Caret.On = !Caret.On;
-
- XDrawLine (DisplayHandle, Caret.Hwnd, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
- }
- #endregion // Callbacks
-
- #region Public Properties
-
- internal override int Caption {
- get {
- return 25;
- }
- }
-
- internal override Size CursorSize {
- get {
- uint x;
- uint y;
- gdk_display_get_maximal_cursor_size (GdkDisplayHandle, out x, out y);
-
- return new Size ((int)x, (int)y);
- }
- }
-
- internal override bool DragFullWindows {
- get {
- return true;
- }
- }
-
- internal override Size DragSize {
- get {
- return new Size (4, 4);
- }
- }
-
- internal override Size FrameBorderSize {
- get {
- throw new NotImplementedException ();
- }
- }
-
- internal override Size IconSize {
- get {
- IntPtr …
Large files files are truncated, but you can click here to view the full file