1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2006 Novell, Inc.
23 // Peter Bartok pbartok@novell.com
24 // Alexander Olk alex.olk@googlemail.com
29 // This driver understands the following environment variables: (Set the var to enable feature)
31 // MONO_XEXCEPTIONS = throw an exception when a X11 error is encountered;
32 // by default a message is displayed but execution continues
34 // MONO_XSYNC = perform all X11 commands synchronous; this is slower but
35 // helps in debugging errors
38 // NOT COMPLETE - WORK IN PROGRESS
40 // One feature of the driver is, that PaintEventstart returns a graphics context created from a offscreen drawable (pixmap)
42 // define to log Window handles and relationships to stdout
45 // Extra detailed debug
46 #undef DriverDebugExtra
49 using System.ComponentModel;
50 using System.Collections;
51 using System.Diagnostics;
53 using System.Drawing.Drawing2D;
54 using System.Drawing.Imaging;
57 using System.Net.Sockets;
58 using System.Reflection;
59 using System.Runtime.InteropServices;
61 using System.Threading;
63 // Only do the poll when building with mono for now
65 using Mono.Unix.Native;
69 namespace System.Windows.Forms {
70 internal class XplatUIX11GTK : XplatUIDriver {
72 internal enum GdkWindowClass {
77 internal enum GdkWindowType {
86 internal enum GdkWindowHints {
87 GDK_HINT_POS = 1 << 0,
88 GDK_HINT_MIN_SIZE = 1 << 1,
89 GDK_HINT_MAX_SIZE = 1 << 2,
90 GDK_HINT_BASE_SIZE = 1 << 3,
91 GDK_HINT_ASPECT = 1 << 4,
92 GDK_HINT_RESIZE_INC = 1 << 5,
93 GDK_HINT_WIN_GRAVITY = 1 << 6,
94 GDK_HINT_USER_POS = 1 << 7,
95 GDK_HINT_USER_SIZE = 1 << 8
98 internal enum GdkGravity {
99 GDK_GRAVITY_NORTH_WEST = 1,
101 GDK_GRAVITY_NORTH_EAST,
105 GDK_GRAVITY_SOUTH_WEST,
107 GDK_GRAVITY_SOUTH_EAST,
111 internal enum GdkWindowEdge {
112 GDK_WINDOW_EDGE_NORTH_WEST,
113 GDK_WINDOW_EDGE_NORTH,
114 GDK_WINDOW_EDGE_NORTH_EAST,
115 GDK_WINDOW_EDGE_WEST,
116 GDK_WINDOW_EDGE_EAST,
117 GDK_WINDOW_EDGE_SOUTH_WEST,
118 GDK_WINDOW_EDGE_SOUTH,
119 GDK_WINDOW_EDGE_SOUTH_EAST
122 internal enum GdkWindowTypeHint {
123 GDK_WINDOW_TYPE_HINT_NORMAL,
124 GDK_WINDOW_TYPE_HINT_DIALOG,
125 GDK_WINDOW_TYPE_HINT_MENU,
126 GDK_WINDOW_TYPE_HINT_TOOLBAR,
127 GDK_WINDOW_TYPE_HINT_SPLASHSCREEN,
128 GDK_WINDOW_TYPE_HINT_UTILITY,
129 GDK_WINDOW_TYPE_HINT_DOCK,
130 GDK_WINDOW_TYPE_HINT_DESKTOP
133 internal enum GdkWindowAttributesType {
134 GDK_WA_TITLE = 1 << 1,
137 GDK_WA_CURSOR = 1 << 4,
138 GDK_WA_COLORMAP = 1 << 5,
139 GDK_WA_VISUAL = 1 << 6,
140 GDK_WA_WMCLASS = 1 << 7,
141 GDK_WA_NOREDIR = 1 << 8
144 internal enum GdkEventMask {
145 GDK_EXPOSURE_MASK = 1 << 1,
146 GDK_POINTER_MOTION_MASK = 1 << 2,
147 GDK_POINTER_MOTION_HINT_MASK = 1 << 3,
148 GDK_BUTTON_MOTION_MASK = 1 << 4,
149 GDK_BUTTON1_MOTION_MASK = 1 << 5,
150 GDK_BUTTON2_MOTION_MASK = 1 << 6,
151 GDK_BUTTON3_MOTION_MASK = 1 << 7,
152 GDK_BUTTON_PRESS_MASK = 1 << 8,
153 GDK_BUTTON_RELEASE_MASK = 1 << 9,
154 GDK_KEY_PRESS_MASK = 1 << 10,
155 GDK_KEY_RELEASE_MASK = 1 << 11,
156 GDK_ENTER_NOTIFY_MASK = 1 << 12,
157 GDK_LEAVE_NOTIFY_MASK = 1 << 13,
158 GDK_FOCUS_CHANGE_MASK = 1 << 14,
159 GDK_STRUCTURE_MASK = 1 << 15,
160 GDK_PROPERTY_CHANGE_MASK = 1 << 16,
161 GDK_VISIBILITY_NOTIFY_MASK = 1 << 17,
162 GDK_PROXIMITY_IN_MASK = 1 << 18,
163 GDK_PROXIMITY_OUT_MASK = 1 << 19,
164 GDK_SUBSTRUCTURE_MASK = 1 << 20,
165 GDK_SCROLL_MASK = 1 << 21,
166 GDK_ALL_EVENTS_MASK = 0x3FFFFE
169 internal enum GdkEventType {
174 GDK_MOTION_NOTIFY = 3,
175 GDK_BUTTON_PRESS = 4,
176 GDK_2BUTTON_PRESS = 5,
177 GDK_3BUTTON_PRESS = 6,
178 GDK_BUTTON_RELEASE = 7,
181 GDK_ENTER_NOTIFY = 10,
182 GDK_LEAVE_NOTIFY = 11,
183 GDK_FOCUS_CHANGE = 12,
187 GDK_PROPERTY_NOTIFY = 16,
188 GDK_SELECTION_CLEAR = 17,
189 GDK_SELECTION_REQUEST = 18,
190 GDK_SELECTION_NOTIFY = 19,
191 GDK_PROXIMITY_IN = 20,
192 GDK_PROXIMITY_OUT = 21,
195 GDK_DRAG_MOTION = 24,
196 GDK_DRAG_STATUS = 25,
198 GDK_DROP_FINISHED = 27,
199 GDK_CLIENT_EVENT = 28,
200 GDK_VISIBILITY_NOTIFY = 29,
203 GDK_WINDOW_STATE = 32,
205 GDK_OWNER_CHANGE = 34,
209 internal enum GdkWMDecoration {
210 GDK_DECOR_ALL = 1 << 0,
211 GDK_DECOR_BORDER = 1 << 1,
212 GDK_DECOR_RESIZEH = 1 << 2,
213 GDK_DECOR_TITLE = 1 << 3,
214 GDK_DECOR_MENU = 1 << 4,
215 GDK_DECOR_MINIMIZE = 1 << 5,
216 GDK_DECOR_MAXIMIZE = 1 << 6
219 internal enum GdkWMFunction {
220 GDK_FUNC_ALL = 1 << 0,
221 GDK_FUNC_RESIZE = 1 << 1,
222 GDK_FUNC_MOVE = 1 << 2,
223 GDK_FUNC_MINIMIZE = 1 << 3,
224 GDK_FUNC_MAXIMIZE = 1 << 4,
225 GDK_FUNC_CLOSE = 1 << 5
228 internal enum GdkCursorType {
231 GDK_BASED_ARROW_DOWN = 4,
232 GDK_BASED_ARROW_UP = 6,
235 GDK_BOTTOM_LEFT_CORNER = 12,
236 GDK_BOTTOM_RIGHT_CORNER = 14,
237 GDK_BOTTOM_SIDE = 16,
245 GDK_CROSS_REVERSE = 32,
247 GDK_DIAMOND_CROSS = 36,
250 GDK_DOUBLE_ARROW = 42,
251 GDK_DRAFT_LARGE = 44,
252 GDK_DRAFT_SMALL = 46,
270 GDK_MIDDLEBUTTON = 82,
275 GDK_QUESTION_ARROW = 92,
279 GDK_RIGHTBUTTON = 100,
282 GDK_SB_DOWN_ARROW = 106,
283 GDK_SB_H_DOUBLE_ARROW = 108,
284 GDK_SB_LEFT_ARROW = 110,
285 GDK_SB_RIGHT_ARROW = 112,
286 GDK_SB_UP_ARROW = 114,
287 GDK_SB_V_DOUBLE_ARROW = 116,
295 GDK_TOP_LEFT_ARROW = 132,
296 GDK_TOP_LEFT_CORNER = 134,
297 GDK_TOP_RIGHT_CORNER = 136,
307 GDK_CURSOR_IS_PIXMAP = -1
310 internal enum GdkPropMode {
311 GDK_PROP_MODE_REPLACE,
312 GDK_PROP_MODE_PREPEND,
316 [StructLayout (LayoutKind.Sequential)]
317 internal struct GdkGeometry {
318 internal int min_width;
319 internal int min_height;
320 internal int max_width;
321 internal int max_height;
322 internal int base_width;
323 internal int base_height;
324 internal int width_inc;
325 internal int height_inc;
326 internal double min_aspect;
327 internal double max_aspect;
328 internal GdkGravity win_gravity;
331 [StructLayout (LayoutKind.Sequential)]
332 internal struct GdkWindowAttr {
333 internal string title;
334 internal int event_mask;
338 internal GdkWindowClass wclass;
339 internal IntPtr visual;
340 internal IntPtr colormap;
341 internal GdkWindowType window_type;
342 internal IntPtr cursor;
343 internal string wmclass_name;
344 internal string wmclass_class;
345 internal bool override_redirect;
348 #region Local Variables
350 static volatile XplatUIX11GTK Instance;
351 private static int RefCount;
352 private static object XlibLock; // Our locking object
353 private static bool ThemesEnabled;
356 private static IntPtr DisplayHandle; // X11 handle to display
357 private static IntPtr GdkDisplayHandle; // gdk handle to display
358 private static int ScreenNo; // Screen number used
359 private static IntPtr GdkScreen;
360 private static IntPtr DefaultColormap; // Colormap for screen
361 private static IntPtr GdkDefaultColormap; // Gdk Colormap for screen
362 private static IntPtr CustomVisual; // Visual for window creation
363 private static IntPtr GdkCustomVisual;
364 private static IntPtr CustomColormap; // Colormap for window creation
365 private static IntPtr GdkCustomColormap;
366 private static int VisualBestDepth;
367 private static IntPtr RootWindow; // Handle of the root window for the screen/display
368 private static IntPtr GdkRootWindow; // Gdk handle of the root window for the screen/display
369 private static IntPtr FosterParent; // Container to hold child windows until their parent exists
370 private static IntPtr GdkFosterParent; // Container to hold child windows until their parent exists
371 private static XErrorHandler ErrorHandler; // Error handler delegate
372 private static bool ErrorExceptions; // Throw exceptions on X errors
373 private static bool PostQuitState; // True if we've got an pending exit
376 private static IntPtr ClipMagic = new IntPtr(27051977);
377 private static ClipboardStruct Clipboard; // Our clipboard
380 private static int PostAtom; // PostMessage atom
381 private static int AsyncAtom; // Support for async messages
384 private static XEventQueue MessageQueue; // Holds our queued up events
386 private static Pollfd[] pollfds; // For watching the X11 socket
388 private static X11Keyboard Keyboard; //
389 private static X11Dnd Dnd;
390 private static Socket listen; //
391 private static Socket wake; //
392 private static Socket wake_receive; //
393 private static byte[] network_buffer; //
397 private static IntPtr ActiveWindow; // Handle of the active window
398 private static IntPtr FocusWindow; // Handle of the window with keyboard focus (if any)
401 private static Stack ModalWindows; // Stack of our modal windows
404 private static IntPtr SystrayMgrWindow; // Handle of the Systray Manager window
407 private static IntPtr LastCursorWindow; // The last window we set the cursor on
408 private static IntPtr LastCursorHandle; // The handle that was last set on LastCursorWindow
409 private static IntPtr OverrideCursorHandle; // The cursor that is set to override any other cursors
412 private static CaretStruct Caret; //
414 // Support for Window Styles
415 private static int[] NetAtoms; // All atoms we know
417 // mouse hover message generation
418 private static HoverStruct HoverState; //
420 // double click message generation
421 private static ClickStruct ClickPending; //
423 // Support for mouse grab
424 private static GrabStruct Grab; //
427 private static Point MousePosition; // Last position of mouse, in screen coords
428 internal static MouseButtons MouseState; // Last state of mouse buttons
431 private static ArrayList TimerList; // Holds SWF.Timers
434 private static int DoubleClickInterval; // msec; max interval between clicks to count as double click
436 const GdkEventMask GdkSelectInputMask = GdkEventMask.GDK_BUTTON_PRESS_MASK |
437 GdkEventMask.GDK_BUTTON_RELEASE_MASK |
438 GdkEventMask.GDK_KEY_PRESS_MASK |
439 GdkEventMask.GDK_KEY_RELEASE_MASK |
440 GdkEventMask.GDK_ENTER_NOTIFY_MASK |
441 GdkEventMask.GDK_LEAVE_NOTIFY_MASK |
442 GdkEventMask.GDK_EXPOSURE_MASK |
443 GdkEventMask.GDK_FOCUS_CHANGE_MASK |
444 GdkEventMask.GDK_POINTER_MOTION_MASK |
445 GdkEventMask.GDK_VISIBILITY_NOTIFY_MASK |
446 GdkEventMask.GDK_SUBSTRUCTURE_MASK |
447 GdkEventMask.GDK_STRUCTURE_MASK;
449 static readonly object lockobj = new object ();
451 static Hashtable backing_store = new Hashtable (5);
453 #endregion // Local Variables
455 private XplatUIX11GTK ()
457 Console.WriteLine ("XplatUIX11GTK ctor...");
458 // Handle singleton stuff first
465 gdk_init_check (out argc, argv);
467 // Now regular initialization
468 XlibLock = new object ();
469 MessageQueue = new XEventQueue ();
470 TimerList = new ArrayList ();
473 ErrorExceptions = false;
475 // X11 Initialization
476 SetDisplay (gdk_x11_display_get_xdisplay (gdk_display_get_default ()));
477 X11DesktopColors.Initialize ();
479 // Handle any upcoming errors; we re-set it here, X11DesktopColor stuff might have stolen it (gtk does)
480 ErrorHandler = new XErrorHandler (HandleError);
481 XSetErrorHandler (ErrorHandler);
483 #endregion // Constructors
485 #region Singleton Specific Code
486 public static XplatUIX11GTK GetInstance ()
489 if (Instance == null) {
490 Instance = new XplatUIX11GTK ();
497 public int Reference {
504 #region Internal Properties
505 internal static IntPtr Display {
507 return DisplayHandle;
511 XplatUIX11GTK.GetInstance ().SetDisplay (value);
515 internal static int Screen {
525 internal static IntPtr RootWindowHandle {
535 internal static IntPtr Visual {
541 CustomVisual = value;
545 internal static IntPtr ColorMap {
547 return CustomColormap;
551 CustomColormap = value;
556 #region XExceptionClass
557 internal class XException : ApplicationException {
561 XRequest RequestCode;
565 public XException (IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode)
567 this.Display = Display;
568 this.ResourceID = ResourceID;
569 this.Serial = Serial;
570 this.RequestCode = RequestCode;
571 this.ErrorCode = ErrorCode;
572 this.MinorCode = MinorCode;
575 public override string Message {
577 return GetMessage (Display, ResourceID, Serial, ErrorCode, RequestCode, MinorCode);
581 public static string GetMessage (IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode)
587 sb = new StringBuilder (160);
588 XGetErrorText (Display, ErrorCode, sb, sb.Capacity);
589 x_error_text = sb.ToString ();
591 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);
595 #endregion // XExceptionClass
597 #region Internal Methods
598 // native X display handle
599 internal void SetDisplay (IntPtr display_handle)
601 if (display_handle != IntPtr.Zero) {
604 if ((GdkDisplayHandle != IntPtr.Zero) && (GdkFosterParent != IntPtr.Zero)) {
605 hwnd = Hwnd.ObjectFromHandle (gdk_x11_drawable_get_xid (GdkFosterParent));
606 gdk_window_destroy (GdkFosterParent);
610 if (GdkDisplayHandle != IntPtr.Zero) {
611 gdk_display_close (GdkDisplayHandle);
614 DisplayHandle = display_handle;
615 GdkDisplayHandle = gdk_x11_lookup_xdisplay (display_handle);
617 // We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
618 // been hacked to do this for us.
619 Graphics.FromHdcInternal (DisplayHandle);
622 if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
623 XSynchronize (DisplayHandle, true);
626 if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
627 ErrorExceptions = true;
631 GdkScreen = gdk_screen_get_default ();
632 // or gdk_x11_get_default_screen
633 ScreenNo = gdk_screen_get_number (GdkScreen);
634 GdkRootWindow = gdk_get_default_root_window ();
635 RootWindow = gdk_x11_drawable_get_xid (GdkRootWindow);
636 GdkDefaultColormap = gdk_colormap_get_system ();
637 DefaultColormap = gdk_x11_colormap_get_xcolormap (GdkDefaultColormap);
639 VisualBestDepth = gdk_visual_get_best_depth ();
640 //Console.WriteLine (VisualBestDepth);
642 // Create the foster parent
643 FosterParent = XCreateSimpleWindow (DisplayHandle, RootWindow, 0, 0, 1, 1, 4, 0, 0);
644 GdkFosterParent = gdk_window_foreign_new (FosterParent);
646 if (GdkFosterParent == IntPtr.Zero) {
647 Console.WriteLine ("XplatUIX11GTK Constructor failed to create FosterParent");
652 hwnd.WholeWindow = FosterParent;
653 hwnd.ClientWindow = FosterParent;
655 // For sleeping on the X11 socket
656 listen = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
657 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 0);
661 // To wake up when a timer is ready
662 network_buffer = new byte [10];
664 wake = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
665 wake.Connect (listen.LocalEndPoint);
666 wake_receive = listen.Accept ();
669 pollfds = new Pollfd [2];
670 pollfds [0] = new Pollfd ();
671 pollfds [0].fd = XConnectionNumber (DisplayHandle);
672 pollfds [0].events = PollEvents.POLLIN;
674 pollfds [1] = new Pollfd ();
675 pollfds [1].fd = wake_receive.Handle.ToInt32 ();
676 pollfds [1].events = PollEvents.POLLIN;
679 Keyboard = new X11Keyboard (DisplayHandle);
680 Dnd = new X11Dnd (DisplayHandle);
682 PostQuitState = false;
684 DoubleClickInterval = 500;
686 HoverState.Interval = 500;
687 HoverState.Timer = new Timer ();
688 HoverState.Timer.Enabled = false;
689 HoverState.Timer.Interval = HoverState.Interval;
690 HoverState.Timer.Tick += new EventHandler (MouseHover);
694 ActiveWindow = IntPtr.Zero;
695 FocusWindow = IntPtr.Zero;
696 ModalWindows = new Stack (3);
698 MouseState = MouseButtons.None;
699 MousePosition = new Point (0, 0);
701 Caret.Timer = new Timer ();
702 Caret.Timer.Interval = 500; // FIXME - where should this number come from?
703 Caret.Timer.Tick += new EventHandler (CaretCallback);
707 // Grab atom changes off the root window to catch certain WM events
708 gdk_window_set_events (GdkRootWindow, (int)GdkEventMask.GDK_PROPERTY_CHANGE_MASK);
710 // Handle any upcoming errors
711 ErrorHandler = new XErrorHandler (HandleError);
712 XSetErrorHandler (ErrorHandler);
714 throw new ArgumentNullException ("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
718 internal static void Where ()
720 Console.WriteLine ("Here: {0}\n", WhereString ());
723 internal static string WhereString ()
732 newline = String.Format ("{0}\t {1} ", Environment.NewLine, Locale.GetText ("at"));
733 unknown = Locale.GetText ("<unknown method>");
734 sb = new StringBuilder ();
735 stack = new StackTrace (true);
737 for (int i = 0; i < stack.FrameCount; i++) {
738 frame = stack.GetFrame (i);
741 method = frame.GetMethod ();
742 if (method != null) {
744 sb.AppendFormat(frame.ToString());
746 if (frame.GetFileLineNumber () != 0) {
747 sb.AppendFormat ("{0}.{1} () [{2}:{3}]", method.DeclaringType.FullName, method.Name, Path.GetFileName (frame.GetFileName ()), frame.GetFileLineNumber ());
749 sb.AppendFormat ("{0}.{1} ()", method.DeclaringType.FullName, method.Name);
755 return sb.ToString ();
757 #endregion // Internal Methods
759 #region Private Methods
760 private static void SetupAtoms ()
762 NetAtoms = new int [(int)NA.LAST_NET_ATOM];
764 NetAtoms [(int)NA.WM_PROTOCOLS] = XInternAtom (DisplayHandle, "WM_PROTOCOLS", false);
765 NetAtoms [(int)NA.WM_DELETE_WINDOW] = XInternAtom (DisplayHandle, "WM_DELETE_WINDOW", false);
766 NetAtoms [(int)NA.WM_TAKE_FOCUS] = XInternAtom (DisplayHandle, "WM_TAKE_FOCUS", false);
768 NetAtoms [(int)NA._NET_SUPPORTED] = XInternAtom (DisplayHandle, "_NET_SUPPORTED", false);
769 NetAtoms [(int)NA._NET_CLIENT_LIST] = XInternAtom (DisplayHandle, "_NET_CLIENT_LIST", false);
770 NetAtoms [(int)NA._NET_NUMBER_OF_DESKTOPS] = XInternAtom (DisplayHandle, "_NET_NUMBER_OF_DESKTOPS", false);
771 NetAtoms [(int)NA._NET_DESKTOP_GEOMETRY] = XInternAtom (DisplayHandle, "_NET_DESKTOP_GEOMETRY", false);
772 NetAtoms [(int)NA._NET_DESKTOP_VIEWPORT] = XInternAtom (DisplayHandle, "_NET_DESKTOP_VIEWPORT", false);
773 NetAtoms [(int)NA._NET_CURRENT_DESKTOP] = XInternAtom (DisplayHandle, "_NET_CURRENT_DESKTOP", false);
774 NetAtoms [(int)NA._NET_DESKTOP_NAMES] = XInternAtom (DisplayHandle, "_NET_DESKTOP_NAMES", false);
775 NetAtoms [(int)NA._NET_ACTIVE_WINDOW] = XInternAtom (DisplayHandle, "_NET_ACTIVE_WINDOW", false);
776 NetAtoms [(int)NA._NET_WORKAREA] = XInternAtom (DisplayHandle, "_NET_WORKAREA", false);
777 NetAtoms [(int)NA._NET_SUPPORTING_WM_CHECK] = XInternAtom (DisplayHandle, "_NET_SUPPORTING_WM_CHECK", false);
778 NetAtoms [(int)NA._NET_VIRTUAL_ROOTS] = XInternAtom (DisplayHandle, "_NET_VIRTUAL_ROOTS", false);
779 NetAtoms [(int)NA._NET_DESKTOP_LAYOUT] = XInternAtom (DisplayHandle, "_NET_DESKTOP_LAYOUT", false);
780 NetAtoms [(int)NA._NET_SHOWING_DESKTOP] = XInternAtom (DisplayHandle, "_NET_SHOWING_DESKTOP", false);
782 NetAtoms [(int)NA._NET_CLOSE_WINDOW] = XInternAtom (DisplayHandle, "_NET_CLOSE_WINDOW", false);
783 NetAtoms [(int)NA._NET_MOVERESIZE_WINDOW] = XInternAtom (DisplayHandle, "_NET_MOVERESIZE_WINDOW", false);
784 NetAtoms [(int)NA._NET_WM_MOVERESIZE] = XInternAtom (DisplayHandle, "_NET_WM_MOVERESIZE", false);
785 NetAtoms [(int)NA._NET_RESTACK_WINDOW] = XInternAtom (DisplayHandle, "_NET_RESTACK_WINDOW", false);
786 NetAtoms [(int)NA._NET_REQUEST_FRAME_EXTENTS] = XInternAtom (DisplayHandle, "_NET_REQUEST_FRAME_EXTENTS", false);
788 NetAtoms [(int)NA._NET_WM_NAME] = XInternAtom (DisplayHandle, "_NET_WM_NAME", false);
789 NetAtoms [(int)NA._NET_WM_VISIBLE_NAME] = XInternAtom (DisplayHandle, "_NET_WM_VISIBLE_NAME", false);
790 NetAtoms [(int)NA._NET_WM_ICON_NAME] = XInternAtom (DisplayHandle, "_NET_WM_ICON_NAME", false);
791 NetAtoms [(int)NA._NET_WM_VISIBLE_ICON_NAME] = XInternAtom (DisplayHandle, "_NET_WM_VISIBLE_ICON_NAME", false);
792 NetAtoms [(int)NA._NET_WM_DESKTOP] = XInternAtom (DisplayHandle, "_NET_WM_DESKTOP", false);
793 NetAtoms [(int)NA._NET_WM_WINDOW_TYPE] = XInternAtom (DisplayHandle, "_NET_WM_WINDOW_TYPE", false);
794 NetAtoms [(int)NA._NET_WM_STATE] = XInternAtom (DisplayHandle, "_NET_WM_STATE", false);
795 NetAtoms [(int)NA._NET_WM_ALLOWED_ACTIONS] = XInternAtom (DisplayHandle, "_NET_WM_ALLOWED_ACTIONS", false);
796 NetAtoms [(int)NA._NET_WM_STRUT] = XInternAtom (DisplayHandle, "_NET_WM_STRUT", false);
797 NetAtoms [(int)NA._NET_WM_STRUT_PARTIAL] = XInternAtom (DisplayHandle, "_NET_WM_STRUT_PARTIAL", false);
798 NetAtoms [(int)NA._NET_WM_ICON_GEOMETRY] = XInternAtom (DisplayHandle, "_NET_WM_ICON_GEOMETRY", false);
799 NetAtoms [(int)NA._NET_WM_ICON] = XInternAtom (DisplayHandle, "_NET_WM_ICON", false);
800 NetAtoms [(int)NA._NET_WM_PID] = XInternAtom (DisplayHandle, "_NET_WM_PID", false);
801 NetAtoms [(int)NA._NET_WM_HANDLED_ICONS] = XInternAtom (DisplayHandle, "_NET_WM_HANDLED_ICONS", false);
802 NetAtoms [(int)NA._NET_WM_USER_TIME] = XInternAtom (DisplayHandle, "_NET_WM_USER_TIME", false);
803 NetAtoms [(int)NA._NET_FRAME_EXTENTS] = XInternAtom (DisplayHandle, "_NET_FRAME_EXTENTS", false);
805 NetAtoms [(int)NA._NET_WM_PING] = XInternAtom (DisplayHandle, "_NET_WM_PING", false);
806 NetAtoms [(int)NA._NET_WM_SYNC_REQUEST] = XInternAtom (DisplayHandle, "_NET_WM_SYNC_REQUEST", false);
808 NetAtoms [(int)NA._NET_SYSTEM_TRAY_S] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString (), false);
809 NetAtoms [(int)NA._NET_SYSTEM_TRAY_OPCODE] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_OPCODE", false);
810 NetAtoms [(int)NA._NET_SYSTEM_TRAY_ORIENTATION] = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_ORIENTATION", false);
812 NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
813 NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MAXIMIZED_VERT", false);
814 NetAtoms [(int)NA._NET_WM_STATE_HIDDEN] = XInternAtom (DisplayHandle, "_NET_WM_STATE_HIDDEN", false);
816 NetAtoms [(int)NA._XEMBED] = XInternAtom (DisplayHandle, "_XEMBED", false);
817 NetAtoms [(int)NA._XEMBED_INFO] = XInternAtom (DisplayHandle, "_XEMBED_INFO", false);
819 NetAtoms [(int)NA._MOTIF_WM_HINTS] = XInternAtom (DisplayHandle, "_MOTIF_WM_HINTS", false);
821 NetAtoms [(int)NA._NET_WM_STATE_NO_TASKBAR] = XInternAtom (DisplayHandle, "_NET_WM_STATE_NO_TASKBAR", false);
822 NetAtoms [(int)NA._NET_WM_STATE_ABOVE] = XInternAtom (DisplayHandle, "_NET_WM_STATE_ABOVE", false);
823 NetAtoms [(int)NA._NET_WM_STATE_MODAL] = XInternAtom (DisplayHandle, "_NET_WM_STATE_MODAL", false);
824 NetAtoms [(int)NA._NET_WM_CONTEXT_HELP] = XInternAtom (DisplayHandle, "_NET_WM_CONTEXT_HELP", false);
825 NetAtoms [(int)NA._NET_WM_WINDOW_OPACITY] = XInternAtom (DisplayHandle, "_NET_WM_WINDOW_OPACITY", false);
828 NetAtoms [(int)NA.CLIPBOARD] = XInternAtom (DisplayHandle, "CLIPBOARD", false);
829 NetAtoms [(int)NA.DIB] = (int)Atom.XA_PIXMAP;
830 NetAtoms [(int)NA.OEMTEXT] = XInternAtom (DisplayHandle, "COMPOUND_TEXT", false);
831 NetAtoms [(int)NA.UNICODETEXT] = XInternAtom (DisplayHandle, "UTF8_STRING", false);
832 NetAtoms [(int)NA.TARGETS] = XInternAtom (DisplayHandle, "TARGETS", false);
835 AsyncAtom = XInternAtom (DisplayHandle, "_SWF_AsyncAtom", false);
836 PostAtom = XInternAtom (DisplayHandle, "_SWF_PostMessageAtom", false);
837 HoverState.Atom = XInternAtom (DisplayHandle, "_SWF_HoverAtom", false);
840 private void GetSystrayManagerWindow ()
842 gdk_x11_grab_server ();
843 SystrayMgrWindow = XGetSelectionOwner (DisplayHandle, NetAtoms [(int)NA._NET_SYSTEM_TRAY_S]);
844 gdk_x11_ungrab_server ();
845 gdk_display_flush (GdkDisplayHandle);
848 private void SendNetWMMessage (IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2)
853 xev.ClientMessageEvent.type = XEventName.ClientMessage;
854 xev.ClientMessageEvent.send_event = true;
855 xev.ClientMessageEvent.window = window;
856 xev.ClientMessageEvent.message_type = message_type;
857 xev.ClientMessageEvent.format = 32;
858 xev.ClientMessageEvent.ptr1 = l0;
859 xev.ClientMessageEvent.ptr2 = l1;
860 xev.ClientMessageEvent.ptr3 = l2;
861 XSendEvent (DisplayHandle, RootWindow, false, EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask, ref xev);
864 private void SendNetClientMessage (IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2)
869 xev.ClientMessageEvent.type = XEventName.ClientMessage;
870 xev.ClientMessageEvent.send_event = true;
871 xev.ClientMessageEvent.window = window;
872 xev.ClientMessageEvent.message_type = message_type;
873 xev.ClientMessageEvent.format = 32;
874 xev.ClientMessageEvent.ptr1 = l0;
875 xev.ClientMessageEvent.ptr2 = l1;
876 xev.ClientMessageEvent.ptr3 = l2;
877 XSendEvent (DisplayHandle, window, false, EventMask.NoEventMask, ref xev);
880 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)
883 // Only MDI windows get caption_heights
885 tool_caption_height = 19;
887 if ((Style & (int) WindowStyles.WS_CHILD) != 0) {
888 if ((Style & (int) WindowStyles.WS_BORDER) == 0) {
889 border_style = FormBorderStyle.None;
890 } else if ((ExStyle & (int) WindowStyles.WS_EX_CLIENTEDGE) != 0) {
891 border_style = FormBorderStyle.Fixed3D;
893 border_style = FormBorderStyle.FixedSingle;
895 title_style = TitleStyle.None;
899 if ((ExStyle & (int) WindowStyles.WS_EX_MDICHILD) != 0) {
904 title_style = TitleStyle.None;
905 if ((Style & (int)WindowStyles.WS_CAPTION) != 0) {
906 if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
907 title_style = TitleStyle.Tool;
909 title_style = TitleStyle.Normal;
914 border_style = FormBorderStyle.None;
916 if ((Style & (int)WindowStyles.WS_THICKFRAME) != 0) {
917 if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
918 border_style = FormBorderStyle.SizableToolWindow;
920 border_style = FormBorderStyle.Sizable;
923 if ((ExStyle & (int)WindowStyles.WS_EX_CLIENTEDGE) != 0) {
924 border_style = FormBorderStyle.Fixed3D;
925 } else if ((ExStyle & (int)WindowStyles.WS_EX_DLGMODALFRAME) != 0) {
926 border_style = FormBorderStyle.FixedDialog;
927 } else if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
928 border_style = FormBorderStyle.FixedToolWindow;
929 } else if ((Style & (int)WindowStyles.WS_BORDER) != 0) {
930 border_style = FormBorderStyle.Sizable;
932 border_style = FormBorderStyle.None;
936 if ((Style & (int) WindowStyles.WS_OVERLAPPEDWINDOW) != 0 ||
937 (ExStyle & (int) WindowStyles.WS_EX_TOOLWINDOW) != 0) {
938 border_style = (FormBorderStyle) 0xFFFF;
940 border_style = FormBorderStyle.None;
946 private void SetHwndStyles (Hwnd hwnd, CreateParams cp)
948 DeriveStyles (hwnd.Handle, cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
951 private void SetWMStyles (Hwnd hwnd, CreateParams cp)
953 GdkWMDecoration decorations = GdkWMDecoration.GDK_DECOR_ALL;
955 if ((cp.Style & (int)WindowStyles.WS_CAPTION) != 0) {
956 decorations |= GdkWMDecoration.GDK_DECOR_TITLE | GdkWMDecoration.GDK_DECOR_MENU;
959 if ((cp.Style & ((int)WindowStyles.WS_THICKFRAME)) != 0) {
960 decorations |= GdkWMDecoration.GDK_DECOR_BORDER | GdkWMDecoration.GDK_DECOR_RESIZEH;
962 if ((cp.Style & ((int)WindowStyles.WS_MINIMIZEBOX)) != 0) {
963 decorations |= GdkWMDecoration.GDK_DECOR_MINIMIZE;
966 if ((cp.Style & ((int)WindowStyles.WS_MAXIMIZEBOX)) != 0) {
967 decorations |= GdkWMDecoration.GDK_DECOR_MAXIMIZE;
970 // is this needed ? most window managers do not even honour any MotifFunctions...
971 // if ((cp.Style & ((int)WindowStyles.WS_SYSMENU)) != 0) {
972 // functions |= MotifFunctions.Close;
975 if ((cp.ExStyle & ((int)WindowStyles.WS_EX_DLGMODALFRAME)) != 0) {
976 decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
979 if ((cp.Style & ((int)WindowStyles.WS_DLGFRAME)) != 0) {
980 decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
983 if ((cp.Style & ((int)WindowStyles.WS_BORDER)) != 0) {
984 decorations |= GdkWMDecoration.GDK_DECOR_BORDER;
987 if ((cp.ExStyle & ((int)WindowStyles.WS_EX_TOOLWINDOW)) != 0) {
991 gdk_window_set_decorations (gdk_window_foreign_new (hwnd.whole_window), (int)decorations);
994 private void SetIcon (Hwnd hwnd, Icon icon)
1001 bitmap = icon.ToBitmap ();
1003 size = bitmap.Width * bitmap.Height + 2;
1004 data = new uint [size];
1006 data [index++] = (uint)bitmap.Width;
1007 data [index++] = (uint)bitmap.Height;
1009 for (int y = 0; y < bitmap.Height; y++) {
1010 for (int x = 0; x < bitmap.Width; x++) {
1011 data [index++] = (uint)bitmap.GetPixel (x, y).ToArgb ();
1014 XChangeProperty (DisplayHandle, hwnd.whole_window, NetAtoms [(int)NA._NET_WM_ICON], Atom.XA_CARDINAL, 32, PropertyMode.Replace, data, size);
1017 private IntPtr ImageToPixmap (Image image)
1022 private void WakeupMain ()
1024 wake.Send (new byte [] { 0xFF });
1027 private void TranslatePropertyToClipboard (int property)
1033 IntPtr prop = IntPtr.Zero;
1035 Clipboard.Item = null;
1037 XGetWindowProperty (DisplayHandle, FosterParent, property, 0, 0x7fffffff, true, Atom.AnyPropertyType, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
1040 if (property == (int)Atom.XA_STRING) {
1041 Clipboard.Item = Marshal.PtrToStringAnsi (prop);
1042 } else if (property == (int)Atom.XA_BITMAP) {
1043 // FIXME - convert bitmap to image
1044 } else if (property == (int)Atom.XA_PIXMAP) {
1045 // FIXME - convert pixmap to image
1046 } else if (property == NetAtoms [(int)NA.OEMTEXT]) {
1047 Clipboard.Item = Marshal.PtrToStringAnsi (prop);
1048 } else if (property == NetAtoms [(int)NA.UNICODETEXT]) {
1049 Clipboard.Item = Marshal.PtrToStringAnsi (prop);
1056 private void AddExpose (XEvent xevent)
1060 hwnd = Hwnd.GetObjectFromWindow (xevent.AnyEvent.window);
1067 if (xevent.AnyEvent.window == hwnd.client_window) {
1068 hwnd.AddInvalidArea (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
1069 if (!hwnd.expose_pending) {
1070 MessageQueue.Enqueue (xevent);
1071 hwnd.expose_pending = true;
1074 if (!hwnd.nc_expose_pending) {
1075 MessageQueue.Enqueue (xevent);
1076 hwnd.nc_expose_pending = true;
1081 private void InvalidateWholeWindow (IntPtr handle)
1085 hwnd = Hwnd.ObjectFromHandle (handle);
1087 InvalidateWholeWindow (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height));
1090 private void InvalidateWholeWindow (IntPtr handle, Rectangle rectangle)
1095 hwnd = Hwnd.ObjectFromHandle (handle);
1098 xevent = new XEvent ();
1099 xevent.type = XEventName.Expose;
1100 xevent.ExposeEvent.display = DisplayHandle;
1101 xevent.ExposeEvent.window = hwnd.whole_window;
1103 xevent.ExposeEvent.x = rectangle.X;
1104 xevent.ExposeEvent.y = rectangle.Y;
1105 xevent.ExposeEvent.width = rectangle.Width;
1106 xevent.ExposeEvent.height = rectangle.Height;
1111 private void WholeToScreen (IntPtr handle, ref int x, ref int y)
1117 hwnd = Hwnd.ObjectFromHandle (handle);
1120 gdk_window_get_origin (gdk_window_lookup (hwnd.whole_window), out dest_x_return, out dest_y_return);
1127 private void AddConfigureNotify (XEvent xevent)
1131 hwnd = Hwnd.GetObjectFromWindow (xevent.ConfigureEvent.window);
1138 if (xevent.ConfigureEvent.window == hwnd.whole_window) {
1139 if (!hwnd.reparented) {
1140 hwnd.x = xevent.ConfigureEvent.x;
1141 hwnd.y = xevent.ConfigureEvent.y;
1145 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);
1148 hwnd.width = xevent.ConfigureEvent.width;
1149 hwnd.height = xevent.ConfigureEvent.height;
1151 if (!hwnd.configure_pending) {
1152 MessageQueue.Enqueue (xevent);
1153 hwnd.configure_pending = true;
1156 // We drop configure events for Client windows
1159 private void ShowCaret ()
1161 if ((Caret.gc == IntPtr.Zero) || Caret.On) {
1166 // gdk_gc_set_foreground
1169 XDrawLine (DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1173 private void HideCaret ()
1175 if ((Caret.gc == IntPtr.Zero) || !Caret.On) {
1180 // gdk_gc_set_foreground
1183 XDrawLine (DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1187 private int NextTimeout (DateTime now)
1189 int timeout = Int32.MaxValue;
1191 foreach (Timer timer in TimerList) {
1192 int next = (int) (timer.Expires - now).TotalMilliseconds;
1194 return 0; // Have a timer that has already expired
1197 if (next < timeout) {
1202 if (timeout < Timer.Minimum) {
1203 timeout = Timer.Minimum;
1209 private void CheckTimers (DateTime now)
1214 count = TimerList.Count;
1220 for (int i = 0; i < TimerList.Count; i++) {
1223 timer = (Timer) TimerList [i];
1225 if (timer.Enabled && timer.Expires <= now) {
1233 private void UpdateMessageQueue ()
1241 pending = XPending (DisplayHandle);
1246 Idle (this, EventArgs.Empty);
1250 pending = XPending (DisplayHandle);
1257 timeout = NextTimeout (now);
1260 Syscall.poll (pollfds, (uint) pollfds.Length, timeout);
1261 // Clean out buffer, so we're not busy-looping on the same data
1262 if (pollfds[1].revents != 0) {
1263 wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None);
1267 pending = XPending (DisplayHandle);
1276 pending = XPending (DisplayHandle);
1280 while (pending > 0) {
1281 XEvent xevent = new XEvent ();
1284 XNextEvent (DisplayHandle, ref xevent);
1286 //Console.WriteLine("Got x event {0}", xevent);
1287 switch (xevent.type) {
1288 case XEventName.Expose:
1292 case XEventName.SelectionClear: {
1293 // Should we do something?
1297 case XEventName.SelectionRequest: {
1298 if (Dnd.HandleSelectionRequestEvent (ref xevent))
1302 sel_event = new XEvent ();
1303 sel_event.SelectionEvent.type = XEventName.SelectionNotify;
1304 sel_event.SelectionEvent.send_event = true;
1305 sel_event.SelectionEvent.display = DisplayHandle;
1306 sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
1307 sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
1308 sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
1309 sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
1310 sel_event.SelectionEvent.property = 0;
1312 // Seems that some apps support asking for supported types
1313 if (xevent.SelectionEvent.target == NetAtoms [(int)NA.TARGETS]) {
1317 atoms = new uint [5];
1320 if (Clipboard.Item is String) {
1321 atoms [atom_count++] = (uint)Atom.XA_STRING;
1322 atoms [atom_count++] = (uint)NetAtoms [(int)NA.OEMTEXT];
1323 atoms [atom_count++] = (uint)NetAtoms [(int)NA.UNICODETEXT];
1324 } else if (Clipboard.Item is Image) {
1325 atoms [atom_count++] = (uint)Atom.XA_PIXMAP;
1326 atoms [atom_count++] = (uint)Atom.XA_BITMAP;
1328 // FIXME - handle other types
1331 XChangeProperty (DisplayHandle, xevent.SelectionEvent.requestor, xevent.SelectionRequestEvent.property, xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
1332 } else if (Clipboard.Item is string) {
1338 if (xevent.SelectionRequestEvent.target == (int)Atom.XA_STRING) {
1341 bytes = new ASCIIEncoding ().GetBytes ((string)Clipboard.Item);
1342 buffer = Marshal.AllocHGlobal (bytes.Length);
1343 buflen = bytes.Length;
1345 for (int i = 0; i < buflen; i++) {
1346 Marshal.WriteByte (buffer, i, bytes [i]);
1348 } else if (xevent.SelectionRequestEvent.target == NetAtoms [(int)NA.OEMTEXT]) {
1349 // FIXME - this should encode into ISO2022
1350 buffer = Marshal.StringToHGlobalAnsi ((string)Clipboard.Item);
1351 while (Marshal.ReadByte (buffer, buflen) != 0) {
1354 } else if (xevent.SelectionRequestEvent.target == NetAtoms [(int)NA.UNICODETEXT]) {
1355 buffer = Marshal.StringToHGlobalAnsi ((string)Clipboard.Item);
1356 while (Marshal.ReadByte (buffer, buflen) != 0) {
1360 buffer = IntPtr.Zero;
1363 if (buffer != IntPtr.Zero) {
1364 XChangeProperty (DisplayHandle, xevent.SelectionRequestEvent.requestor, xevent.SelectionRequestEvent.property, xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
1365 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1366 Marshal.FreeHGlobal (buffer);
1368 } else if (Clipboard.Item is Image) {
1369 if (xevent.SelectionEvent.target == (int)Atom.XA_PIXMAP) {
1370 // FIXME - convert image and store as property
1371 } else if (xevent.SelectionEvent.target == (int)Atom.XA_PIXMAP) {
1372 // FIXME - convert image and store as property
1376 XSendEvent (DisplayHandle, xevent.SelectionRequestEvent.requestor, false, EventMask.NoEventMask, ref sel_event);
1380 case XEventName.SelectionNotify: {
1381 if (Clipboard.Enumerating) {
1382 Clipboard.Enumerating = false;
1383 if (xevent.SelectionEvent.property != 0) {
1384 XDeleteProperty (DisplayHandle, FosterParent, xevent.SelectionEvent.property);
1385 if (!Clipboard.Formats.Contains (xevent.SelectionEvent.property)) {
1386 Clipboard.Formats.Add (xevent.SelectionEvent.property);
1387 #if DriverDebugExtra
1388 Console.WriteLine("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
1392 } else if (Clipboard.Retrieving) {
1393 Clipboard.Retrieving = false;
1394 if (xevent.SelectionEvent.property != 0) {
1395 TranslatePropertyToClipboard (xevent.SelectionEvent.property);
1397 Clipboard.Item = null;
1400 Dnd.HandleSelectionNotifyEvent (ref xevent);
1405 case XEventName.KeyPress:
1406 case XEventName.KeyRelease:
1407 case XEventName.ButtonPress:
1408 case XEventName.ButtonRelease:
1409 case XEventName.MotionNotify:
1410 case XEventName.EnterNotify:
1411 case XEventName.LeaveNotify:
1412 case XEventName.CreateNotify:
1413 case XEventName.DestroyNotify:
1414 case XEventName.FocusIn:
1415 case XEventName.FocusOut:
1416 case XEventName.ClientMessage:
1417 case XEventName.ReparentNotify:
1418 MessageQueue.Enqueue (xevent);
1421 case XEventName.ConfigureNotify:
1422 AddConfigureNotify (xevent);
1425 case XEventName.PropertyNotify:
1426 if (xevent.PropertyEvent.atom == NetAtoms [(int)NA._NET_ACTIVE_WINDOW]) {
1431 IntPtr prop = IntPtr.Zero;
1432 IntPtr prev_active;;
1434 prev_active = ActiveWindow;
1435 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);
1436 if ((nitems > 0) && (prop != IntPtr.Zero)) {
1437 ActiveWindow = Hwnd.GetHandleFromWindow ((IntPtr)Marshal.ReadInt32 (prop));
1440 if (prev_active != ActiveWindow) {
1441 if (prev_active != IntPtr.Zero) {
1442 PostMessage (prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
1444 if (ActiveWindow != IntPtr.Zero) {
1445 PostMessage (ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
1448 if (ModalWindows.Count == 0) {
1451 // Modality handling, if we are modal and the new active window is one
1452 // of ours but not the modal one, switch back to the modal window
1454 if (NativeWindow.FindWindow (ActiveWindow) != null) {
1455 if (ActiveWindow != (IntPtr)ModalWindows.Peek ()) {
1456 Activate ((IntPtr)ModalWindows.Peek ());
1468 pending = XPending (DisplayHandle);
1473 private IntPtr GetMousewParam (int Delta)
1477 if ((MouseState & MouseButtons.Left) != 0) {
1478 result |= (int)MsgButtons.MK_LBUTTON;
1481 if ((MouseState & MouseButtons.Middle) != 0) {
1482 result |= (int)MsgButtons.MK_MBUTTON;
1485 if ((MouseState & MouseButtons.Right) != 0) {
1486 result |= (int)MsgButtons.MK_RBUTTON;
1489 Keys mods = ModifierKeys;
1490 if ((mods & Keys.Control) != 0) {
1491 result |= (int)MsgButtons.MK_CONTROL;
1494 if ((mods & Keys.Shift) != 0) {
1495 result |= (int)MsgButtons.MK_SHIFT;
1498 result |= Delta << 16;
1500 return (IntPtr)result;
1502 private IntPtr XGetParent (IntPtr handle)
1504 return gdk_x11_drawable_get_xid (gdk_window_get_parent (gdk_window_lookup (handle)));
1507 private int HandleError (IntPtr display, ref XErrorEvent error_event)
1509 if (ErrorExceptions) {
1510 throw new XException (error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code);
1512 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), WhereString ());
1517 private void DestroyChildWindow (Control c)
1524 controls = c.child_controls.GetAllControls ();
1526 for (i = 0; i < controls.Length; i++) {
1527 if (controls [i].IsHandleCreated) {
1528 hwnd = Hwnd.ObjectFromHandle (controls [i].Handle);
1529 SendMessage (controls [i].Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
1532 DestroyChildWindow (controls [i]);
1537 #endregion // Private Methods
1540 private void MouseHover (object sender, EventArgs e)
1542 if ((HoverState.X == MousePosition.X) && (HoverState.Y == MousePosition.Y)) {
1545 HoverState.Timer.Enabled = false;
1547 if (HoverState.Window != IntPtr.Zero) {
1548 xevent = new XEvent ();
1550 xevent.type = XEventName.ClientMessage;
1551 xevent.ClientMessageEvent.display = DisplayHandle;
1552 xevent.ClientMessageEvent.window = (IntPtr)HoverState.Window;
1553 xevent.ClientMessageEvent.message_type = (IntPtr)HoverState.Atom;
1554 xevent.ClientMessageEvent.format = 32;
1555 xevent.ClientMessageEvent.ptr1 = (IntPtr) (HoverState.Y << 16 | HoverState.X);
1557 MessageQueue.EnqueueLocked (xevent);
1564 private void CaretCallback (object sender, EventArgs e)
1569 Caret.On = !Caret.On;
1571 XDrawLine (DisplayHandle, Caret.Hwnd, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1573 #endregion // Callbacks
1575 #region Public Properties
1577 internal override int Caption {
1583 internal override Size CursorSize {
1587 gdk_display_get_maximal_cursor_size (GdkDisplayHandle, out x, out y);
1589 return new Size ((int)x, (int)y);
1593 internal override bool DragFullWindows {
1599 internal override Size DragSize {
1601 return new Size (4, 4);
1605 internal override Size FrameBorderSize {
1607 throw new NotImplementedException ();
1611 internal override Size IconSize {
1617 if (XGetIconSizes (DisplayHandle, RootWindow, out list, out count) != 0) {
1621 current = (long)list;
1624 size = new XIconSize ();
1626 for (int i = 0; i < count; i++) {
1627 size = (XIconSize)Marshal.PtrToStructure ((IntPtr)current, size.GetType ());
1628 current += Marshal.SizeOf (size);
1630 // Look for our preferred size
1631 if (size.min_width == 32) {
1633 return new Size (32, 32);
1636 if (size.max_width == 32) {
1638 return new Size (32, 32);
1641 if (size.min_width < 32 && size.max_width > 32) {
1644 // check if we can fit one
1646 while (x < size.max_width) {
1647 x += size.width_inc;
1650 return new Size (32, 32);
1655 if (largest < size.max_width) {
1656 largest = size.max_width;
1660 // We didn't find a match or we wouldn't be here
1661 return new Size (largest, largest);
1664 return new Size (32, 32);
1669 internal override int KeyboardSpeed {
1672 // A lot harder: need to do:
1673 // XkbQueryExtension(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 1
1674 // XkbAllocKeyboard(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 0x080517a8
1675 // XkbGetControls(0x08051008, 1, 0x080517a8, 0xbfffdf54, 0xbfffdf58) = 0
1677 // And from that we can tell the repetition rate
1679 // Notice, the values must map to:
1680 // [0, 31] which maps to 2.5 to 30 repetitions per second.
1686 internal override int KeyboardDelay {
1689 // Return values must range from 0 to 4, 0 meaning 250ms,
1690 // and 4 meaning 1000 ms.
1692 return 1; // ie, 500 ms
1696 internal override Size MaxWindowTrackSize {
1698 return new Size (WorkingArea.Width, WorkingArea.Height);
1702 internal override Size MinimizedWindowSize {
1704 return new Size (1, 1);
1708 internal override Size MinimizedWindowSpacingSize {
1710 return new Size (1, 1);
1714 internal override Size MinimumWindowSize {
1716 return new Size (1, 1);
1720 internal override Size MinWindowTrackSize {
1722 return new Size (1, 1);
1726 internal override Keys ModifierKeys {
1728 return Keyboard.ModifierKeys;
1732 internal override Size SmallIconSize {
1738 if (XGetIconSizes (DisplayHandle, RootWindow, out list, out count) != 0) {
1742 current = (long)list;
1745 size = new XIconSize ();
1747 for (int i = 0; i < count; i++) {
1748 size = (XIconSize)Marshal.PtrToStructure ((IntPtr)current, size.GetType ());
1749 current += Marshal.SizeOf (size);
1751 // Look for our preferred size
1752 if (size.min_width == 16) {
1754 return new Size (16, 16);
1757 if (size.max_width == 16) {
1759 return new Size (16, 16);
1762 if (size.min_width < 16 && size.max_width > 16) {
1765 // check if we can fit one
1767 while (x < size.max_width) {
1768 x += size.width_inc;
1771 return new Size (16, 16);
1776 if (smallest == 0 || smallest > size.min_width) {
1777 smallest = size.min_width;
1781 // We didn't find a match or we wouldn't be here
1782 return new Size (smallest, smallest);
1785 return new Size (16, 16);
1790 internal override int MouseButtonCount {
1796 internal override bool MouseButtonsSwapped {
1798 return false; // FIXME - how to detect?
1802 internal override bool MouseWheelPresent {
1804 return true; // FIXME - how to detect?
1808 internal override Rectangle VirtualScreen {
1814 internal override Rectangle WorkingArea {
1820 IntPtr prop = IntPtr.Zero;
1824 XGetWindowProperty (DisplayHandle, RootWindow, NetAtoms [(int)NA._NET_DESKTOP_GEOMETRY], 0, 256, false, Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
1825 if ((nitems == 2) && (prop != IntPtr.Zero)) {
1826 width = Marshal.ReadInt32 (prop, 0);
1827 height = Marshal.ReadInt32 (prop, 4);
1830 return new Rectangle (0, 0, width, height);
1832 XWindowAttributes attributes=new XWindowAttributes ();
1835 XGetWindowAttributes (DisplayHandle, XRootWindow (DisplayHandle, ScreenNo), ref attributes);
1838 return new Rectangle (0, 0, attributes.width, attributes.height);
1842 #endregion // Public properties
1844 #region Public Static Methods
1845 internal override IntPtr InitializeDriver ()
1848 if (GdkDisplayHandle == IntPtr.Zero) {
1849 SetDisplay (gdk_x11_display_get_xdisplay (gdk_display_get_default ()));
1855 internal override void ShutdownDriver (IntPtr token)
1858 if (GdkDisplayHandle != IntPtr.Zero) {
1859 gdk_display_close (GdkDisplayHandle);
1860 DisplayHandle = IntPtr.Zero;
1861 GdkDisplayHandle = IntPtr.Zero;
1866 internal override void EnableThemes ()
1868 ThemesEnabled = true;
1872 internal override void Activate (IntPtr handle)
1876 hwnd = Hwnd.ObjectFromHandle (handle);
1878 if (hwnd != null) lock (XlibLock) {
1879 SendNetWMMessage (hwnd.whole_window, (IntPtr)NetAtoms [(int)NA._NET_ACTIVE_WINDOW], IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
1880 //XRaiseWindow(DisplayHandle, handle);
1885 internal override void AudibleAlert ()
1887 gdk_display_beep (gdk_x11_lookup_xdisplay (DisplayHandle));
1892 internal override void CaretVisible (IntPtr handle, bool visible)
1894 // Visible is cumulative; two hides require two shows before the caret is visible again
1895 if (Caret.Hwnd == handle) {
1897 if (Caret.Visible < 1) {
1900 if (Caret.Visible == 1) {
1902 Caret.Timer.Start ();
1907 if (Caret.Visible == 0) {
1908 Caret.Timer.Stop ();
1915 internal override bool CalculateWindowRect (IntPtr handle, ref Rectangle ClientRect, int Style, int ExStyle, Menu menu, out Rectangle WindowRect)
1917 FormBorderStyle border_style;
1918 TitleStyle title_style;
1920 int tool_caption_height;
1922 DeriveStyles (handle, Style, ExStyle, out border_style, out title_style,
1923 out caption_height, out tool_caption_height);
1925 WindowRect = Hwnd.GetWindowRectangle (border_style, menu, title_style,
1926 caption_height, tool_caption_height,
1932 internal override void ClientToScreen (IntPtr handle, ref int x, ref int y)
1939 hwnd = Hwnd.ObjectFromHandle (handle);
1942 XTranslateCoordinates (DisplayHandle, hwnd.client_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
1949 internal override int[] ClipboardAvailableFormats (IntPtr handle)
1951 DataFormats.Format f;
1954 f = DataFormats.Format.List;
1956 if (XGetSelectionOwner (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD]) == IntPtr.Zero) {
1960 Clipboard.Formats = new ArrayList ();
1963 XConvertSelection (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], f.Id, f.Id, FosterParent, IntPtr.Zero);
1965 Clipboard.Enumerating = true;
1966 while (Clipboard.Enumerating) {
1967 UpdateMessageQueue ();
1972 result = new int [Clipboard.Formats.Count];
1974 for (int i = 0; i < Clipboard.Formats.Count; i++) {
1975 result [i] = (int)Clipboard.Formats [i];
1978 Clipboard.Formats = null;
1982 internal override void ClipboardClose (IntPtr handle)
1984 if (handle != ClipMagic) {
1985 throw new ArgumentException ("handle is not a valid clipboard handle");
1990 internal override int ClipboardGetID (IntPtr handle, string format)
1992 if (handle != ClipMagic) {
1993 throw new ArgumentException ("handle is not a valid clipboard handle");
1996 if (format == "Text") return (int)Atom.XA_STRING;
1997 else if (format == "Bitmap") return (int)Atom.XA_BITMAP;
1998 //else if (format == "MetaFilePict" ) return 3;
1999 //else if (format == "SymbolicLink" ) return 4;
2000 //else if (format == "DataInterchangeFormat" ) return 5;
2001 //else if (format == "Tiff" ) return 6;
2002 else if (format == "OEMText") return XInternAtom (DisplayHandle, "COMPOUND_TEXT", false);
2003 else if (format == "DeviceIndependentBitmap") return (int)Atom.XA_PIXMAP;
2004 else if (format == "Palette") return (int)Atom.XA_COLORMAP; // Useless
2005 //else if (format == "PenData" ) return 10;
2006 //else if (format == "RiffAudio" ) return 11;
2007 //else if (format == "WaveAudio" ) return 12;
2008 else if (format == "UnicodeText") return XInternAtom (DisplayHandle, "UTF8_STRING", false);
2009 //else if (format == "EnhancedMetafile" ) return 14;
2010 //else if (format == "FileDrop" ) return 15;
2011 //else if (format == "Locale" ) return 16;
2013 return XInternAtom (DisplayHandle, format, false);
2016 internal override IntPtr ClipboardOpen ()
2021 internal override object ClipboardRetrieve (IntPtr handle, int type, XplatUI.ClipboardToObject converter)
2023 XConvertSelection (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], type, type, FosterParent, IntPtr.Zero);
2025 Clipboard.Retrieving = true;
2026 while (Clipboard.Retrieving) {
2027 UpdateMessageQueue ();
2030 return Clipboard.Item;
2033 internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter)
2035 Clipboard.Item = obj;
2036 Clipboard.Type = type;
2037 Clipboard.Converter = converter;
2040 XSetSelectionOwner (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], FosterParent, IntPtr.Zero);
2042 // Clearing the selection
2043 XSetSelectionOwner (DisplayHandle, NetAtoms [(int)NA.CLIPBOARD], IntPtr.Zero, IntPtr.Zero);
2047 internal override void CreateCaret (IntPtr handle, int width, int height)
2049 XGCValues gc_values;
2052 hwnd = Hwnd.ObjectFromHandle (handle);
2054 if (Caret.Hwnd != IntPtr.Zero) {
2055 DestroyCaret (Caret.Hwnd);
2058 Caret.Hwnd = handle;
2059 Caret.Window = hwnd.client_window;
2060 Caret.Width = width;
2061 Caret.Height = height;
2065 gc_values = new XGCValues ();
2066 gc_values.line_width = width;
2068 Caret.gc = XCreateGC (DisplayHandle, Caret.Window, GCFunction.GCLineWidth, ref gc_values);
2069 if (Caret.gc == IntPtr.Zero) {
2070 Caret.Hwnd = IntPtr.Zero;
2074 XSetFunction (DisplayHandle, Caret.gc, GXFunction.GXinvert);
2077 internal override IntPtr CreateWindow (CreateParams cp)
2079 GdkWindowAttr gdk_window_attributes;
2080 GdkWindowAttributesType attributes_mask = 0;
2086 IntPtr GdkParentHandle;
2087 IntPtr GdkWholeWindow;
2088 IntPtr GdkClientWindow;
2089 Rectangle ClientRect;
2090 GdkWindowType gdk_window_type;
2095 gdk_window_attributes = new GdkWindowAttr ();
2102 if (Width < 1) Width = 1;
2103 if (Height < 1) Height = 1;
2105 gdk_window_type = GdkWindowType.GDK_WINDOW_CHILD;
2107 if (cp.Parent != IntPtr.Zero) {
2108 GdkParentHandle = gdk_window_lookup (Hwnd.ObjectFromHandle (cp.Parent).client_window);
2110 if ((cp.Style & (int)WindowStyles.WS_CHILD) != 0) {
2111 // We need to use our foster parent window until this poor child gets it's parent assigned
2112 GdkParentHandle = GdkFosterParent;
2113 } else if ((cp.Style & (int)WindowStyles.WS_POPUP) != 0) {
2114 GdkParentHandle = GdkRootWindow;
2116 // Default position on screen, if window manager doesn't place us somewhere else
2119 GdkParentHandle = GdkRootWindow;
2123 // ValueMask = SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
2125 // Attributes.bit_gravity = Gravity.NorthWestGravity;
2126 // Attributes.win_gravity = Gravity.NorthWestGravity;
2128 // FIXME: does gdk need that ?
2129 // Save what's under the toolwindow
2130 if ((cp.ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
2131 // Attributes.save_under = true;
2132 // ValueMask |= SetWindowValuemask.SaveUnder;
2135 // If we're a popup without caption we override the WM
2136 if ((cp.Style & ((int)WindowStyles.WS_POPUP)) != 0) {
2137 if ((cp.Style & (int)WindowStyles.WS_CAPTION) == 0) {
2138 gdk_window_attributes.override_redirect = true;
2139 attributes_mask |= GdkWindowAttributesType.GDK_WA_NOREDIR;
2146 hwnd.height = Height;
2147 hwnd.parent = Hwnd.ObjectFromHandle (cp.Parent);
2149 if ((cp.Style & ((int)WindowStyles.WS_DISABLED)) != 0) {
2150 hwnd.enabled = false;
2153 ClientRect = hwnd.ClientRect;
2154 GdkClientWindow = IntPtr.Zero;
2156 gdk_window_attributes.x = X;
2157 gdk_window_attributes.y = Y;
2158 gdk_window_attributes.width = Width;
2159 gdk_window_attributes.height = Height;
2160 gdk_window_attributes.window_type = gdk_window_type;
2162 attributes_mask |= GdkWindowAttributesType.GDK_WA_X | GdkWindowAttributesType.GDK_WA_Y;
2164 gdk_window_attributes.wclass = GdkWindowClass.GDK_INPUT_OUTPUT;
2167 GdkWholeWindow = gdk_window_new (GdkParentHandle, ref gdk_window_attributes, (int)attributes_mask);
2169 if (GdkWholeWindow != IntPtr.Zero) {
2170 attributes_mask &= ~GdkWindowAttributesType.GDK_WA_NOREDIR;
2172 if (GdkCustomVisual != IntPtr.Zero && GdkCustomColormap != IntPtr.Zero) {
2173 attributes_mask |= GdkWindowAttributesType.GDK_WA_COLORMAP | GdkWindowAttributesType.GDK_WA_VISUAL;
2174 gdk_window_attributes.colormap = GdkCustomColormap;
2175 gdk_window_attributes.visual = GdkCustomVisual;
2178 gdk_window_attributes.x = ClientRect.X;
2179 gdk_window_attributes.y = ClientRect.Y;
2180 gdk_window_attributes.width = ClientRect.Width;
2181 gdk_window_attributes.height = ClientRect.Height;
2183 GdkClientWindow = gdk_window_new (GdkWholeWindow, ref gdk_window_attributes, (int)attributes_mask);
2187 if ((GdkWholeWindow == IntPtr.Zero) || (GdkClientWindow == IntPtr.Zero)) {
2188 throw new Exception ("Could not create X11 Gdk windows");
2191 hwnd.WholeWindow = gdk_x11_drawable_get_xid (GdkWholeWindow);
2192 hwnd.ClientWindow = gdk_x11_drawable_get_xid (GdkClientWindow);
2195 Console.WriteLine("Created window {0:X} / {1:X} parent {2:X}", ClientWindow.ToInt32(), WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0);
2199 gdk_window_set_events (GdkWholeWindow, (int)GdkSelectInputMask);
2200 gdk_window_set_events (GdkClientWindow, (int)GdkSelectInputMask);
2202 if ((cp.Style & (int)WindowStyles.WS_VISIBLE) != 0) {
2203 gdk_window_show (GdkWholeWindow);
2204 gdk_window_show (GdkClientWindow);
2205 hwnd.visible = true;
2209 SetWMStyles (hwnd, cp);
2211 if ((cp.Style & (int)WindowStyles.WS_MINIMIZE) != 0) {
2212 SetWindowState (hwnd.Handle, FormWindowState.Minimized);
2213 } else if ((cp.Style & (int)WindowStyles.WS_MAXIMIZE) != 0) {
2214 SetWindowState (hwnd.Handle, FormWindowState.Maximized);
2217 // for now make all windows dnd enabled
2218 Dnd.SetAllowDrop (hwnd, true);
2220 // Set caption/window title
2221 Text (hwnd.Handle, cp.Caption);
2226 internal override IntPtr CreateWindow (IntPtr Parent, int X, int Y, int Width, int Height)
2228 CreateParams create_params = new CreateParams ();
2230 create_params.Caption = "";
2231 create_params.X = X;
2232 create_params.Y = Y;
2233 create_params.Width = Width;
2234 create_params.Height = Height;
2236 create_params.ClassName = XplatUI.DefaultClassName;
2237 create_params.ClassStyle = 0;
2238 create_params.ExStyle = 0;
2239 create_params.Parent = IntPtr.Zero;
2240 create_params.Param = 0;
2242 return CreateWindow (create_params);
2245 internal override IntPtr DefineCursor (Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot)
2248 Bitmap cursor_bitmap;
2256 IntPtr cursor_pixmap;
2263 Size cursor_size = CursorSize;
2264 width = cursor_size.Width;
2265 height = cursor_size.Height;
2267 // Win32 only allows creation cursors of a certain size
2268 if ((bitmap.Width != width) || (bitmap.Width != height)) {
2269 cursor_bitmap = new Bitmap (bitmap, new Size (width, height));
2270 cursor_mask = new Bitmap (mask, new Size (width, height));
2272 cursor_bitmap = bitmap;
2276 width = cursor_bitmap.Width;
2277 height = cursor_bitmap.Height;
2279 cursor_bits = new Byte [(width / 8) * height];
2280 mask_bits = new Byte [(width / 8) * height];
2282 for (int y = 0; y < height; y++) {
2283 for (int x = 0; x < width; x++) {
2284 c_pixel = cursor_bitmap.GetPixel (x, y);
2285 m_pixel = cursor_mask.GetPixel (x, y);
2287 and = c_pixel == cursor_pixel;
2288 xor = m_pixel == mask_pixel;
2292 // cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8))); // The bit already is 0
2293 mask_bits [y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
2294 } else if (and && !xor) {
2296 cursor_bits [y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
2297 mask_bits [y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
2299 } else if (and && !xor) {
2301 } else if (and && xor) {
2304 // X11 doesn't know the 'reverse screen' concept, so we'll treat them the same
2305 // we want both to be 0 so nothing to be done
2306 //cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));
2307 //mask_bits[y * width / 8 + x / 8] |= (byte)(01 << (x % 8));
2313 cursor_pixmap = XCreatePixmapFromBitmapData (DisplayHandle, RootWindow, cursor_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
2314 mask_pixmap = XCreatePixmapFromBitmapData (DisplayHandle, RootWindow, mask_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
2318 fg.pixel = XWhitePixel (DisplayHandle, ScreenNo);
2319 fg.red = (ushort)65535;
2320 fg.green = (ushort)65535;
2321 fg.blue = (ushort)65535;
2323 bg.pixel = XBlackPixel (DisplayHandle, ScreenNo);
2325 cursor = XCreatePixmapCursor (DisplayHandle, cursor_pixmap, mask_pixmap, ref fg, ref bg, xHotSpot, yHotSpot);
2327 XFreePixmap (DisplayHandle, cursor_pixmap);
2328 XFreePixmap (DisplayHandle, mask_pixmap);
2333 internal override IntPtr DefineStdCursor (StdCursor id)
2335 CursorFontShape shape;
2338 // FIXME - define missing shapes
2341 case StdCursor.AppStarting: {
2342 shape = CursorFontShape.XC_watch;
2346 case StdCursor.Arrow: {
2350 case StdCursor.Cross: {
2351 shape = CursorFontShape.XC_crosshair;
2355 case StdCursor.Default: {
2359 case StdCursor.Hand: {
2360 shape = CursorFontShape.XC_hand1;
2364 case StdCursor.Help: {
2365 shape = CursorFontShape.XC_question_arrow;
2369 case StdCursor.HSplit: {
2370 shape = CursorFontShape.XC_sb_v_double_arrow;
2374 case StdCursor.IBeam: {
2375 shape = CursorFontShape.XC_xterm;
2379 case StdCursor.No: {
2380 shape = CursorFontShape.XC_circle;
2384 case StdCursor.NoMove2D: {
2385 shape = CursorFontShape.XC_fleur;
2389 case StdCursor.NoMoveHoriz: {
2390 shape = CursorFontShape.XC_fleur;
2394 case StdCursor.NoMoveVert: {
2395 shape = CursorFontShape.XC_fleur;
2399 case StdCursor.PanEast: {
2400 shape = CursorFontShape.XC_fleur;
2404 case StdCursor.PanNE: {
2405 shape = CursorFontShape.XC_fleur;
2409 case StdCursor.PanNorth: {
2410 shape = CursorFontShape.XC_fleur;
2414 case StdCursor.PanNW: {
2415 shape = CursorFontShape.XC_fleur;
2419 case StdCursor.PanSE: {
2420 shape = CursorFontShape.XC_fleur;
2424 case StdCursor.PanSouth: {
2425 shape = CursorFontShape.XC_fleur;
2429 case StdCursor.PanSW: {
2430 shape = CursorFontShape.XC_fleur;
2434 case StdCursor.PanWest: {
2435 shape = CursorFontShape.XC_sizing;
2439 case StdCursor.SizeAll: {
2440 shape = CursorFontShape.XC_fleur;
2444 case StdCursor.SizeNESW: {
2445 shape = CursorFontShape.XC_top_right_corner;
2449 case StdCursor.SizeNS: {
2450 shape = CursorFontShape.XC_sb_v_double_arrow;
2454 case StdCursor.SizeNWSE: {
2455 shape = CursorFontShape.XC_top_left_corner;
2459 case StdCursor.SizeWE: {
2460 shape = CursorFontShape.XC_sb_h_double_arrow;
2464 case StdCursor.UpArrow: {
2465 shape = CursorFontShape.XC_center_ptr;
2469 case StdCursor.VSplit: {
2470 shape = CursorFontShape.XC_sb_h_double_arrow;
2474 case StdCursor.WaitCursor: {
2475 shape = CursorFontShape.XC_watch;
2485 cursor = XCreateFontCursor (DisplayHandle, shape);
2490 internal override IntPtr DefWndProc (ref Message msg)
2495 internal override void DestroyCaret (IntPtr handle)
2497 if (Caret.Hwnd == handle) {
2498 if (Caret.Visible == 1) {
2499 Caret.Timer.Stop ();
2502 if (Caret.gc != IntPtr.Zero) {
2503 XFreeGC (DisplayHandle, Caret.gc);
2504 Caret.gc = IntPtr.Zero;
2506 Caret.Hwnd = IntPtr.Zero;
2512 internal override void DestroyCursor (IntPtr cursor)
2515 XFreeCursor (DisplayHandle, cursor);
2519 internal override void DestroyWindow (IntPtr handle)
2523 hwnd = Hwnd.ObjectFromHandle (handle);
2527 Console.WriteLine("window {0:X} already destroyed", handle.ToInt32());
2533 Console.WriteLine("Destroying window {0:X}", handle.ToInt32());
2536 // Make sure if the caret is in the window, that we destroy the caret, too
2537 if (Caret.Hwnd == hwnd.client_window) {
2538 DestroyCaret (handle);
2541 // Mark our children as gone as well
2542 DestroyChildWindow (Control.ControlNativeWindow.ControlFromHandle (handle));
2544 // Send destroy message
2545 SendMessage (handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
2548 if (hwnd.client_window != IntPtr.Zero) {
2549 gdk_window_destroy (gdk_window_lookup (hwnd.client_window));
2552 if ((hwnd.whole_window != IntPtr.Zero) && (hwnd.whole_window != hwnd.client_window)) {
2553 gdk_window_destroy (gdk_window_lookup (hwnd.whole_window));
2559 internal override IntPtr DispatchMessage (ref MSG msg)
2561 return NativeWindow.WndProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
2564 internal override void DrawReversibleRectangle (IntPtr handle, Rectangle rect, int line_width)
2567 XGCValues gc_values;
2570 hwnd = Hwnd.ObjectFromHandle (handle);
2572 gc_values = new XGCValues ();
2574 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
2575 gc_values.line_width = line_width;
2576 gc_values.foreground = XBlackPixel (DisplayHandle, ScreenNo);
2578 // This logic will give us true rubber bands: (libsx, SANE_XOR)
2579 //mask = foreground ^ background;
2580 //XSetForeground(DisplayHandle, gc, 0xffffffff);
2581 //XSetBackground(DisplayHandle, gc, background);
2582 //XSetFunction(DisplayHandle, gc, GXxor);
2583 //XSetPlaneMask(DisplayHandle, gc, mask);
2586 gc = XCreateGC (DisplayHandle, hwnd.client_window, GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground, ref gc_values);
2591 control = Control.FromHandle (handle);
2593 XColor xcolor = new XColor ();
2595 xcolor.red = (ushort)(control.ForeColor.R * 257);
2596 xcolor.green = (ushort)(control.ForeColor.G * 257);
2597 xcolor.blue = (ushort)(control.ForeColor.B * 257);
2598 XAllocColor (DisplayHandle, DefaultColormap, ref xcolor);
2599 foreground = (uint)xcolor.pixel.ToInt32 ();
2601 xcolor.red = (ushort)(control.BackColor.R * 257);
2602 xcolor.green = (ushort)(control.BackColor.G * 257);
2603 xcolor.blue = (ushort)(control.BackColor.B * 257);
2604 XAllocColor (DisplayHandle, DefaultColormap, ref xcolor);
2605 background = (uint)xcolor.pixel.ToInt32 ();
2607 uint mask = foreground ^ background;
2609 XSetForeground (DisplayHandle, gc, 0xffffffff);
2610 XSetBackground (DisplayHandle, gc, background);
2611 XSetFunction (DisplayHandle, gc, GXFunction.GXxor);
2612 XSetPlaneMask (DisplayHandle, gc, mask);
2614 if ((rect.Width > 0) && (rect.Height > 0)) {
2615 XDrawRectangle (DisplayHandle, hwnd.client_window, gc, rect.Left, rect.Top, rect.Width, rect.Height);
2617 if (rect.Width > 0) {
2618 XDrawLine (DisplayHandle, hwnd.client_window, gc, rect.X, rect.Y, rect.Right, rect.Y);
2620 XDrawLine (DisplayHandle, hwnd.client_window, gc, rect.X, rect.Y, rect.X, rect.Bottom);
2623 XFreeGC (DisplayHandle, gc);
2626 internal override void DoEvents ()
2628 MSG msg = new MSG ();
2630 if (OverrideCursorHandle != IntPtr.Zero) {
2631 OverrideCursorHandle = IntPtr.Zero;
2634 while (PeekMessage (ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
2635 TranslateMessage (ref msg);
2636 DispatchMessage (ref msg);
2640 internal override void EnableWindow (IntPtr handle, bool Enable)
2644 hwnd = Hwnd.ObjectFromHandle (handle);
2646 hwnd.Enabled = Enable;
2650 internal override void EndLoop (Thread thread)
2652 // This is where we one day will shut down the loop for the thread
2656 internal override IntPtr GetActive ()
2662 IntPtr prop = IntPtr.Zero;
2663 IntPtr active = IntPtr.Zero;
2665 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);
2666 if ((nitems > 0) && (prop != IntPtr.Zero)) {
2667 active = (IntPtr)Marshal.ReadInt32 (prop);
2671 if (active != IntPtr.Zero) {
2674 hwnd = Hwnd.GetObjectFromWindow (active);
2676 active = hwnd.Handle;
2678 active = IntPtr.Zero;
2684 internal override void GetCursorInfo (IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y)
2686 throw new NotImplementedException ();
2689 internal override void GetDisplaySize (out Size size)
2691 XWindowAttributes attributes=new XWindowAttributes ();
2694 // FIXME - use _NET_WM messages instead?
2695 XGetWindowAttributes (DisplayHandle, XRootWindow (DisplayHandle, ScreenNo), ref attributes);
2698 size = new Size (attributes.width, attributes.height);
2701 internal override SizeF GetAutoScaleSize (Font font)
2705 string magic_string = "The quick brown fox jumped over the lazy dog.";
2706 double magic_number = 44.549996948242189;
2708 g = Graphics.FromHwnd (FosterParent);
2710 width = (float) (g.MeasureString (magic_string, font).Width / magic_number);
2711 return new SizeF (width, font.Height);
2714 internal override IntPtr GetParent (IntPtr handle)
2718 hwnd = Hwnd.ObjectFromHandle (handle);
2719 if (hwnd != null && hwnd.parent != null) {
2720 return hwnd.parent.Handle;
2725 internal override void GetCursorPos (IntPtr handle, out int x, out int y)
2736 if (handle != IntPtr.Zero) {
2737 use_handle = Hwnd.ObjectFromHandle (handle).client_window;
2739 use_handle = RootWindow;
2743 XQueryPointer (DisplayHandle, use_handle, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
2746 if (handle != IntPtr.Zero) {
2755 internal override bool GetFontMetrics (Graphics g, Font font, out int ascent, out int descent)
2757 return GetFontMetrics (g.GetHdc (), font.ToHfont (), out ascent, out descent);
2760 internal override Point GetMenuOrigin (IntPtr handle)
2764 hwnd = Hwnd.ObjectFromHandle (handle);
2767 return hwnd.MenuOrigin;
2772 internal override bool GetMessage (ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
2780 if (MessageQueue.Count > 0) {
2781 xevent = (XEvent) MessageQueue.Dequeue ();
2783 UpdateMessageQueue ();
2785 if (MessageQueue.Count > 0) {
2786 xevent = (XEvent) MessageQueue.Dequeue ();
2788 if (!PostQuitState) {
2789 msg.hwnd = IntPtr.Zero;
2790 msg.message = Msg.WM_ENTERIDLE;
2794 // We reset ourselves so GetMessage can be called again
2795 PostQuitState = false;
2801 // FIXME - handle filtering
2803 hwnd = Hwnd.GetObjectFromWindow (xevent.AnyEvent.window);
2805 // Handle messages for windows that are already or are about to be destroyed
2808 Console.WriteLine("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
2810 goto ProcessNextMessage;
2813 if (hwnd.client_window == xevent.AnyEvent.window) {
2815 //Console.WriteLine("Client message, sending to window {0:X}", msg.hwnd.ToInt32());
2818 //Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
2821 msg.hwnd = hwnd.Handle;
2824 // If you add a new event to this switch make sure to add it in
2825 // UpdateMessage also unless it is not coming through the X event system.
2827 switch (xevent.type) {
2828 case XEventName.KeyPress: {
2829 Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
2833 case XEventName.KeyRelease: {
2834 Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
2838 case XEventName.ButtonPress: {
2839 switch (xevent.ButtonEvent.button) {
2841 MouseState |= MouseButtons.Left;
2843 msg.message = Msg.WM_LBUTTONDOWN;
2845 msg.message = Msg.WM_NCLBUTTONDOWN;
2846 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2848 // TODO: For WM_NCLBUTTONDOWN wParam specifies a hit-test value not the virtual keys down
2849 msg.wParam = GetMousewParam (0);
2854 MouseState |= MouseButtons.Middle;
2856 msg.message = Msg.WM_MBUTTONDOWN;
2858 msg.message = Msg.WM_NCMBUTTONDOWN;
2859 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2861 msg.wParam = GetMousewParam (0);
2866 MouseState |= MouseButtons.Right;
2868 msg.message = Msg.WM_RBUTTONDOWN;
2870 msg.message = Msg.WM_NCRBUTTONDOWN;
2871 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2873 msg.wParam = GetMousewParam (0);
2878 msg.message = Msg.WM_MOUSEWHEEL;
2879 msg.wParam = GetMousewParam (120);
2884 msg.message = Msg.WM_MOUSEWHEEL;
2885 msg.wParam = GetMousewParam (-120);
2891 msg.lParam = (IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
2892 MousePosition.X = xevent.ButtonEvent.x;
2893 MousePosition.Y = xevent.ButtonEvent.y;
2895 if (!hwnd.Enabled) {
2898 msg.hwnd = hwnd.EnabledHwnd;
2899 XTranslateCoordinates (DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle (msg.hwnd).ClientWindow, xevent.ButtonEvent.x, xevent.ButtonEvent.y, out xevent.ButtonEvent.x, out xevent.ButtonEvent.y, out dummy);
2900 msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
2903 if (Grab.Hwnd != IntPtr.Zero) {
2904 msg.hwnd = Grab.Hwnd;
2907 if (!ClickPending.Pending) {
2908 ClickPending.Pending = true;
2909 ClickPending.Hwnd = msg.hwnd;
2910 ClickPending.Message = msg.message;
2911 ClickPending.wParam = msg.wParam;
2912 ClickPending.lParam = msg.lParam;
2913 ClickPending.Time = (long)xevent.ButtonEvent.time;
2915 if ((((long)xevent.ButtonEvent.time - ClickPending.Time) < DoubleClickInterval) && (msg.wParam == ClickPending.wParam) && (msg.lParam == ClickPending.lParam) && (msg.message == ClickPending.Message)) {
2916 // Looks like a genuine double click, clicked twice on the same spot with the same keys
2917 switch (xevent.ButtonEvent.button) {
2919 msg.message = client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK;
2924 msg.message = client ? Msg.WM_MBUTTONDBLCLK : Msg.WM_NCMBUTTONDBLCLK;
2929 msg.message = client ? Msg.WM_RBUTTONDBLCLK : Msg.WM_NCRBUTTONDBLCLK;
2934 ClickPending.Pending = false;
2940 case XEventName.ButtonRelease: {
2941 Dnd.HandleButtonRelease (ref xevent);
2942 switch (xevent.ButtonEvent.button) {
2944 MouseState &= ~MouseButtons.Left;
2946 msg.message = Msg.WM_LBUTTONUP;
2948 msg.message = Msg.WM_NCLBUTTONUP;
2949 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2951 msg.wParam = GetMousewParam (0);
2956 MouseState &= ~MouseButtons.Middle;
2958 msg.message = Msg.WM_MBUTTONUP;
2960 msg.message = Msg.WM_NCMBUTTONUP;
2961 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2963 msg.wParam = GetMousewParam (0);
2968 MouseState &= ~MouseButtons.Right;
2970 msg.message = Msg.WM_RBUTTONUP;
2972 msg.message = Msg.WM_NCRBUTTONUP;
2973 WholeToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
2975 msg.wParam = GetMousewParam (0);
2980 goto ProcessNextMessage;
2984 goto ProcessNextMessage;
2988 if (!hwnd.Enabled) {
2991 msg.hwnd = hwnd.EnabledHwnd;
2992 XTranslateCoordinates (DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle (msg.hwnd).ClientWindow, xevent.ButtonEvent.x, xevent.ButtonEvent.y, out xevent.ButtonEvent.x, out xevent.ButtonEvent.y, out dummy);
2993 msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
2996 if (Grab.Hwnd != IntPtr.Zero) {
2997 msg.hwnd = Grab.Hwnd;
3000 msg.lParam = (IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
3001 MousePosition.X = xevent.ButtonEvent.x;
3002 MousePosition.Y = xevent.ButtonEvent.y;
3006 case XEventName.MotionNotify: {
3008 #if DriverDebugExtra
3009 Console.WriteLine("GetMessage(): Window {0:X} MotionNotify x={1} y={2}", client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(), xevent.MotionEvent.x, xevent.MotionEvent.y);
3012 if (Dnd.HandleMotionNotify (ref xevent))
3013 goto ProcessNextMessage;
3014 if (Grab.Hwnd != IntPtr.Zero) {
3015 msg.hwnd = Grab.Hwnd;
3017 NativeWindow.WndProc (msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
3020 msg.message = Msg.WM_MOUSEMOVE;
3021 msg.wParam = GetMousewParam (0);
3022 msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
3024 if (!hwnd.Enabled) {
3027 msg.hwnd = hwnd.EnabledHwnd;
3028 XTranslateCoordinates (DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle (msg.hwnd).ClientWindow, xevent.MotionEvent.x, xevent.MotionEvent.y, out xevent.MotionEvent.x, out xevent.MotionEvent.y, out dummy);
3029 msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
3032 HoverState.X = MousePosition.X = xevent.MotionEvent.x;
3033 HoverState.Y = MousePosition.Y = xevent.MotionEvent.y;
3037 #if DriverDebugExtra
3038 Console.WriteLine("GetMessage(): non-client area {0:X} MotionNotify x={1} y={2}", client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(), xevent.MotionEvent.x, xevent.MotionEvent.y);
3040 msg.message = Msg.WM_NCMOUSEMOVE;
3041 msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
3043 if (!hwnd.Enabled) {
3046 msg.hwnd = hwnd.EnabledHwnd;
3047 XTranslateCoordinates (DisplayHandle, xevent.AnyEvent.window, Hwnd.ObjectFromHandle (msg.hwnd).ClientWindow, xevent.MotionEvent.x, xevent.MotionEvent.y, out xevent.MotionEvent.x, out xevent.MotionEvent.y, out dummy);
3048 msg.lParam = (IntPtr)(MousePosition.Y << 16 | MousePosition.X);
3052 // Not sure we need this...
3054 ht = NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero, msg.lParam);
3057 MousePosition.X = xevent.MotionEvent.x;
3058 MousePosition.Y = xevent.MotionEvent.y;
3064 case XEventName.EnterNotify: {
3065 if (!hwnd.Enabled) {
3066 goto ProcessNextMessage;
3068 if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
3069 goto ProcessNextMessage;
3071 msg.message = Msg.WM_MOUSE_ENTER;
3072 HoverState.Timer.Enabled = true;
3073 HoverState.Window = xevent.CrossingEvent.window;
3077 case XEventName.LeaveNotify: {
3078 if (!hwnd.Enabled) {
3079 goto ProcessNextMessage;
3081 if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
3082 goto ProcessNextMessage;
3084 msg.message = Msg.WM_MOUSE_LEAVE;
3085 HoverState.Timer.Enabled = false;
3086 HoverState.Window = IntPtr.Zero;
3091 case XEventName.CreateNotify: {
3092 if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {
3093 msg.message = WM_CREATE;
3094 // Set up CreateStruct
3096 goto ProcessNextMessage;
3103 case XEventName.ReparentNotify: {
3104 if (hwnd.parent == null) { // Toplevel
3105 if (xevent.ReparentEvent.parent != IntPtr.Zero) {
3106 // We need to adjust x/y
3109 hwnd.Reparented = true;
3111 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);
3112 msg.message = Msg.WM_WINDOWPOSCHANGED;
3113 if (hwnd.opacity != 0xffffffff) {
3116 opacity = hwnd.opacity;
3117 XChangeProperty (DisplayHandle, XGetParent (hwnd.whole_window), NetAtoms [(int)NA._NET_WM_WINDOW_OPACITY], Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
3120 hwnd.Reparented = false;
3121 goto ProcessNextMessage;
3127 case XEventName.ConfigureNotify: {
3128 if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
3129 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
3133 #if DriverDebugExtra
3134 Console.WriteLine("GetMessage(): Window {0:X} ConfigureNotify x={1} y={2} width={3} height={4}", hwnd.client_window.ToInt32(), xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
3136 msg.message = Msg.WM_WINDOWPOSCHANGED;
3137 hwnd.configure_pending = false;
3139 // We need to adjust our client window to track the resize of whole_window
3140 rect = hwnd.DefaultClientRect;
3142 ncp = new XplatUIWin32.NCCALCSIZE_PARAMS ();
3143 ptr = Marshal.AllocHGlobal (Marshal.SizeOf (ncp));
3145 ncp.rgrc1.left = rect.Left;
3146 ncp.rgrc1.top = rect.Top;
3147 ncp.rgrc1.right = rect.Right;
3148 ncp.rgrc1.bottom = rect.Bottom;
3150 Marshal.StructureToPtr (ncp, ptr, true);
3151 NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
3152 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
3153 Marshal.FreeHGlobal (ptr);
3155 // FIXME - debug this with Menus, need to set hwnd.ClientRect
3157 rect = new Rectangle (ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
3158 //Console.WriteLine("CreateOffscreenbuffer...");
3159 // CreateOffscreenBuffer (ref hwnd.client_offscreen, rect.Width, rect.Height);
3161 XMoveResizeWindow (DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
3163 goto ProcessNextMessage;
3166 msg.lParam = IntPtr.Zero; // FIXME - Generate LPWINDOWPOS structure and pass on
3170 case XEventName.FocusIn: {
3171 if (!hwnd.Enabled) {
3172 goto ProcessNextMessage;
3174 msg.message = Msg.WM_SETFOCUS;
3175 msg.wParam = IntPtr.Zero;
3179 case XEventName.FocusOut: {
3180 if (!hwnd.Enabled) {
3181 goto ProcessNextMessage;
3183 msg.message = Msg.WM_KILLFOCUS;
3184 msg.wParam = IntPtr.Zero;
3188 case XEventName.Expose: {
3189 if (PostQuitState) {
3190 goto ProcessNextMessage;
3195 if (!hwnd.expose_pending) {
3196 goto ProcessNextMessage;
3199 if (!hwnd.nc_expose_pending) {
3200 goto ProcessNextMessage;
3203 switch (hwnd.border_style) {
3204 case FormBorderStyle.Fixed3D: {
3207 g = Graphics.FromHwnd (hwnd.whole_window);
3208 ControlPaint.DrawBorder3D (g, new Rectangle (0, 0, hwnd.Width, hwnd.Height));
3213 case FormBorderStyle.FixedSingle: {
3216 g = Graphics.FromHwnd (hwnd.whole_window);
3217 ControlPaint.DrawBorder (g, new Rectangle (0, 0, hwnd.Width, hwnd.Height), Color.Black, ButtonBorderStyle.Solid);
3222 #if DriverDebugExtra
3223 Console.WriteLine("GetMessage(): Window {0:X} Exposed non-client area {1},{2} {3}x{4}", hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
3226 Rectangle rect = new Rectangle (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
3227 Region region = new Region (rect);
3228 IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
3229 msg.message = Msg.WM_NCPAINT;
3231 hwnd.nc_expose_pending = false;
3234 #if DriverDebugExtra
3235 Console.WriteLine("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}", hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
3237 if (Caret.Visible == 1) {
3238 Caret.Paused = true;
3242 if (Caret.Visible == 1) {
3244 Caret.Paused = false;
3246 msg.message = Msg.WM_PAINT;
3250 case XEventName.DestroyNotify: {
3252 // This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
3253 hwnd = Hwnd.ObjectFromHandle (xevent.DestroyWindowEvent.window);
3255 // We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
3256 if (hwnd.client_window == xevent.DestroyWindowEvent.window) {
3257 msg.hwnd = hwnd.client_window;
3258 msg.message = Msg.WM_DESTROY;
3262 Console.WriteLine("Got DestroyNotify on Window {0:X}", msg.hwnd.ToInt32());
3265 goto ProcessNextMessage;
3271 case XEventName.ClientMessage: {
3272 if (Dnd.HandleClientMessage (ref xevent)) {
3273 goto ProcessNextMessage;
3276 if (xevent.ClientMessageEvent.message_type == (IntPtr)AsyncAtom) {
3277 XplatUIDriverSupport.ExecuteClientMessage ((GCHandle)xevent.ClientMessageEvent.ptr1);
3281 if (xevent.ClientMessageEvent.message_type == (IntPtr)HoverState.Atom) {
3282 msg.message = Msg.WM_MOUSEHOVER;
3283 msg.wParam = GetMousewParam (0);
3284 msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
3288 if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {
3289 msg.hwnd = xevent.ClientMessageEvent.ptr1;
3290 msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
3291 msg.wParam = xevent.ClientMessageEvent.ptr3;
3292 msg.lParam = xevent.ClientMessageEvent.ptr4;
3297 if (xevent.ClientMessageEvent.message_type == (IntPtr)NetAtoms[(int)NA._XEMBED]) {
3298 Console.WriteLine("GOT EMBED MESSAGE {0:X}", xevent.ClientMessageEvent.ptr2.ToInt32());
3303 if (xevent.ClientMessageEvent.message_type == (IntPtr)NetAtoms [(int)NA.WM_PROTOCOLS]) {
3304 if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms [(int)NA.WM_DELETE_WINDOW]) {
3305 msg.message = Msg.WM_CLOSE;
3306 Graphics.FromHdcInternal (IntPtr.Zero);
3310 // We should not get this, but I'll leave the code in case we need it in the future
3311 if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms [(int)NA.WM_TAKE_FOCUS]) {
3312 goto ProcessNextMessage;
3318 case XEventName.TimerNotify: {
3319 xevent.TimerNotifyEvent.handler (this, EventArgs.Empty);
3324 goto ProcessNextMessage;
3331 internal override bool GetText (IntPtr handle, out string text)
3335 textptr = IntPtr.Zero;
3338 // FIXME - use _NET properties
3339 XFetchName (DisplayHandle, Hwnd.ObjectFromHandle (handle).whole_window, ref textptr);
3341 if (textptr != IntPtr.Zero) {
3342 text = Marshal.PtrToStringAnsi (textptr);
3351 internal override void GetWindowPos (IntPtr handle, bool is_toplevel, out int x, out int y, out int width, out int height, out int client_width, out int client_height)
3356 hwnd = Hwnd.ObjectFromHandle (handle);
3362 height = hwnd.height;
3364 rect = Hwnd.GetClientRectangle (hwnd.border_style, hwnd.menu, hwnd.title_style, hwnd.caption_height, hwnd.tool_caption_height, width, height);
3366 client_width = rect.Width;
3367 client_height = rect.Height;
3372 // Should we throw an exception or fail silently?
3373 // throw new ArgumentException("Called with an invalid window handle", "handle");
3383 internal override FormWindowState GetWindowState (IntPtr handle)
3389 IntPtr prop = IntPtr.Zero;
3393 XWindowAttributes attributes;
3396 hwnd = Hwnd.ObjectFromHandle (handle);
3400 XGetWindowProperty (DisplayHandle, hwnd.whole_window, NetAtoms [(int)NA._NET_WM_STATE], 0, 256, false, Atom.XA_ATOM, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
3401 if ((nitems > 0) && (prop != IntPtr.Zero)) {
3402 for (int i = 0; i < nitems; i++) {
3403 atom = (IntPtr)Marshal.ReadInt32 (prop, i * 4);
3404 if ((atom == (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ]) || (atom == (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT])) {
3406 } else if (atom == (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_HIDDEN]) {
3414 return FormWindowState.Minimized;
3415 } else if (maximized == 2) {
3416 return FormWindowState.Maximized;
3419 attributes = new XWindowAttributes ();
3420 XGetWindowAttributes (DisplayHandle, handle, ref attributes);
3421 if (attributes.map_state == MapState.IsUnmapped) {
3422 throw new NotSupportedException ("Cannot retrieve the state of an unmapped window");
3426 return FormWindowState.Normal;
3429 internal override void GrabInfo (out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea)
3432 GrabConfined = Grab.Confined;
3433 GrabArea = Grab.Area;
3436 internal override void GrabWindow (IntPtr handle, IntPtr confine_to_handle)
3439 IntPtr confine_to_window;
3441 confine_to_window = IntPtr.Zero;
3443 if (confine_to_handle != IntPtr.Zero) {
3444 XWindowAttributes attributes = new XWindowAttributes ();
3446 hwnd = Hwnd.ObjectFromHandle (confine_to_handle);
3449 XGetWindowAttributes (DisplayHandle, hwnd.client_window, ref attributes);
3451 Grab.Area.X = attributes.x;
3452 Grab.Area.Y = attributes.y;
3453 Grab.Area.Width = attributes.width;
3454 Grab.Area.Height = attributes.height;
3455 Grab.Confined = true;
3456 confine_to_window = hwnd.client_window;
3461 hwnd = Hwnd.ObjectFromHandle (handle);
3464 XGrabPointer (DisplayHandle, hwnd.client_window, false,
3465 EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
3466 EventMask.ButtonReleaseMask | EventMask.PointerMotionMask,
3467 GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, 0, 0);
3471 internal override void UngrabWindow (IntPtr hwnd)
3474 XUngrabPointer (DisplayHandle, 0);
3475 XFlush (DisplayHandle);
3477 Grab.Hwnd = IntPtr.Zero;
3478 Grab.Confined = false;
3481 internal override void HandleException (Exception e)
3483 StackTrace st = new StackTrace (e, true);
3484 Console.WriteLine ("Exception '{0}'", e.Message + st.ToString ());
3485 Console.WriteLine ("{0}{1}", e.Message, st.ToString ());
3488 internal override void Invalidate (IntPtr handle, Rectangle rc, bool clear)
3493 hwnd = Hwnd.ObjectFromHandle (handle);
3496 xevent = new XEvent ();
3497 xevent.type = XEventName.Expose;
3498 xevent.ExposeEvent.display = DisplayHandle;
3499 xevent.ExposeEvent.window = hwnd.client_window;
3502 xevent.ExposeEvent.x = hwnd.X;
3503 xevent.ExposeEvent.y = hwnd.Y;
3504 xevent.ExposeEvent.width = hwnd.Width;
3505 xevent.ExposeEvent.height = hwnd.Height;
3507 xevent.ExposeEvent.x = rc.X;
3508 xevent.ExposeEvent.y = rc.Y;
3509 xevent.ExposeEvent.width = rc.Width;
3510 xevent.ExposeEvent.height = rc.Height;
3516 internal override bool IsEnabled (IntPtr handle)
3518 return Hwnd.ObjectFromHandle (handle).Enabled;
3521 internal override bool IsVisible (IntPtr handle)
3523 return Hwnd.ObjectFromHandle (handle).visible;
3526 internal override void KillTimer (Timer timer)
3529 TimerList.Remove (timer);
3533 internal override void MenuToScreen (IntPtr handle, ref int x, ref int y)
3540 hwnd = Hwnd.ObjectFromHandle (handle);
3543 XTranslateCoordinates (DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
3550 internal override void OverrideCursor (IntPtr cursor)
3552 OverrideCursorHandle = cursor;
3555 internal override PaintEventArgs PaintEventStart (IntPtr handle, bool client)
3557 PaintEventArgs paint_event;
3560 hwnd = Hwnd.ObjectFromHandle (handle);
3562 if (Caret.Visible == 1) {
3563 Caret.Paused = true;
3568 // handle backing store
3569 IntPtr gdk_window = gdk_window_lookup (hwnd.client_window);
3570 IntPtr gdk_pixmap = NewPixmap (gdk_window, hwnd.ClientRect.Width, hwnd.ClientRect.Height);
3572 backing_store [gdk_window] = gdk_pixmap;
3574 hwnd.client_dc = Graphics.FromHwnd (gdk_x11_drawable_get_xid (gdk_pixmap));
3575 hwnd.client_dc.SetClip (hwnd.invalid);
3576 paint_event = new PaintEventArgs (hwnd.client_dc, hwnd.invalid);
3577 hwnd.expose_pending = false;
3581 hwnd.client_dc = Graphics.FromHwnd (hwnd.whole_window);
3582 paint_event = new PaintEventArgs (hwnd.client_dc, new Rectangle (0, 0, hwnd.width, hwnd.height));
3583 hwnd.nc_expose_pending = false;
3589 internal override void PaintEventEnd (IntPtr handle, bool client)
3593 hwnd = Hwnd.ObjectFromHandle (handle);
3595 hwnd.client_dc.Flush ();
3598 // clients are already drawn to a backing store pixmap
3599 IntPtr gdk_window = gdk_window_lookup (hwnd.client_window);
3600 IntPtr gdk_pixmap = (IntPtr)backing_store [gdk_window];
3602 BlitOffscreenPixmap (gdk_pixmap, gdk_window, hwnd.Invalid);
3604 g_object_unref (gdk_pixmap);
3605 backing_store.Remove (gdk_pixmap);
3607 hwnd.ClearInvalidArea ();
3610 hwnd.client_dc.Dispose ();
3611 hwnd.client_dc = null;
3613 if (Caret.Visible == 1) {
3615 Caret.Paused = false;
3619 internal override bool PeekMessage (ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
3623 // FIXME - imlement filtering
3625 if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
3626 throw new NotImplementedException ("PeekMessage PM_NOREMOVE is not implemented yet"); // FIXME - Implement PM_NOREMOVE flag
3630 if (MessageQueue.Count > 0) {
3633 // Only call UpdateMessageQueue if real events are pending
3634 // otherwise we go to sleep on the socket
3635 if (XPending (DisplayHandle) != 0) {
3636 UpdateMessageQueue ();
3641 CheckTimers (DateTime.Now);
3646 return GetMessage (ref msg, hWnd, wFilterMin, wFilterMax);
3649 // FIXME - I think this should just enqueue directly
3650 internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam)
3652 XEvent xevent = new XEvent ();
3653 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
3655 xevent.type = XEventName.ClientMessage;
3656 xevent.ClientMessageEvent.display = DisplayHandle;
3659 xevent.ClientMessageEvent.window = hwnd.whole_window;
3661 xevent.ClientMessageEvent.window = IntPtr.Zero;
3664 xevent.ClientMessageEvent.message_type = (IntPtr) PostAtom;
3665 xevent.ClientMessageEvent.format = 32;
3666 xevent.ClientMessageEvent.ptr1 = handle;
3667 xevent.ClientMessageEvent.ptr2 = (IntPtr) message;
3668 xevent.ClientMessageEvent.ptr3 = wparam;
3669 xevent.ClientMessageEvent.ptr4 = lparam;
3671 MessageQueue.Enqueue (xevent);
3676 internal override void PostQuitMessage (int exitCode)
3678 XFlush (DisplayHandle);
3679 PostQuitState = true;
3681 // Remove our display handle from S.D
3682 Graphics.FromHdcInternal (IntPtr.Zero);
3685 internal override void ScreenToClient (IntPtr handle, ref int x, ref int y)
3692 hwnd = Hwnd.ObjectFromHandle (handle);
3695 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.client_window, x, y, out dest_x_return, out dest_y_return, out child);
3702 internal override void ScreenToMenu (IntPtr handle, ref int x, ref int y)
3709 hwnd = Hwnd.ObjectFromHandle (handle);
3712 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.whole_window, x, y, out dest_x_return, out dest_y_return, out child);
3719 internal override void ScrollWindow (IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children)
3723 XGCValues gc_values;
3725 hwnd = Hwnd.ObjectFromHandle (handle);
3727 if (hwnd.invalid != Rectangle.Empty) {
3728 // BIG FAT WARNING. This only works with how we use this function right now
3729 // where we basically still scroll the whole window, but work around areas
3730 // that are covered by our children
3732 hwnd.invalid.X += XAmount;
3733 hwnd.invalid.Y += YAmount;
3735 if (hwnd.invalid.X < 0) {
3736 hwnd.invalid.Width += hwnd.invalid.X;
3740 if (hwnd.invalid.Y < 0) {
3741 hwnd.invalid.Height += hwnd.invalid.Y;
3746 gc_values = new XGCValues ();
3748 if (with_children) {
3749 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
3752 gc = XCreateGC (DisplayHandle, hwnd.client_window, 0, ref gc_values);
3754 XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, area.X - XAmount, area.Y - YAmount, area.Width, area.Height, area.X, area.Y);
3756 // Generate an expose for the area exposed by the horizontal scroll
3758 hwnd.AddInvalidArea (area.X, area.Y, XAmount, area.Height);
3759 } else if (XAmount < 0) {
3760 hwnd.AddInvalidArea (XAmount + area.X + area.Width, area.Y, -XAmount, area.Height);
3763 // Generate an expose for the area exposed by the vertical scroll
3765 hwnd.AddInvalidArea (area.X, area.Y, area.Width, YAmount);
3766 } else if (YAmount < 0) {
3767 hwnd.AddInvalidArea (area.X, YAmount + area.Y + area.Height, area.Width, -YAmount);
3769 XFreeGC (DisplayHandle, gc);
3771 UpdateWindow (handle);
3774 internal override void ScrollWindow (IntPtr handle, int XAmount, int YAmount, bool with_children)
3778 hwnd = Hwnd.GetObjectFromWindow (handle);
3780 ScrollWindow (handle, hwnd.ClientRect, XAmount, YAmount, with_children);
3783 internal override void SendAsyncMethod (AsyncMethodData method)
3785 XEvent xevent = new XEvent ();
3787 xevent.type = XEventName.ClientMessage;
3788 xevent.ClientMessageEvent.display = DisplayHandle;
3789 xevent.ClientMessageEvent.window = FosterParent;
3790 xevent.ClientMessageEvent.message_type = (IntPtr)AsyncAtom;
3791 xevent.ClientMessageEvent.format = 32;
3792 xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
3794 MessageQueue.EnqueueLocked (xevent);
3799 internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam)
3801 return NativeWindow.WndProc (hwnd, message, wParam, lParam);
3804 internal override void SetAllowDrop (IntPtr handle, bool value)
3806 // We allow drop on all windows
3809 internal override DragDropEffects StartDrag (IntPtr handle, object data,
3810 DragDropEffects allowed_effects)
3812 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
3815 throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");
3817 return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
3820 internal override void SetBorderStyle (IntPtr handle, FormBorderStyle border_style)
3824 hwnd = Hwnd.ObjectFromHandle (handle);
3826 hwnd.border_style = border_style;
3828 XMoveResizeWindow (DisplayHandle, hwnd.client_window, hwnd.ClientRect.X, hwnd.ClientRect.Y, hwnd.ClientRect.Width, hwnd.ClientRect.Height);
3830 InvalidateWholeWindow (handle);
3833 internal override void SetCaretPos (IntPtr handle, int x, int y)
3835 if (Caret.Hwnd == handle) {
3836 Caret.Timer.Stop ();
3842 if (Caret.Visible == 1) {
3844 Caret.Timer.Start ();
3849 internal override void SetCursor (IntPtr handle, IntPtr cursor)
3853 if (OverrideCursorHandle == IntPtr.Zero) {
3854 if ((LastCursorWindow == handle) && (LastCursorHandle == cursor)) {
3858 LastCursorHandle = cursor;
3859 LastCursorWindow = handle;
3861 hwnd = Hwnd.ObjectFromHandle (handle);
3863 if (cursor != IntPtr.Zero) {
3864 XDefineCursor (DisplayHandle, hwnd.whole_window, cursor);
3866 XUndefineCursor (DisplayHandle, hwnd.whole_window);
3872 hwnd = Hwnd.ObjectFromHandle (handle);
3874 XDefineCursor (DisplayHandle, hwnd.whole_window, OverrideCursorHandle);
3878 internal override void SetCursorPos (IntPtr handle, int x, int y)
3880 if (handle == IntPtr.Zero) {
3882 XWarpPointer (DisplayHandle, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x, y);
3888 hwnd = Hwnd.ObjectFromHandle (handle);
3890 XWarpPointer (DisplayHandle, IntPtr.Zero, hwnd.client_window, 0, 0, 0, 0, x, y);
3896 internal override void SetFocus (IntPtr handle)
3900 hwnd = Hwnd.ObjectFromHandle (handle);
3902 if (FocusWindow != IntPtr.Zero) {
3903 PostMessage (FocusWindow, Msg.WM_KILLFOCUS, hwnd.client_window, IntPtr.Zero);
3905 PostMessage (hwnd.client_window, Msg.WM_SETFOCUS, FocusWindow, IntPtr.Zero);
3906 FocusWindow = hwnd.client_window;
3908 //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
3911 internal override void SetIcon (IntPtr handle, Icon icon)
3915 hwnd = Hwnd.ObjectFromHandle (handle);
3917 SetIcon (hwnd, icon);
3921 internal override void SetMenu (IntPtr handle, Menu menu)
3925 hwnd = Hwnd.ObjectFromHandle (handle);
3928 // FIXME - do we need to trigger some resize?
3931 internal override void SetModal (IntPtr handle, bool Modal)
3934 ModalWindows.Push (handle);
3936 if (ModalWindows.Contains (handle)) {
3937 ModalWindows.Pop ();
3939 if (ModalWindows.Count > 0) {
3940 Activate ((IntPtr)ModalWindows.Peek ());
3945 internal override IntPtr SetParent (IntPtr handle, IntPtr parent)
3949 hwnd = Hwnd.ObjectFromHandle (handle);
3950 hwnd.parent = Hwnd.ObjectFromHandle (parent);
3954 Console.WriteLine("Parent for window {0:X} / {1:X} = {2:X} (Handle:{3:X})", hwnd.ClientWindow.ToInt32(), hwnd.WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0, parent.ToInt32());
3956 XReparentWindow (DisplayHandle, hwnd.whole_window, hwnd.parent.client_window, hwnd.x, hwnd.y);
3962 internal override void SetTimer (Timer timer)
3965 TimerList.Add (timer);
3970 internal override bool SetTopmost (IntPtr handle, IntPtr handle_owner, bool enabled)
3975 hwnd = Hwnd.ObjectFromHandle (handle);
3977 if (handle_owner != IntPtr.Zero) {
3978 hwnd_owner = Hwnd.ObjectFromHandle (handle_owner);
3985 if (hwnd_owner != null) {
3986 XSetTransientForHint (DisplayHandle, hwnd.whole_window, hwnd_owner.whole_window);
3988 XSetTransientForHint (DisplayHandle, hwnd.whole_window, FosterParent);
3993 XDeleteProperty (DisplayHandle, hwnd.whole_window, (int)Atom.XA_WM_TRANSIENT_FOR);
3999 internal override bool SetVisible (IntPtr handle, bool visible)
4003 hwnd = Hwnd.ObjectFromHandle (handle);
4004 hwnd.visible = visible;
4008 if (Control.FromHandle (handle) is Form) {
4011 s = ((Form)Control.FromHandle (handle)).WindowState;
4013 XMapWindow (DisplayHandle, hwnd.whole_window);
4014 XMapWindow (DisplayHandle, hwnd.client_window);
4017 case FormWindowState.Minimized: SetWindowState (handle, FormWindowState.Minimized); break;
4018 case FormWindowState.Maximized: SetWindowState (handle, FormWindowState.Maximized); break;
4021 XMapWindow (DisplayHandle, hwnd.whole_window);
4022 XMapWindow (DisplayHandle, hwnd.client_window);
4025 XUnmapWindow (DisplayHandle, hwnd.whole_window);
4031 internal override void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max)
4036 hwnd = Hwnd.ObjectFromHandle (handle);
4041 hints = new XSizeHints ();
4043 if (min != Size.Empty) {
4044 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
4045 hints.min_width = min.Width;
4046 hints.min_height = min.Height;
4049 if (max != Size.Empty) {
4050 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
4051 hints.max_width = max.Width;
4052 hints.max_height = max.Height;
4055 XSetWMNormalHints (DisplayHandle, hwnd.whole_window, ref hints);
4057 if (maximized != Rectangle.Empty) {
4058 hints.flags = (IntPtr)XSizeHintsFlags.PPosition;
4059 hints.x = maximized.X;
4060 hints.y = maximized.Y;
4061 hints.width = maximized.Width;
4062 hints.height = maximized.Height;
4064 // Metacity does not seem to follow this constraint for maximized (zoomed) windows
4065 XSetZoomHints (DisplayHandle, hwnd.whole_window, ref hints);
4070 internal override void SetWindowPos (IntPtr handle, int x, int y, int width, int height)
4073 Rectangle client_rect;
4075 hwnd = Hwnd.ObjectFromHandle (handle);
4077 // X requires a sanity check for width & height; otherwise it dies
4078 if (hwnd.zero_sized && width > 0 && height > 0) {
4080 XMapWindow (DisplayHandle, hwnd.whole_window);
4082 hwnd.zero_sized = false;
4086 hwnd.zero_sized = true;
4087 XUnmapWindow (DisplayHandle, hwnd.whole_window);
4091 hwnd.zero_sized = true;
4092 XUnmapWindow (DisplayHandle, hwnd.whole_window);
4095 client_rect = Hwnd.GetClientRectangle (hwnd.border_style, hwnd.menu, hwnd.title_style, hwnd.caption_height, hwnd.tool_caption_height, width, height);
4097 // Save a server roundtrip (and prevent a feedback loop)
4098 if ((hwnd.x == x) && (hwnd.y == y) &&
4099 (hwnd.width == width) && (hwnd.height == height) &&
4100 (hwnd.ClientRect == client_rect)) {
4104 if (!hwnd.zero_sized) {
4106 XMoveResizeWindow (DisplayHandle, hwnd.whole_window, x, y, width, height);
4107 XMoveResizeWindow (DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
4111 // Prevent an old queued ConfigureNotify from setting our width with outdated data, set it now
4113 hwnd.height = height;
4116 internal override void SetWindowState (IntPtr handle, FormWindowState state)
4118 FormWindowState current_state;
4121 hwnd = Hwnd.ObjectFromHandle (handle);
4123 current_state = GetWindowState (handle);
4125 if (current_state == state) {
4130 case FormWindowState.Normal: {
4132 if (current_state == FormWindowState.Minimized) {
4133 XMapWindow (DisplayHandle, hwnd.whole_window);
4134 XMapWindow (DisplayHandle, hwnd.client_window);
4135 } else if (current_state == FormWindowState.Maximized) {
4136 SendNetWMMessage (hwnd.whole_window, (IntPtr)(uint)NetAtoms [(int)NA._NET_WM_STATE], (IntPtr)2 /* toggle */, (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
4143 case FormWindowState.Minimized: {
4145 if (current_state == FormWindowState.Maximized) {
4146 SendNetWMMessage (hwnd.whole_window, (IntPtr)NetAtoms [(int)NA._NET_WM_STATE], (IntPtr)2 /* toggle */, (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
4148 XIconifyWindow (DisplayHandle, hwnd.whole_window, ScreenNo);
4153 case FormWindowState.Maximized: {
4155 if (current_state == FormWindowState.Minimized) {
4156 XMapWindow (DisplayHandle, hwnd.whole_window);
4157 XMapWindow (DisplayHandle, hwnd.client_window);
4160 SendNetWMMessage (hwnd.whole_window, (IntPtr)NetAtoms [(int)NA._NET_WM_STATE], (IntPtr)1 /* Add */, (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms [(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
4168 internal override void SetWindowStyle (IntPtr handle, CreateParams cp)
4172 hwnd = Hwnd.ObjectFromHandle (handle);
4173 SetHwndStyles (hwnd, cp);
4174 SetWMStyles (hwnd, cp);
4177 internal override void SetWindowTransparency (IntPtr handle, double transparency, Color key)
4182 hwnd = Hwnd.ObjectFromHandle (handle);
4188 hwnd.opacity = (uint)(0xffffffff * transparency);
4189 opacity = hwnd.opacity;
4191 if (hwnd.reparented) {
4192 XChangeProperty (DisplayHandle, XGetParent (hwnd.whole_window), NetAtoms [(int)NA._NET_WM_WINDOW_OPACITY], Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
4196 internal override bool SetZOrder (IntPtr handle, IntPtr after_handle, bool top, bool bottom)
4198 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
4202 XRaiseWindow (DisplayHandle, hwnd.whole_window);
4205 } else if (!bottom) {
4206 Hwnd after_hwnd = null;
4208 if (after_handle != IntPtr.Zero) {
4209 after_hwnd = Hwnd.ObjectFromHandle (after_handle);
4212 XWindowChanges values = new XWindowChanges ();
4214 if (after_hwnd == null) {
4215 throw new ArgumentNullException ("after_handle", "Need sibling to adjust z-order");
4217 values.sibling = after_hwnd.whole_window;
4218 values.stack_mode = StackMode.Below;
4221 XConfigureWindow (DisplayHandle, hwnd.whole_window, ChangeWindowFlags.CWStackMode | ChangeWindowFlags.CWSibling, ref values);
4226 XLowerWindow (DisplayHandle, hwnd.whole_window);
4233 internal override void ShowCursor (bool show)
4235 ; // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
4238 internal override void StartLoop (Thread thread)
4240 // Future place for prepping a new queue for this specific thread
4243 internal override bool SupportsTransparency ()
4245 // We need to check if the x compositing manager is running
4249 internal override bool SystrayAdd (IntPtr handle, string tip, Icon icon, out ToolTip tt)
4251 GetSystrayManagerWindow ();
4253 if (SystrayMgrWindow != IntPtr.Zero) {
4255 XSizeHints size_hints;
4258 hwnd = Hwnd.ObjectFromHandle (handle);
4260 Console.WriteLine("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
4263 XUnmapWindow (DisplayHandle, hwnd.whole_window);
4264 XUnmapWindow (DisplayHandle, hwnd.client_window);
4267 gdk_window_destroy (gdk_window_lookup (hwnd.client_window));
4268 hwnd.client_window = hwnd.whole_window;
4270 size_hints = new XSizeHints ();
4272 size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
4273 size_hints.min_width = icon.Width;
4274 size_hints.min_height = icon.Height;
4276 size_hints.max_width = icon.Width;
4277 size_hints.max_height = icon.Height;
4279 size_hints.base_width = icon.Width;
4280 size_hints.base_height = icon.Height;
4281 XSetWMNormalHints (DisplayHandle, hwnd.whole_window, ref size_hints);
4283 atoms = new uint [2];
4284 atoms [0] = 1; // Version 1
4285 atoms [1] = 0; // We're not mapped
4287 // This line cost me 3 days...
4288 XChangeProperty (DisplayHandle, hwnd.whole_window, NetAtoms [(int)NA._XEMBED_INFO], NetAtoms [(int)NA._XEMBED_INFO], 32, PropertyMode.Replace, atoms, 2);
4290 // Need to pick some reasonable defaults
4291 tt = new ToolTip ();
4292 tt.AutomaticDelay = 100;
4293 tt.InitialDelay = 250;
4294 tt.ReshowDelay = 250;
4295 tt.ShowAlways = true;
4297 if ((tip != null) && (tip != string.Empty)) {
4298 tt.SetToolTip (Control.FromHandle (handle), tip);
4304 // Make sure the window exists
4305 XSync (DisplayHandle, hwnd.whole_window);
4307 SendNetClientMessage (SystrayMgrWindow, (IntPtr)NetAtoms [(int)NA._NET_SYSTEM_TRAY_OPCODE], IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
4315 internal override bool SystrayChange (IntPtr handle, string tip, Icon icon, ref ToolTip tt)
4319 control = Control.FromHandle (handle);
4320 if (control != null && tt != null) {
4321 tt.SetToolTip (control, tip);
4329 internal override void SystrayRemove (IntPtr handle, ref ToolTip tt)
4333 hwnd = Hwnd.ObjectFromHandle (handle);
4335 XUnmapWindow (DisplayHandle, hwnd.whole_window);
4336 SetParent (hwnd.whole_window, FosterParent);
4338 // The caller can now re-dock it later...
4345 internal override bool Text (IntPtr handle, string text)
4348 gdk_window_set_title (gdk_window_lookup (Hwnd.ObjectFromHandle (handle).whole_window), text);
4353 internal override bool TranslateMessage (ref MSG msg)
4355 return Keyboard.TranslateMessage (ref msg);
4358 internal override void UpdateWindow (IntPtr handle)
4363 hwnd = Hwnd.ObjectFromHandle (handle);
4365 if (!hwnd.visible || hwnd.expose_pending) {
4370 SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
4372 xevent = new XEvent ();
4373 xevent.type = XEventName.Expose;
4374 xevent.ExposeEvent.display = DisplayHandle;
4375 xevent.ExposeEvent.window = hwnd.client_window;
4377 MessageQueue.Enqueue (xevent);
4378 hwnd.expose_pending = true;
4382 internal static IntPtr NewPixmap (IntPtr gdk_window, int width, int height)
4384 return gdk_pixmap_new (gdk_window, width, height, 24); // FIXME: instead of 24, get the correct display depth
4387 internal static void BlitOffscreenPixmap (IntPtr gdk_pixmap, IntPtr dest_drawable, Rectangle area)
4389 IntPtr gdk_gc = gdk_gc_new (gdk_pixmap);
4391 gdk_draw_drawable (dest_drawable, gdk_gc, gdk_pixmap, area.X, area.Y, area.X, area.Y, area.Width, area.Height);
4393 g_object_unref (gdk_gc);
4395 #endregion // Public Static Methods
4398 internal override event EventHandler Idle;
4399 #endregion // Events
4402 [DllImport ("libX11", EntryPoint="XSynchronize")]
4403 internal extern static IntPtr XSynchronize (IntPtr display, bool onoff);
4405 [DllImport ("libX11", EntryPoint="XCreateWindow")]
4406 internal extern static IntPtr XCreateWindow (IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, SetWindowValuemask valuemask, ref XSetWindowAttributes attributes);
4407 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
4408 internal extern static IntPtr XCreateSimpleWindow (IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int border, int background);
4409 [DllImport ("libX11", EntryPoint="XMapWindow")]
4410 internal extern static int XMapWindow (IntPtr display, IntPtr window);
4411 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
4412 internal extern static int XUnmapWindow (IntPtr display, IntPtr window);
4413 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
4414 internal extern static int XMapSubindows (IntPtr display, IntPtr window);
4415 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
4416 internal extern static int XUnmapSubwindows (IntPtr display, IntPtr window);
4417 [DllImport ("libX11", EntryPoint="XRootWindow")]
4418 internal extern static IntPtr XRootWindow (IntPtr display, int screen_number);
4419 [DllImport ("libX11", EntryPoint="XNextEvent")]
4420 internal extern static IntPtr XNextEvent (IntPtr display, ref XEvent xevent);
4421 [DllImport ("libX11")]
4422 internal extern static int XConnectionNumber (IntPtr diplay);
4423 [DllImport ("libX11")]
4424 internal extern static int XPending (IntPtr diplay);
4425 [DllImport ("libX11")]
4426 internal extern static bool XCheckWindowEvent (IntPtr display, IntPtr window, EventMask mask, ref XEvent xevent);
4427 [DllImport ("libX11")]
4428 internal extern static bool XCheckMaskEvent (IntPtr display, EventMask mask, ref XEvent xevent);
4429 [DllImport ("libX11", EntryPoint="XSelectInput")]
4430 internal extern static IntPtr XSelectInput (IntPtr display, IntPtr window, EventMask mask);
4432 [DllImport ("libX11", EntryPoint="XReparentWindow")]
4433 internal extern static int XReparentWindow (IntPtr display, IntPtr window, IntPtr parent, int x, int y);
4434 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
4435 internal extern static int XMoveResizeWindow (IntPtr display, IntPtr window, int x, int y, int width, int height);
4437 [DllImport ("libX11", EntryPoint="XResizeWindow")]
4438 internal extern static int XResizeWindow (IntPtr display, IntPtr window, int width, int height);
4440 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
4441 internal extern static int XGetWindowAttributes (IntPtr display, IntPtr window, ref XWindowAttributes attributes);
4443 [DllImport ("libX11", EntryPoint="XFlush")]
4444 internal extern static int XFlush (IntPtr display);
4446 [DllImport ("libX11", EntryPoint="XSetWMName")]
4447 internal extern static int XSetWMName (IntPtr display, IntPtr window, ref XTextProperty text_prop);
4449 [DllImport ("libX11", EntryPoint="XStoreName")]
4450 internal extern static int XStoreName (IntPtr display, IntPtr window, string window_name);
4452 [DllImport ("libX11", EntryPoint="XFetchName")]
4453 internal extern static int XFetchName (IntPtr display, IntPtr window, ref IntPtr window_name);
4455 [DllImport ("libX11", EntryPoint="XSendEvent")]
4456 internal extern static int XSendEvent (IntPtr display, IntPtr window, bool propagate, EventMask event_mask, ref XEvent send_event);
4458 [DllImport ("libX11", EntryPoint="XQueryTree")]
4459 internal extern static int XQueryTree (IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return);
4461 [DllImport ("libX11", EntryPoint="XFree")]
4462 internal extern static int XFree (IntPtr data);
4464 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
4465 internal extern static int XRaiseWindow (IntPtr display, IntPtr window);
4467 [DllImport ("libX11", EntryPoint="XLowerWindow")]
4468 internal extern static uint XLowerWindow (IntPtr display, IntPtr window);
4470 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
4471 internal extern static uint XConfigureWindow (IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
4473 [DllImport ("libX11", EntryPoint="XInternAtom")]
4474 internal extern static int XInternAtom (IntPtr display, string atom_name, bool only_if_exists);
4476 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
4477 internal extern static int XSetWMProtocols (IntPtr display, IntPtr window, uint[] protocols, int count);
4479 [DllImport ("libX11", EntryPoint="XGrabPointer")]
4480 internal extern static int XGrabPointer (IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, uint cursor, uint timestamp);
4482 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
4483 internal extern static int XUngrabPointer (IntPtr display, uint timestamp);
4485 [DllImport ("libX11", EntryPoint="XQueryPointer")]
4486 internal extern static bool XQueryPointer (IntPtr display, IntPtr window, out IntPtr root, out IntPtr child, out int root_x, out int root_y, out int win_x, out int win_y, out int keys_buttons);
4488 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
4489 internal extern static bool XTranslateCoordinates (IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, out int intdest_x_return, out int dest_y_return, out IntPtr child_return);
4491 [DllImport ("libX11", EntryPoint="XWarpPointer")]
4492 internal extern static uint XWarpPointer (IntPtr display, IntPtr src_w, IntPtr dest_w, int src_x, int src_y, uint src_width, uint src_height, int dest_x, int dest_y);
4494 [DllImport ("libX11", EntryPoint="XClearWindow")]
4495 internal extern static int XClearWindow (IntPtr display, IntPtr window);
4497 [DllImport ("libX11", EntryPoint="XClearArea")]
4498 internal extern static int XClearArea (IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
4501 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
4502 internal extern static IntPtr XDefaultScreenOfDisplay (IntPtr display);
4504 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
4505 internal extern static int XScreenNumberOfScreen (IntPtr display, IntPtr Screen);
4507 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
4508 internal extern static IntPtr XDefaultVisual (IntPtr display, int screen_number);
4510 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
4511 internal extern static uint XDefaultDepth (IntPtr display, int screen_number);
4513 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
4514 internal extern static IntPtr XDefaultColormap (IntPtr display, int screen_number);
4516 [DllImport ("libX11", EntryPoint="XLookupColor")]
4517 internal extern static int XLookupColor (IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
4519 [DllImport ("libX11", EntryPoint="XAllocColor")]
4520 internal extern static int XAllocColor (IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
4522 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
4523 internal extern static int XSetTransientForHint (IntPtr display, IntPtr window, IntPtr prop_window);
4525 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4526 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
4528 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4529 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode mode, uint[] atoms, int nelements);
4531 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4532 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode mode, ref uint value, int nelements);
4534 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4535 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int format, int type, PropertyMode mode, uint[] atoms, int nelements);
4537 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4538 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int format, int type, PropertyMode mode, IntPtr atoms, int nelements);
4540 [DllImport ("libX11", EntryPoint="XChangeProperty")]
4541 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode mode, IntPtr atoms, int nelements);
4543 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
4544 internal extern static int XChangeProperty (IntPtr display, IntPtr window, int property, int type, int format, PropertyMode mode, string text, int text_length);
4546 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
4547 internal extern static int XDeleteProperty (IntPtr display, IntPtr window, int property);
4549 [DllImport ("gdiplus", EntryPoint="GetFontMetrics")]
4550 internal extern static bool GetFontMetrics (IntPtr graphicsObject, IntPtr nativeObject, out int ascent, out int descent);
4553 [DllImport ("libX11", EntryPoint="XCreateGC")]
4554 internal extern static IntPtr XCreateGC (IntPtr display, IntPtr window, GCFunction valuemask, ref XGCValues values);
4556 [DllImport ("libX11", EntryPoint="XFreeGC")]
4557 internal extern static int XFreeGC (IntPtr display, IntPtr gc);
4559 [DllImport ("libX11", EntryPoint="XSetFunction")]
4560 internal extern static int XSetFunction (IntPtr display, IntPtr gc, GXFunction function);
4562 [DllImport ("libX11", EntryPoint="XDrawLine")]
4563 internal extern static int XDrawLine (IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
4565 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
4566 internal extern static int XDrawRectangle (IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
4568 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
4569 internal extern static int XSetWindowBackground (IntPtr display, IntPtr window, IntPtr background);
4571 [DllImport ("libX11", EntryPoint="XCopyArea")]
4572 internal extern static int XCopyArea (IntPtr display, IntPtr src, IntPtr dest, IntPtr gc, int src_x, int src_y, int width, int height, int dest_x, int dest_y);
4574 [DllImport ("libX11", EntryPoint="XGetAtomName")]
4575 internal extern static string XGetAtomName (IntPtr display, int atom);
4577 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
4578 internal extern static int XGetWindowProperty (IntPtr display, IntPtr window, int atom, int long_offset, int long_length, bool delete, Atom req_type, out Atom actual_type, out int actual_format, out int nitems, out int bytes_after, ref IntPtr prop);
4580 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
4581 internal extern static int XSetInputFocus (IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
4583 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
4584 internal extern static int XIconifyWindow (IntPtr display, IntPtr window, int screen_number);
4586 [DllImport ("libX11", EntryPoint="XDefineCursor")]
4587 internal extern static int XDefineCursor (IntPtr display, IntPtr window, IntPtr cursor);
4589 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
4590 internal extern static int XUndefineCursor (IntPtr display, IntPtr window);
4592 [DllImport ("libX11", EntryPoint="XFreeCursor")]
4593 internal extern static int XFreeCursor (IntPtr display, IntPtr cursor);
4595 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
4596 internal extern static IntPtr XCreateFontCursor (IntPtr display, CursorFontShape shape);
4598 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
4599 internal extern static IntPtr XCreatePixmapCursor (IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot);
4601 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
4602 internal extern static IntPtr XCreatePixmapFromBitmapData (IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
4604 [DllImport ("libX11", EntryPoint="XFreePixmap")]
4605 internal extern static IntPtr XFreePixmap (IntPtr display, IntPtr pixmap);
4607 [DllImport ("libX11", EntryPoint="XWhitePixel")]
4608 internal extern static IntPtr XWhitePixel (IntPtr display, int screen_no);
4610 [DllImport ("libX11", EntryPoint="XBlackPixel")]
4611 internal extern static IntPtr XBlackPixel (IntPtr display, int screen_no);
4613 [DllImport ("libX11", EntryPoint="XGrabServer")]
4614 internal extern static void XGrabServer (IntPtr display);
4616 [DllImport ("libX11", EntryPoint="XUngrabServer")]
4617 internal extern static void XUngrabServer (IntPtr display);
4619 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
4620 internal extern static void XSetWMNormalHints (IntPtr display, IntPtr window, ref XSizeHints hints);
4622 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
4623 internal extern static void XSetZoomHints (IntPtr display, IntPtr window, ref XSizeHints hints);
4625 [DllImport ("libX11", EntryPoint="XSetWMHints")]
4626 internal extern static void XSetWMHints (IntPtr display, IntPtr window, ref XWMHints wmhints);
4628 [DllImport ("libX11", EntryPoint="XSync")]
4629 internal extern static void XSync (IntPtr display, IntPtr window);
4631 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
4632 internal extern static int XGetIconSizes (IntPtr display, IntPtr window, out IntPtr size_list, out int count);
4634 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
4635 internal extern static IntPtr XSetErrorHandler (XErrorHandler error_handler);
4637 [DllImport ("libX11", EntryPoint="XGetErrorText")]
4638 internal extern static IntPtr XGetErrorText (IntPtr display, byte code, StringBuilder buffer, int length);
4640 [DllImport ("libX11", EntryPoint="XInitThreads")]
4641 internal extern static int XInitThreads ();
4643 [DllImport ("libX11", EntryPoint="XConvertSelection")]
4644 internal extern static int XConvertSelection (IntPtr display, int selection, int target, int property, IntPtr requestor, IntPtr time);
4646 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
4647 internal extern static IntPtr XGetSelectionOwner (IntPtr display, int selection);
4649 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
4650 internal extern static int XSetSelectionOwner (IntPtr display, int selection, IntPtr owner, IntPtr time);
4652 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
4653 internal extern static int XSetPlaneMask (IntPtr display, IntPtr gc, uint mask);
4655 [DllImport ("libX11", EntryPoint="XSetForeground")]
4656 internal extern static int XSetForeground (IntPtr display, IntPtr gc, uint foreground);
4658 [DllImport ("libX11", EntryPoint="XSetBackground")]
4659 internal extern static int XSetBackground (IntPtr display, IntPtr gc, uint background);
4664 [DllImport("libgdk-x11-2.0.so")]
4665 static extern bool gdk_init_check (out int argc, string argv);
4667 [DllImport("libgdk-x11-2.0.so")]
4668 internal static extern IntPtr gdk_x11_display_get_xdisplay (IntPtr display);
4670 [DllImport("libgdk-x11-2.0.so")]
4671 internal static extern IntPtr gdk_display_get_default ();
4673 [DllImport("libgdk-x11-2.0.so")]
4674 static extern IntPtr gdk_pixmap_new (IntPtr drawable, int width, int height, int depth);
4676 [DllImport("libgdk-x11-2.0.so")]
4677 static extern IntPtr gdk_x11_drawable_get_xid (IntPtr gdkdrawable);
4679 [DllImport("libgdk-x11-2.0.so")]
4680 static extern void gdk_draw_drawable (IntPtr drawable_dest, IntPtr gdk_gc, IntPtr drawable_src, int xsrc, int ysrc, int xdest, int ydest, int width, int height);
4682 [DllImport("libgdk-x11-2.0.so")]
4683 static extern IntPtr gdk_gc_new (IntPtr drawable);
4685 [DllImport("libgdk-x11-2.0.so")]
4686 static extern IntPtr gdk_window_foreign_new (IntPtr anid);
4688 [DllImport("libgdk-x11-2.0.so")]
4689 static extern IntPtr gdk_x11_lookup_xdisplay (IntPtr xdisplay);
4691 [DllImport("libgdk-x11-2.0.so")]
4692 static extern void gdk_display_close (IntPtr display);
4694 [DllImport("libgdk-x11-2.0.so")]
4695 static extern void gdk_display_beep (IntPtr display);
4697 [DllImport("libgdk-x11-2.0.so")]
4698 static extern void gdk_display_sync (IntPtr display);
4700 [DllImport("libgdk-x11-2.0.so")]
4701 static extern IntPtr gdk_get_default_root_window ();
4703 [DllImport("libgdk-x11-2.0.so")]
4704 static extern IntPtr gdk_colormap_get_system ();
4706 [DllImport("libgdk-x11-2.0.so")]
4707 static extern IntPtr gdk_x11_colormap_get_xcolormap (IntPtr gdk_colormap);
4709 [DllImport("libgdk-x11-2.0.so")]
4710 static extern void gdk_window_destroy (IntPtr gdk_window);
4712 [DllImport("libgdk-x11-2.0.so")]
4713 static extern void gdk_x11_grab_server ();
4715 [DllImport("libgdk-x11-2.0.so")]
4716 static extern void gdk_x11_ungrab_server ();
4718 [DllImport("libgdk-x11-2.0.so")]
4719 static extern void gdk_display_flush (IntPtr gdk_display);
4721 [DllImport("libgdk-x11-2.0.so")]
4722 static extern void gdk_window_iconify (IntPtr gdk_window);
4724 [DllImport("libgdk-x11-2.0.so")]
4725 static extern void gdk_window_deiconify (IntPtr gdk_window);
4727 [DllImport("libgdk-x11-2.0.so")]
4728 static extern void gdk_window_set_decorations (IntPtr gdk_window, int decorations);
4730 [DllImport("libgdk-x11-2.0.so")]
4731 static extern IntPtr gdk_screen_get_default ();
4733 [DllImport("libgdk-x11-2.0.so")]
4734 static extern int gdk_screen_get_number (IntPtr gdk_screen);
4736 [DllImport("libgdk-x11-2.0.so")]
4737 static extern IntPtr gdk_window_lookup (IntPtr anid);
4739 [DllImport("libgdk-x11-2.0.so")]
4740 static extern IntPtr gdk_window_new (IntPtr gdk_parent, ref GdkWindowAttr gdk_window_attributes, int attributes_mask);
4742 [DllImport("libgdk-x11-2.0.so")]
4743 static extern void gdk_window_set_events (IntPtr gdk_window, int event_mask);
4745 [DllImport("libgdk-x11-2.0.so")]
4746 static extern void gdk_window_show (IntPtr window);
4748 [DllImport("libgdk-x11-2.0.so")]
4749 static extern void gdk_window_set_title (IntPtr gdk_window, string title);
4751 [DllImport("libgdk-x11-2.0.so")]
4752 static extern int gdk_window_get_origin (IntPtr gdk_window, out int x, out int y);
4754 [DllImport("libgdk-x11-2.0.so")]
4755 static extern void gdk_window_get_geometry (IntPtr gdk_window, out int x, out int y, out int width, out int height, out int depth);
4757 [DllImport("libgdk-x11-2.0.so")]
4758 static extern void gdk_property_change (IntPtr gdk_window, /*GdkAtom*/IntPtr property, /*GdkAtom*/IntPtr type, int format, int gdk_prop_mode, /*const guchar **/ IntPtr data, int nelements);
4760 [DllImport("libgdk-x11-2.0.so")]
4761 static extern IntPtr gdk_window_get_parent (IntPtr gdk_window);
4763 [DllImport("libgdk-x11-2.0.so")]
4764 static extern void gdk_display_get_maximal_cursor_size (IntPtr gdk_display, out uint width, out uint height);
4766 [DllImport("libgdk-x11-2.0.so")]
4767 static extern int gdk_visual_get_best_depth ();
4770 #region gobject imports
4771 [DllImport("libglib-2.0.so")]
4772 static extern void g_free (IntPtr mem);
4774 [DllImport("libgobject-2.0.so")]
4775 static extern void g_object_unref (IntPtr nativeObject);