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
28 // This driver understands the following environment variables: (Set the var to enable feature)
30 // MONO_XEXCEPTIONS = throw an exception when a X11 error is encountered;
31 // by default a message is displayed but execution continues
33 // MONO_XSYNC = perform all X11 commands synchronous; this is slower but
34 // helps in debugging errors
39 // define to log Window handles and relationships to stdout
42 // Extra detailed debug
43 #undef DriverDebugExtra
44 #undef DriverDebugParent
45 #undef DriverDebugCreate
46 #undef DriverDebugDestroy
47 #undef DriverDebugThreads
48 #undef DriverDebugXEmbed
54 using System.ComponentModel;
55 using System.Collections;
56 using System.Diagnostics;
58 using System.Drawing.Drawing2D;
59 using System.Drawing.Imaging;
62 using System.Net.Sockets;
63 using System.Reflection;
64 using System.Runtime.InteropServices;
65 using System.Runtime.Serialization;
66 using System.Runtime.Serialization.Formatters.Binary;
68 using System.Threading;
70 // Only do the poll when building with mono for now
72 using Mono.Unix.Native;
76 namespace System.Windows.Forms {
77 internal class XplatUIX11 : XplatUIDriver {
78 #region Local Variables
80 static volatile XplatUIX11 Instance;
82 static object XlibLock; // Our locking object
83 static bool themes_enabled;
86 static IntPtr DisplayHandle; // X11 handle to display
87 static int ScreenNo; // Screen number used
88 static IntPtr DefaultColormap; // Colormap for screen
89 static IntPtr CustomVisual; // Visual for window creation
90 static IntPtr CustomColormap; // Colormap for window creation
91 static IntPtr RootWindow; // Handle of the root window for the screen/display
92 static IntPtr FosterParent; // Container to hold child windows until their parent exists
93 static XErrorHandler ErrorHandler; // Error handler delegate
94 static bool ErrorExceptions; // Throw exceptions on X errors
95 int render_major_opcode;
96 int render_first_event;
97 int render_first_error;
100 static IntPtr ClipMagic;
101 static ClipboardData Clipboard; // Our clipboard
104 static IntPtr PostAtom; // PostMessage atom
105 static IntPtr AsyncAtom; // Support for async messages
108 static Hashtable MessageQueues; // Holds our thread-specific XEventQueues
109 static ArrayList unattached_timer_list; // holds timers that are enabled but not attached to a window.
111 static Pollfd[] pollfds; // For watching the X11 socket
112 static bool wake_waiting;
113 static object wake_waiting_lock = new object ();
115 static X11Keyboard Keyboard; //
117 static Socket listen; //
118 static Socket wake; //
119 static Socket wake_receive; //
120 static byte[] network_buffer; //
121 static bool detectable_key_auto_repeat;
124 static IntPtr ActiveWindow; // Handle of the active window
125 static IntPtr FocusWindow; // Handle of the window with keyboard focus (if any)
128 static Stack ModalWindows; // Stack of our modal windows
131 static IntPtr SystrayMgrWindow; // Handle of the Systray Manager window
134 static IntPtr LastCursorWindow; // The last window we set the cursor on
135 static IntPtr LastCursorHandle; // The handle that was last set on LastCursorWindow
136 static IntPtr OverrideCursorHandle; // The cursor that is set to override any other cursors
139 static CaretStruct Caret; //
141 // Last window containing the pointer
142 static IntPtr LastPointerWindow; // The last window containing the pointer
145 static IntPtr WM_PROTOCOLS;
146 static IntPtr WM_DELETE_WINDOW;
147 static IntPtr WM_TAKE_FOCUS;
148 //static IntPtr _NET_SUPPORTED;
149 //static IntPtr _NET_CLIENT_LIST;
150 //static IntPtr _NET_NUMBER_OF_DESKTOPS;
151 static IntPtr _NET_DESKTOP_GEOMETRY;
152 //static IntPtr _NET_DESKTOP_VIEWPORT;
153 static IntPtr _NET_CURRENT_DESKTOP;
154 //static IntPtr _NET_DESKTOP_NAMES;
155 static IntPtr _NET_ACTIVE_WINDOW;
156 static IntPtr _NET_WORKAREA;
157 //static IntPtr _NET_SUPPORTING_WM_CHECK;
158 //static IntPtr _NET_VIRTUAL_ROOTS;
159 //static IntPtr _NET_DESKTOP_LAYOUT;
160 //static IntPtr _NET_SHOWING_DESKTOP;
161 //static IntPtr _NET_CLOSE_WINDOW;
162 //static IntPtr _NET_MOVERESIZE_WINDOW;
163 static IntPtr _NET_WM_MOVERESIZE;
164 //static IntPtr _NET_RESTACK_WINDOW;
165 //static IntPtr _NET_REQUEST_FRAME_EXTENTS;
166 static IntPtr _NET_WM_NAME;
167 //static IntPtr _NET_WM_VISIBLE_NAME;
168 //static IntPtr _NET_WM_ICON_NAME;
169 //static IntPtr _NET_WM_VISIBLE_ICON_NAME;
170 //static IntPtr _NET_WM_DESKTOP;
171 static IntPtr _NET_WM_WINDOW_TYPE;
172 static IntPtr _NET_WM_STATE;
173 //static IntPtr _NET_WM_ALLOWED_ACTIONS;
174 //static IntPtr _NET_WM_STRUT;
175 //static IntPtr _NET_WM_STRUT_PARTIAL;
176 //static IntPtr _NET_WM_ICON_GEOMETRY;
177 static IntPtr _NET_WM_ICON;
178 //static IntPtr _NET_WM_PID;
179 //static IntPtr _NET_WM_HANDLED_ICONS;
180 static IntPtr _NET_WM_USER_TIME;
181 static IntPtr _NET_FRAME_EXTENTS;
182 //static IntPtr _NET_WM_PING;
183 //static IntPtr _NET_WM_SYNC_REQUEST;
184 static IntPtr _NET_SYSTEM_TRAY_S;
185 //static IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
186 static IntPtr _NET_SYSTEM_TRAY_OPCODE;
187 static IntPtr _NET_WM_STATE_MAXIMIZED_HORZ;
188 static IntPtr _NET_WM_STATE_MAXIMIZED_VERT;
189 static IntPtr _XEMBED;
190 static IntPtr _XEMBED_INFO;
191 static IntPtr _MOTIF_WM_HINTS;
192 static IntPtr _NET_WM_STATE_SKIP_TASKBAR;
193 static IntPtr _NET_WM_STATE_ABOVE;
194 static IntPtr _NET_WM_STATE_MODAL;
195 static IntPtr _NET_WM_STATE_HIDDEN;
196 static IntPtr _NET_WM_CONTEXT_HELP;
197 static IntPtr _NET_WM_WINDOW_OPACITY;
198 //static IntPtr _NET_WM_WINDOW_TYPE_DESKTOP;
199 //static IntPtr _NET_WM_WINDOW_TYPE_DOCK;
200 //static IntPtr _NET_WM_WINDOW_TYPE_TOOLBAR;
201 //static IntPtr _NET_WM_WINDOW_TYPE_MENU;
202 static IntPtr _NET_WM_WINDOW_TYPE_UTILITY;
203 //static IntPtr _NET_WM_WINDOW_TYPE_SPLASH;
204 // static IntPtr _NET_WM_WINDOW_TYPE_DIALOG;
205 static IntPtr _NET_WM_WINDOW_TYPE_NORMAL;
206 static IntPtr CLIPBOARD;
207 static IntPtr PRIMARY;
209 static IntPtr OEMTEXT;
210 static IntPtr UTF8_STRING;
211 static IntPtr UTF16_STRING;
212 static IntPtr RICHTEXTFORMAT;
213 static IntPtr TARGETS;
215 // mouse hover message generation
216 static HoverStruct HoverState; //
218 // double click message generation
219 static ClickStruct ClickPending; //
221 // Support for mouse grab
222 static GrabStruct Grab; //
225 Point mouse_position; // Last position of mouse, in screen coords
226 internal static MouseButtons MouseState; // Last state of mouse buttons
227 internal static bool in_doevents;
229 static int DoubleClickInterval; // msec; max interval between clicks to count as double click
231 const EventMask SelectInputMask = (EventMask.ButtonPressMask |
232 EventMask.ButtonReleaseMask |
233 EventMask.KeyPressMask |
234 EventMask.KeyReleaseMask |
235 EventMask.EnterWindowMask |
236 EventMask.LeaveWindowMask |
237 EventMask.ExposureMask |
238 EventMask.FocusChangeMask |
239 EventMask.PointerMotionMask |
240 EventMask.PointerMotionHintMask |
241 EventMask.SubstructureNotifyMask);
243 static readonly object lockobj = new object ();
245 // messages WaitForHwndMwssage is waiting on
246 static Hashtable messageHold;
248 #endregion // Local Variables
252 // Handle singleton stuff first
256 // Now regular initialization
257 XlibLock = new object ();
258 X11Keyboard.XlibLock = XlibLock;
259 MessageQueues = Hashtable.Synchronized (new Hashtable(7));
260 unattached_timer_list = ArrayList.Synchronized (new ArrayList (3));
261 messageHold = Hashtable.Synchronized (new Hashtable(3));
262 Clipboard = new ClipboardData ();
265 ErrorExceptions = false;
267 // X11 Initialization
268 SetDisplay(XOpenDisplay(IntPtr.Zero));
269 X11DesktopColors.Initialize();
272 // Disable keyboard autorepeat
274 XkbSetDetectableAutoRepeat (DisplayHandle, true, IntPtr.Zero);
275 detectable_key_auto_repeat = true;
277 Console.Error.WriteLine ("Could not disable keyboard auto repeat, will attempt to disable manually.");
278 detectable_key_auto_repeat = false;
281 // Handle any upcoming errors; we re-set it here, X11DesktopColor stuff might have stolen it (gtk does)
282 ErrorHandler = new XErrorHandler(HandleError);
283 XSetErrorHandler(ErrorHandler);
287 // Remove our display handle from S.D
288 Graphics.FromHdcInternal (IntPtr.Zero);
291 #endregion // Constructors
293 #region Singleton Specific Code
294 public static XplatUIX11 GetInstance() {
296 if (Instance == null) {
297 Instance=new XplatUIX11();
304 public int Reference {
311 #region Internal Properties
312 internal static IntPtr Display {
314 return DisplayHandle;
318 XplatUIX11.GetInstance().SetDisplay(value);
322 internal static int Screen {
332 internal static IntPtr RootWindowHandle {
342 internal static IntPtr Visual {
348 CustomVisual = value;
352 internal static IntPtr ColorMap {
354 return CustomColormap;
358 CustomColormap = value;
363 internal static IntPtr DefaultColorMap {
365 return DefaultColormap;
371 #region XExceptionClass
372 internal class XException : ApplicationException {
376 XRequest RequestCode;
380 public XException(IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode) {
381 this.Display = Display;
382 this.ResourceID = ResourceID;
383 this.Serial = Serial;
384 this.RequestCode = RequestCode;
385 this.ErrorCode = ErrorCode;
386 this.MinorCode = MinorCode;
389 public override string Message {
391 return GetMessage(Display, ResourceID, Serial, ErrorCode, RequestCode, MinorCode);
395 public static string GetMessage(IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode) {
404 sb = new StringBuilder(160);
405 XGetErrorText(Display, ErrorCode, sb, sb.Capacity);
406 x_error_text = sb.ToString();
407 hwnd = Hwnd.ObjectFromHandle(ResourceID);
409 hwnd_text = hwnd.ToString();
410 c = Control.FromHandle(hwnd.Handle);
412 control_text = c.ToString();
414 control_text = String.Format("<handle {0:X} non-existant>", hwnd.Handle.ToInt32());
417 hwnd_text = "<null>";
418 control_text = "<null>";
422 error = String.Format("\n Error: {0}\n Request: {1:D} ({2})\n Resource ID: 0x{3:X}\n Serial: {4}\n Hwnd: {5}\n Control: {6}", x_error_text, RequestCode, MinorCode, ResourceID.ToInt32(), Serial, hwnd_text, control_text);
426 #endregion // XExceptionClass
428 #region Internal Methods
429 internal void SetDisplay(IntPtr display_handle)
431 if (display_handle != IntPtr.Zero) {
434 if ((DisplayHandle != IntPtr.Zero) && (FosterParent != IntPtr.Zero)) {
435 hwnd = Hwnd.ObjectFromHandle(FosterParent);
436 XDestroyWindow(DisplayHandle, FosterParent);
440 if (DisplayHandle != IntPtr.Zero) {
441 XCloseDisplay(DisplayHandle);
444 DisplayHandle=display_handle;
446 // We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
447 // been hacked to do this for us.
448 Graphics.FromHdcInternal (DisplayHandle);
450 // query for the render extension so
451 // we can ignore the spurious
452 // BadPicture errors that are
453 // generated by cairo/render.
454 XQueryExtension (DisplayHandle, "RENDER",
455 ref render_major_opcode, ref render_first_event, ref render_first_error);
458 if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
459 XSynchronize(DisplayHandle, true);
462 if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
463 ErrorExceptions = true;
467 ScreenNo = XDefaultScreen(DisplayHandle);
468 RootWindow = XRootWindow(DisplayHandle, ScreenNo);
469 DefaultColormap = XDefaultColormap(DisplayHandle, ScreenNo);
471 // Create the foster parent
472 // it is important that border_width is kept in synch with the other XCreateWindow calls
473 FosterParent=XCreateSimpleWindow(DisplayHandle, RootWindow, 0, 0, 1, 1, 0, UIntPtr.Zero, UIntPtr.Zero);
474 if (FosterParent==IntPtr.Zero) {
475 Console.WriteLine("XplatUIX11 Constructor failed to create FosterParent");
478 DebugHelper.WriteLine ("FosterParent created 0x{0:x}", FosterParent.ToInt32());
481 hwnd.Queue = ThreadQueue(Thread.CurrentThread);
482 hwnd.WholeWindow = FosterParent;
483 hwnd.ClientWindow = FosterParent;
485 // Create a HWND for RootWIndow as well, so our queue doesn't eat the events
487 hwnd.Queue = ThreadQueue(Thread.CurrentThread);
488 hwnd.whole_window = RootWindow;
489 hwnd.ClientWindow = RootWindow;
491 // For sleeping on the X11 socket
492 listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
493 IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 0);
497 // To wake up when a timer is ready
498 network_buffer = new byte[10];
500 wake = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
501 wake.Connect(listen.LocalEndPoint);
503 // Make this non-blocking, so it doesn't
504 // deadlock if too many wakes are sent
505 // before the wake_receive end is polled
506 wake.Blocking = false;
508 wake_receive = listen.Accept();
511 pollfds = new Pollfd [2];
512 pollfds [0] = new Pollfd ();
513 pollfds [0].fd = XConnectionNumber (DisplayHandle);
514 pollfds [0].events = PollEvents.POLLIN;
516 pollfds [1] = new Pollfd ();
517 pollfds [1].fd = wake_receive.Handle.ToInt32 ();
518 pollfds [1].events = PollEvents.POLLIN;
521 Keyboard = new X11Keyboard(DisplayHandle, FosterParent);
522 Dnd = new X11Dnd (DisplayHandle, Keyboard);
524 DoubleClickInterval = 500;
526 HoverState.Interval = 500;
527 HoverState.Timer = new Timer();
528 HoverState.Timer.Enabled = false;
529 HoverState.Timer.Interval = HoverState.Interval;
530 HoverState.Timer.Tick += new EventHandler(MouseHover);
531 HoverState.Size = new Size(4, 4);
535 ActiveWindow = IntPtr.Zero;
536 FocusWindow = IntPtr.Zero;
537 ModalWindows = new Stack(3);
539 MouseState = MouseButtons.None;
540 mouse_position = new Point(0, 0);
542 Caret.Timer = new Timer();
543 Caret.Timer.Interval = 500; // FIXME - where should this number come from?
544 Caret.Timer.Tick += new EventHandler(CaretCallback);
548 // Grab atom changes off the root window to catch certain WM events
549 XSelectInput(DisplayHandle, RootWindow, new IntPtr ((int) (EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
551 // Handle any upcoming errors
552 ErrorHandler = new XErrorHandler(HandleError);
553 XSetErrorHandler(ErrorHandler);
555 throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check your DISPLAY environment variable)");
558 #endregion // Internal Methods
561 [Conditional ("DriverDebug")]
562 static void DriverDebug (string format, params object [] args)
564 Console.WriteLine (String.Format (format, args));
568 TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
570 return (int) t.TotalSeconds;
573 static void SetupAtoms() {
574 // make sure this array stays in sync with the statements below
575 string [] atom_names = new string[] {
580 //"_NET_CLIENT_LIST",
581 //"_NET_NUMBER_OF_DESKTOPS",
582 "_NET_DESKTOP_GEOMETRY",
583 //"_NET_DESKTOP_VIEWPORT",
584 "_NET_CURRENT_DESKTOP",
585 //"_NET_DESKTOP_NAMES",
586 "_NET_ACTIVE_WINDOW",
588 //"_NET_SUPPORTING_WM_CHECK",
589 //"_NET_VIRTUAL_ROOTS",
590 //"_NET_DESKTOP_LAYOUT",
591 //"_NET_SHOWING_DESKTOP",
592 //"_NET_CLOSE_WINDOW",
593 //"_NET_MOVERESIZE_WINDOW",
594 "_NET_WM_MOVERESIZE",
595 //"_NET_RESTACK_WINDOW",
596 //"_NET_REQUEST_FRAME_EXTENTS",
598 //"_NET_WM_VISIBLE_NAME",
599 //"_NET_WM_ICON_NAME",
600 //"_NET_WM_VISIBLE_ICON_NAME",
602 "_NET_WM_WINDOW_TYPE",
604 //"_NET_WM_ALLOWED_ACTIONS",
606 //"_NET_WM_STRUT_PARTIAL",
607 //"_NET_WM_ICON_GEOMETRY",
610 //"_NET_WM_HANDLED_ICONS",
612 "_NET_FRAME_EXTENTS",
614 //"_NET_WM_SYNC_REQUEST",
615 "_NET_SYSTEM_TRAY_OPCODE",
616 //"_NET_SYSTEM_TRAY_ORIENTATION",
617 "_NET_WM_STATE_MAXIMIZED_HORZ",
618 "_NET_WM_STATE_MAXIMIZED_VERT",
619 "_NET_WM_STATE_HIDDEN",
623 "_NET_WM_STATE_SKIP_TASKBAR",
624 "_NET_WM_STATE_ABOVE",
625 "_NET_WM_STATE_MODAL",
626 "_NET_WM_CONTEXT_HELP",
627 "_NET_WM_WINDOW_OPACITY",
628 //"_NET_WM_WINDOW_TYPE_DESKTOP",
629 //"_NET_WM_WINDOW_TYPE_DOCK",
630 //"_NET_WM_WINDOW_TYPE_TOOLBAR",
631 //"_NET_WM_WINDOW_TYPE_MENU",
632 "_NET_WM_WINDOW_TYPE_UTILITY",
633 // "_NET_WM_WINDOW_TYPE_DIALOG",
634 //"_NET_WM_WINDOW_TYPE_SPLASH",
635 "_NET_WM_WINDOW_TYPE_NORMAL",
644 "_SWF_PostMessageAtom",
647 IntPtr[] atoms = new IntPtr [atom_names.Length];;
649 XInternAtoms (DisplayHandle, atom_names, atom_names.Length, false, atoms);
652 WM_PROTOCOLS = atoms [off++];
653 WM_DELETE_WINDOW = atoms [off++];
654 WM_TAKE_FOCUS = atoms [off++];
655 //_NET_SUPPORTED = atoms [off++];
656 //_NET_CLIENT_LIST = atoms [off++];
657 //_NET_NUMBER_OF_DESKTOPS = atoms [off++];
658 _NET_DESKTOP_GEOMETRY = atoms [off++];
659 //_NET_DESKTOP_VIEWPORT = atoms [off++];
660 _NET_CURRENT_DESKTOP = atoms [off++];
661 //_NET_DESKTOP_NAMES = atoms [off++];
662 _NET_ACTIVE_WINDOW = atoms [off++];
663 _NET_WORKAREA = atoms [off++];
664 //_NET_SUPPORTING_WM_CHECK = atoms [off++];
665 //_NET_VIRTUAL_ROOTS = atoms [off++];
666 //_NET_DESKTOP_LAYOUT = atoms [off++];
667 //_NET_SHOWING_DESKTOP = atoms [off++];
668 //_NET_CLOSE_WINDOW = atoms [off++];
669 //_NET_MOVERESIZE_WINDOW = atoms [off++];
670 _NET_WM_MOVERESIZE = atoms [off++];
671 //_NET_RESTACK_WINDOW = atoms [off++];
672 //_NET_REQUEST_FRAME_EXTENTS = atoms [off++];
673 _NET_WM_NAME = atoms [off++];
674 //_NET_WM_VISIBLE_NAME = atoms [off++];
675 //_NET_WM_ICON_NAME = atoms [off++];
676 //_NET_WM_VISIBLE_ICON_NAME = atoms [off++];
677 //_NET_WM_DESKTOP = atoms [off++];
678 _NET_WM_WINDOW_TYPE = atoms [off++];
679 _NET_WM_STATE = atoms [off++];
680 //_NET_WM_ALLOWED_ACTIONS = atoms [off++];
681 //_NET_WM_STRUT = atoms [off++];
682 //_NET_WM_STRUT_PARTIAL = atoms [off++];
683 //_NET_WM_ICON_GEOMETRY = atoms [off++];
684 _NET_WM_ICON = atoms [off++];
685 //_NET_WM_PID = atoms [off++];
686 //_NET_WM_HANDLED_ICONS = atoms [off++];
687 _NET_WM_USER_TIME = atoms [off++];
688 _NET_FRAME_EXTENTS = atoms [off++];
689 //_NET_WM_PING = atoms [off++];
690 //_NET_WM_SYNC_REQUEST = atoms [off++];
691 _NET_SYSTEM_TRAY_OPCODE = atoms [off++];
692 //_NET_SYSTEM_TRAY_ORIENTATION = atoms [off++];
693 _NET_WM_STATE_MAXIMIZED_HORZ = atoms [off++];
694 _NET_WM_STATE_MAXIMIZED_VERT = atoms [off++];
695 _NET_WM_STATE_HIDDEN = atoms [off++];
696 _XEMBED = atoms [off++];
697 _XEMBED_INFO = atoms [off++];
698 _MOTIF_WM_HINTS = atoms [off++];
699 _NET_WM_STATE_SKIP_TASKBAR = atoms [off++];
700 _NET_WM_STATE_ABOVE = atoms [off++];
701 _NET_WM_STATE_MODAL = atoms [off++];
702 _NET_WM_CONTEXT_HELP = atoms [off++];
703 _NET_WM_WINDOW_OPACITY = atoms [off++];
704 //_NET_WM_WINDOW_TYPE_DESKTOP = atoms [off++];
705 //_NET_WM_WINDOW_TYPE_DOCK = atoms [off++];
706 //_NET_WM_WINDOW_TYPE_TOOLBAR = atoms [off++];
707 //_NET_WM_WINDOW_TYPE_MENU = atoms [off++];
708 _NET_WM_WINDOW_TYPE_UTILITY = atoms [off++];
709 // _NET_WM_WINDOW_TYPE_DIALOG = atoms [off++];
710 //_NET_WM_WINDOW_TYPE_SPLASH = atoms [off++];
711 _NET_WM_WINDOW_TYPE_NORMAL = atoms [off++];
712 CLIPBOARD = atoms [off++];
713 PRIMARY = atoms [off++];
714 OEMTEXT = atoms [off++];
715 UTF8_STRING = atoms [off++];
716 UTF16_STRING = atoms [off++];
717 RICHTEXTFORMAT = atoms [off++];
718 TARGETS = atoms [off++];
719 AsyncAtom = atoms [off++];
720 PostAtom = atoms [off++];
721 HoverState.Atom = atoms [off++];
723 //DIB = (IntPtr)Atom.XA_PIXMAP;
724 _NET_SYSTEM_TRAY_S = XInternAtom (DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString(), false);
727 void GetSystrayManagerWindow() {
728 XGrabServer(DisplayHandle);
729 SystrayMgrWindow = XGetSelectionOwner(DisplayHandle, _NET_SYSTEM_TRAY_S);
730 XUngrabServer(DisplayHandle);
731 XFlush(DisplayHandle);
734 void SendNetWMMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
735 SendNetWMMessage (window, message_type, l0, l1, l2, IntPtr.Zero);
738 void SendNetWMMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2, IntPtr l3) {
742 xev.ClientMessageEvent.type = XEventName.ClientMessage;
743 xev.ClientMessageEvent.send_event = true;
744 xev.ClientMessageEvent.window = window;
745 xev.ClientMessageEvent.message_type = message_type;
746 xev.ClientMessageEvent.format = 32;
747 xev.ClientMessageEvent.ptr1 = l0;
748 xev.ClientMessageEvent.ptr2 = l1;
749 xev.ClientMessageEvent.ptr3 = l2;
750 xev.ClientMessageEvent.ptr4 = l3;
751 XSendEvent(DisplayHandle, RootWindow, false, new IntPtr ((int) (EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask)), ref xev);
754 void SendNetClientMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
758 xev.ClientMessageEvent.type = XEventName.ClientMessage;
759 xev.ClientMessageEvent.send_event = true;
760 xev.ClientMessageEvent.window = window;
761 xev.ClientMessageEvent.message_type = message_type;
762 xev.ClientMessageEvent.format = 32;
763 xev.ClientMessageEvent.ptr1 = l0;
764 xev.ClientMessageEvent.ptr2 = l1;
765 xev.ClientMessageEvent.ptr3 = l2;
766 XSendEvent(DisplayHandle, window, false, new IntPtr ((int)EventMask.NoEventMask), ref xev);
769 // For WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN, WM_XBUTTONDOWN
770 // WM_CREATE and WM_DESTROY causes
771 void SendParentNotify(IntPtr child, Msg cause, int x, int y)
775 if (child == IntPtr.Zero) {
779 hwnd = Hwnd.GetObjectFromWindow (child);
785 if (hwnd.Handle == IntPtr.Zero) {
789 if (ExStyleSet ((int) hwnd.initial_ex_style, WindowExStyles.WS_EX_NOPARENTNOTIFY)) {
793 if (hwnd.Parent == null) {
797 if (hwnd.Parent.Handle == IntPtr.Zero) {
801 if (cause == Msg.WM_CREATE || cause == Msg.WM_DESTROY) {
802 SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), child);
804 SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), Control.MakeParam(x, y));
807 SendParentNotify (hwnd.Parent.Handle, cause, x, y);
810 bool StyleSet (int s, WindowStyles ws)
812 return (s & (int)ws) == (int)ws;
815 bool ExStyleSet (int ex, WindowExStyles exws)
817 return (ex & (int)exws) == (int)exws;
820 internal static Rectangle TranslateClientRectangleToXClientRectangle (Hwnd hwnd)
822 return TranslateClientRectangleToXClientRectangle (hwnd, Control.FromHandle (hwnd.Handle));
825 internal static Rectangle TranslateClientRectangleToXClientRectangle (Hwnd hwnd, Control ctrl)
828 * If this is a form with no window manager, X is handling all the border and caption painting
829 * so remove that from the area (since the area we set of the window here is the part of the window
830 * we're painting in only)
832 Rectangle rect = hwnd.ClientRect;
833 Form form = ctrl as Form;
834 CreateParams cp = null;
837 cp = form.GetCreateParams ();
839 if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
840 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
841 Rectangle xrect = rect;
843 xrect.Y -= borders.top;
844 xrect.X -= borders.left;
845 xrect.Width += borders.left + borders.right;
846 xrect.Height += borders.top + borders.bottom;
851 if (rect.Width < 1 || rect.Height < 1) {
861 internal static Size TranslateWindowSizeToXWindowSize (CreateParams cp)
863 return TranslateWindowSizeToXWindowSize (cp, new Size (cp.Width, cp.Height));
866 internal static Size TranslateWindowSizeToXWindowSize (CreateParams cp, Size size)
869 * If this is a form with no window manager, X is handling all the border and caption painting
870 * so remove that from the area (since the area we set of the window here is the part of the window
871 * we're painting in only)
873 Form form = cp.control as Form;
874 if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
875 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
878 xrect.Width -= borders.left + borders.right;
879 xrect.Height -= borders.top + borders.bottom;
883 if (size.Height == 0)
890 internal static Size TranslateXWindowSizeToWindowSize (CreateParams cp, int xWidth, int xHeight)
893 * If this is a form with no window manager, X is handling all the border and caption painting
894 * so remove that from the area (since the area we set of the window here is the part of the window
895 * we're painting in only)
897 Size rect = new Size (xWidth, xHeight);
898 Form form = cp.control as Form;
899 if (form != null && (form.window_manager == null && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
900 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
903 xrect.Width += borders.left + borders.right;
904 xrect.Height += borders.top + borders.bottom;
911 internal static Point GetTopLevelWindowLocation (Hwnd hwnd)
917 XTranslateCoordinates (DisplayHandle, hwnd.whole_window, RootWindow, 0, 0, out x, out y, out dummy);
918 frame = FrameExtents (hwnd.whole_window);
923 return new Point (x, y);
926 void DeriveStyles(int Style, int ExStyle, out FormBorderStyle border_style, out bool border_static, out TitleStyle title_style, out int caption_height, out int tool_caption_height) {
929 tool_caption_height = 19;
930 border_static = false;
932 if (StyleSet (Style, WindowStyles.WS_CHILD)) {
933 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
934 border_style = FormBorderStyle.Fixed3D;
935 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
936 border_style = FormBorderStyle.Fixed3D;
937 border_static = true;
938 } else if (!StyleSet (Style, WindowStyles.WS_BORDER)) {
939 border_style = FormBorderStyle.None;
941 border_style = FormBorderStyle.FixedSingle;
943 title_style = TitleStyle.None;
945 if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
947 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
948 title_style = TitleStyle.Tool;
950 title_style = TitleStyle.Normal;
954 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_MDICHILD)) {
957 if (StyleSet (Style, WindowStyles.WS_OVERLAPPEDWINDOW) ||
958 ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
959 border_style = (FormBorderStyle) 0xFFFF;
961 border_style = FormBorderStyle.None;
966 title_style = TitleStyle.None;
967 if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
968 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
969 title_style = TitleStyle.Tool;
971 title_style = TitleStyle.Normal;
975 border_style = FormBorderStyle.None;
977 if (StyleSet (Style, WindowStyles.WS_THICKFRAME)) {
978 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
979 border_style = FormBorderStyle.SizableToolWindow;
981 border_style = FormBorderStyle.Sizable;
984 if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
985 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
986 border_style = FormBorderStyle.Fixed3D;
987 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
988 border_style = FormBorderStyle.Fixed3D;
989 border_static = true;
990 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_DLGMODALFRAME)) {
991 border_style = FormBorderStyle.FixedDialog;
992 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
993 border_style = FormBorderStyle.FixedToolWindow;
994 } else if (StyleSet (Style, WindowStyles.WS_BORDER)) {
995 border_style = FormBorderStyle.FixedSingle;
998 if (StyleSet (Style, WindowStyles.WS_BORDER)) {
999 border_style = FormBorderStyle.FixedSingle;
1006 void SetHwndStyles(Hwnd hwnd, CreateParams cp) {
1007 DeriveStyles(cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.border_static, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
1010 void SetWMStyles(Hwnd hwnd, CreateParams cp) {
1011 MotifWmHints mwmHints;
1012 MotifFunctions functions;
1013 MotifDecorations decorations;
1016 Rectangle client_rect;
1019 bool hide_from_taskbar;
1020 IntPtr transient_for_parent;
1022 // Windows we manage ourselves don't need WM window styles.
1023 if (cp.HasWindowManager && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
1028 mwmHints = new MotifWmHints();
1031 window_type = _NET_WM_WINDOW_TYPE_NORMAL;
1032 transient_for_parent = IntPtr.Zero;
1034 mwmHints.flags = (IntPtr)(MotifFlags.Functions | MotifFlags.Decorations);
1035 mwmHints.functions = (IntPtr)0;
1036 mwmHints.decorations = (IntPtr)0;
1038 form = cp.control as Form;
1040 if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
1041 /* tool windows get no window manager
1045 /* just because the window doesn't get any decorations doesn't
1046 mean we should disable the functions. for instance, without
1047 MotifFunctions.Maximize, changing the windowstate to Maximized
1048 is ignored by metacity. */
1049 functions |= MotifFunctions.Move | MotifFunctions.Resize | MotifFunctions.Minimize | MotifFunctions.Maximize;
1050 } else if (form != null && form.FormBorderStyle == FormBorderStyle.None) {
1051 /* allow borderless window to be maximized */
1052 functions |= MotifFunctions.All | MotifFunctions.Resize;
1054 if (StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
1055 functions |= MotifFunctions.Move;
1056 decorations |= MotifDecorations.Title | MotifDecorations.Menu;
1059 if (StyleSet (cp.Style, WindowStyles.WS_THICKFRAME)) {
1060 functions |= MotifFunctions.Move | MotifFunctions.Resize;
1061 decorations |= MotifDecorations.Border | MotifDecorations.ResizeH;
1064 if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZEBOX)) {
1065 functions |= MotifFunctions.Minimize;
1066 decorations |= MotifDecorations.Minimize;
1069 if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZEBOX)) {
1070 functions |= MotifFunctions.Maximize;
1071 decorations |= MotifDecorations.Maximize;
1074 if (StyleSet (cp.Style, WindowStyles.WS_SIZEBOX)) {
1075 functions |= MotifFunctions.Resize;
1076 decorations |= MotifDecorations.ResizeH;
1079 if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_DLGMODALFRAME)) {
1080 decorations |= MotifDecorations.Border;
1083 if (StyleSet (cp.Style, WindowStyles.WS_BORDER)) {
1084 decorations |= MotifDecorations.Border;
1087 if (StyleSet (cp.Style, WindowStyles.WS_DLGFRAME)) {
1088 decorations |= MotifDecorations.Border;
1091 if (StyleSet (cp.Style, WindowStyles.WS_SYSMENU)) {
1092 functions |= MotifFunctions.Close;
1095 functions &= ~(MotifFunctions.Maximize | MotifFunctions.Minimize | MotifFunctions.Close);
1096 decorations &= ~(MotifDecorations.Menu | MotifDecorations.Maximize | MotifDecorations.Minimize);
1097 if (cp.Caption == "") {
1098 functions &= ~MotifFunctions.Move;
1099 decorations &= ~(MotifDecorations.Title | MotifDecorations.ResizeH);
1104 if ((functions & MotifFunctions.Resize) == 0) {
1105 hwnd.fixed_size = true;
1106 Rectangle fixed_rectangle = new Rectangle (cp.X, cp.Y, cp.Width, cp.Height);
1107 SetWindowMinMax(hwnd.Handle, fixed_rectangle, fixed_rectangle.Size, fixed_rectangle.Size, cp);
1109 hwnd.fixed_size = false;
1112 mwmHints.functions = (IntPtr)functions;
1113 mwmHints.decorations = (IntPtr)decorations;
1115 DriverDebug ("SetWMStyles ({0}, {1}) functions = {2}, decorations = {3}", hwnd, cp, functions, decorations);
1117 if (cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
1118 // needed! map toolwindows to _NET_WM_WINDOW_TYPE_UTILITY to make newer metacity versions happy
1119 // and get those windows in front of their parents
1120 window_type = _NET_WM_WINDOW_TYPE_UTILITY;
1122 window_type = _NET_WM_WINDOW_TYPE_NORMAL;
1125 if (!cp.IsSet (WindowExStyles.WS_EX_APPWINDOW)) {
1126 hide_from_taskbar = true;
1127 } else if (cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW) && form != null && form.Parent != null && !form.ShowInTaskbar) {
1128 hide_from_taskbar = true;
1130 hide_from_taskbar = false;
1133 if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
1134 if (form != null && !hwnd.reparented) {
1135 if (form.Owner != null && form.Owner.Handle != IntPtr.Zero) {
1136 Hwnd owner_hwnd = Hwnd.ObjectFromHandle (form.Owner.Handle);
1137 if (owner_hwnd != null)
1138 transient_for_parent = owner_hwnd.whole_window;
1142 if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && (hwnd.parent != null) && (hwnd.parent.whole_window != IntPtr.Zero)) {
1143 transient_for_parent = hwnd.parent.whole_window;
1146 FormWindowState current_state = GetWindowState (hwnd.Handle);
1147 if (current_state == (FormWindowState)(-1))
1148 current_state = FormWindowState.Normal;
1150 client_rect = TranslateClientRectangleToXClientRectangle (hwnd);
1155 atoms [0] = window_type.ToInt32 ();
1156 XChangeProperty (DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
1158 XChangeProperty(DisplayHandle, hwnd.whole_window, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropertyMode.Replace, ref mwmHints, 5);
1160 if (transient_for_parent != IntPtr.Zero) {
1161 XSetTransientForHint (DisplayHandle, hwnd.whole_window, transient_for_parent);
1164 MoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
1166 if (hide_from_taskbar) {
1167 /* this line keeps the window from showing up in gnome's taskbar */
1168 atoms[atom_count++] = _NET_WM_STATE_SKIP_TASKBAR.ToInt32();
1170 /* we need to add these atoms in the
1171 * event we're maximized, since we're
1172 * replacing the existing
1173 * _NET_WM_STATE here. If we don't
1174 * add them, future calls to
1175 * GetWindowState will return Normal
1176 * for a window which is maximized. */
1177 if (current_state == FormWindowState.Maximized) {
1178 atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_HORZ.ToInt32();
1179 atoms[atom_count++] = _NET_WM_STATE_MAXIMIZED_VERT.ToInt32();
1182 if (form != null && form.Modal) {
1183 atoms[atom_count++] = _NET_WM_STATE_MODAL.ToInt32 ();
1186 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, atom_count);
1189 IntPtr[] atom_ptrs = new IntPtr[2];
1190 atom_ptrs[atom_count++] = WM_DELETE_WINDOW;
1191 if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_CONTEXTHELP)) {
1192 atom_ptrs[atom_count++] = _NET_WM_CONTEXT_HELP;
1195 XSetWMProtocols(DisplayHandle, hwnd.whole_window, atom_ptrs, atom_count);
1199 void SetIcon(Hwnd hwnd, Icon icon)
1204 // This really needs to do whatever it
1205 // takes to remove the window manager
1206 // menu, not just delete the ICON
1207 // property. This will cause metacity
1208 // to use the "no icon set" icon, and
1209 // we'll still have an icon.
1210 XDeleteProperty (DisplayHandle, hwnd.whole_window, _NET_WM_ICON);
1218 bitmap = icon.ToBitmap();
1220 size = bitmap.Width * bitmap.Height + 2;
1221 data = new IntPtr[size];
1223 data[index++] = (IntPtr)bitmap.Width;
1224 data[index++] = (IntPtr)bitmap.Height;
1226 for (int y = 0; y < bitmap.Height; y++) {
1227 for (int x = 0; x < bitmap.Width; x++) {
1228 data[index++] = (IntPtr)bitmap.GetPixel (x, y).ToArgb ();
1232 XChangeProperty (DisplayHandle, hwnd.whole_window,
1233 _NET_WM_ICON, (IntPtr)Atom.XA_CARDINAL, 32,
1234 PropertyMode.Replace, data, size);
1238 void WakeupMain () {
1240 wake.Send (new byte [] { 0xFF });
1241 } catch (SocketException ex) {
1242 if (ex.SocketErrorCode != SocketError.WouldBlock) {
1248 XEventQueue ThreadQueue(Thread thread) {
1251 queue = (XEventQueue)MessageQueues[thread];
1252 if (queue == null) {
1253 queue = new XEventQueue(thread);
1254 MessageQueues[thread] = queue;
1260 void TranslatePropertyToClipboard(IntPtr property) {
1265 IntPtr prop = IntPtr.Zero;
1267 Clipboard.Item = null;
1269 XGetWindowProperty(DisplayHandle, FosterParent, property, IntPtr.Zero, new IntPtr (0x7fffffff), true, (IntPtr)Atom.AnyPropertyType, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
1271 if ((long)nitems > 0) {
1272 if (property == (IntPtr)Atom.XA_STRING) {
1273 // Xamarin-5116: PtrToStringAnsi expects to get UTF-8, but we might have
1274 // Latin-1 instead, in which case it will return null.
1275 var s = Marshal.PtrToStringAnsi (prop);
1276 if (string.IsNullOrEmpty (s)) {
1277 var sb = new StringBuilder ();
1278 for (int i = 0; i < (int)nitems; i++) {
1279 var b = Marshal.ReadByte (prop, i);
1280 sb.Append ((char)b);
1284 // Some X managers/apps pass unicode chars as escaped strings, so
1285 // we may need to unescape them.
1286 Clipboard.Item = UnescapeUnicodeFromAnsi (s);
1287 } else if (property == (IntPtr)Atom.XA_BITMAP) {
1288 // FIXME - convert bitmap to image
1289 } else if (property == (IntPtr)Atom.XA_PIXMAP) {
1290 // FIXME - convert pixmap to image
1291 } else if (property == OEMTEXT) {
1292 Clipboard.Item = UnescapeUnicodeFromAnsi (Marshal.PtrToStringAnsi(prop));
1293 } else if (property == UTF8_STRING) {
1294 byte [] buffer = new byte [(int)nitems];
1295 for (int i = 0; i < (int)nitems; i++)
1296 buffer [i] = Marshal.ReadByte (prop, i);
1297 Clipboard.Item = Encoding.UTF8.GetString (buffer);
1298 } else if (property == UTF16_STRING) {
1299 byte [] buffer = new byte [(int)nitems];
1300 for (int i = 0; i < (int)nitems; i++)
1301 buffer [i] = Marshal.ReadByte (prop, i);
1302 Clipboard.Item = Encoding.Unicode.GetString (buffer);
1303 } else if (property == RICHTEXTFORMAT)
1304 Clipboard.Item = Marshal.PtrToStringAnsi(prop);
1305 else if (DataFormats.ContainsFormat (property.ToInt32 ())) {
1306 if (DataFormats.GetFormat (property.ToInt32 ()).is_serializable) {
1307 MemoryStream memory_stream = new MemoryStream ((int)nitems);
1308 for (int i = 0; i < (int)nitems; i++)
1309 memory_stream.WriteByte (Marshal.ReadByte (prop, i));
1311 memory_stream.Position = 0;
1312 BinaryFormatter formatter = new BinaryFormatter ();
1313 Clipboard.Item = formatter.Deserialize (memory_stream);
1314 memory_stream.Close ();
1322 string UnescapeUnicodeFromAnsi (string value)
1324 if (value == null || value.IndexOf ("\\u") == -1)
1327 StringBuilder sb = new StringBuilder (value.Length);
1331 while (start < value.Length) {
1332 pos = value.IndexOf ("\\u", start);
1336 sb.Append (value, start, pos - start);
1341 while (pos < value.Length && length < 4) {
1342 if (!ValidHexDigit (value [pos]))
1349 if (!Int32.TryParse (value.Substring (start, length), System.Globalization.NumberStyles.HexNumber,
1351 return value; // Error, return the unescaped original value.
1353 sb.Append ((char)res);
1357 // Append any remaining data.
1358 if (start < value.Length)
1359 sb.Append (value, start, value.Length - start);
1361 return sb.ToString ();
1364 private static bool ValidHexDigit (char e)
1366 return Char.IsDigit (e) || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
1369 void AddExpose (Hwnd hwnd, bool client, int x, int y, int width, int height) {
1371 if ((hwnd == null) || (x > hwnd.Width) || (y > hwnd.Height) || ((x + width) < 0) || ((y + height) < 0)) {
1375 // Keep the invalid area as small as needed
1376 if ((x + width) > hwnd.width) {
1377 width = hwnd.width - x;
1380 if ((y + height) > hwnd.height) {
1381 height = hwnd.height - y;
1385 hwnd.AddInvalidArea(x, y, width, height);
1386 if (!hwnd.expose_pending) {
1387 if (!hwnd.nc_expose_pending) {
1388 hwnd.Queue.Paint.Enqueue(hwnd);
1390 hwnd.expose_pending = true;
1393 hwnd.AddNcInvalidArea (x, y, width, height);
1395 if (!hwnd.nc_expose_pending) {
1396 if (!hwnd.expose_pending) {
1397 hwnd.Queue.Paint.Enqueue(hwnd);
1399 hwnd.nc_expose_pending = true;
1404 static Hwnd.Borders FrameExtents (IntPtr window)
1410 IntPtr prop = IntPtr.Zero;
1411 Hwnd.Borders rect = new Hwnd.Borders ();
1413 XGetWindowProperty (DisplayHandle, window, _NET_FRAME_EXTENTS, IntPtr.Zero, new IntPtr (16), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
1414 if (prop != IntPtr.Zero) {
1415 if (nitems.ToInt32 () == 4) {
1416 rect.left = Marshal.ReadInt32 (prop, 0);
1417 rect.right = Marshal.ReadInt32 (prop, IntPtr.Size);
1418 rect.top = Marshal.ReadInt32 (prop, 2 * IntPtr.Size);
1419 rect.bottom = Marshal.ReadInt32 (prop, 3 * IntPtr.Size);
1427 void AddConfigureNotify (XEvent xevent) {
1430 hwnd = Hwnd.GetObjectFromWindow(xevent.ConfigureEvent.window);
1433 if (hwnd == null || hwnd.zombie) {
1436 if ((xevent.ConfigureEvent.window == hwnd.whole_window)/* && (xevent.ConfigureEvent.window == xevent.ConfigureEvent.xevent)*/) {
1437 if (hwnd.parent == null) {
1438 // The location given by the event is not reliable between different wm's,
1439 // so use an alternative way of getting it.
1440 Point location = GetTopLevelWindowLocation (hwnd);
1441 hwnd.x = location.X;
1442 hwnd.y = location.Y;
1445 // XXX this sucks. this isn't thread safe
1446 Control ctrl = Control.FromHandle (hwnd.Handle);
1447 Size TranslatedSize;
1449 TranslatedSize = TranslateXWindowSizeToWindowSize (ctrl.GetCreateParams (), xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
1451 TranslatedSize = new Size (xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
1453 hwnd.width = TranslatedSize.Width;
1454 hwnd.height = TranslatedSize.Height;
1455 hwnd.ClientRect = Rectangle.Empty;
1457 DriverDebug ("AddConfigureNotify (hwnd.Handle = {1}, final hwnd.rect = {0}, reported rect={2})",
1458 new Rectangle (hwnd.x, hwnd.y, hwnd.width, hwnd.height), hwnd.Handle,
1459 new Rectangle (xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.width));
1460 lock (hwnd.configure_lock) {
1461 if (!hwnd.configure_pending) {
1462 hwnd.Queue.EnqueueLocked (xevent);
1463 hwnd.configure_pending = true;
1467 // We drop configure events for Client windows
1471 if ((Caret.gc == IntPtr.Zero) || Caret.On) {
1477 XDrawLine(DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1482 if ((Caret.gc == IntPtr.Zero) || !Caret.On) {
1488 XDrawLine(DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1492 int NextTimeout (ArrayList timers, DateTime now) {
1495 foreach (Timer timer in timers) {
1496 int next = (int) (timer.Expires - now).TotalMilliseconds;
1498 return 0; // Have a timer that has already expired
1501 if (next < timeout) {
1505 if (timeout < Timer.Minimum) {
1506 timeout = Timer.Minimum;
1514 void CheckTimers (ArrayList timers, DateTime now) {
1517 count = timers.Count;
1522 for (int i = 0; i < timers.Count; i++) {
1525 timer = (Timer) timers [i];
1527 if (timer.Enabled && timer.Expires <= now && !timer.Busy) {
1529 // - Before MainForm.OnLoad if DoEvents () is called.
1530 // - After MainForm.OnLoad if not.
1533 (Application.MWFThread.Current.Context != null &&
1534 (Application.MWFThread.Current.Context.MainForm == null ||
1535 Application.MWFThread.Current.Context.MainForm.IsLoaded))) {
1545 void WaitForHwndMessage (Hwnd hwnd, Msg message) {
1546 WaitForHwndMessage (hwnd, message, false);
1550 void WaitForHwndMessage (Hwnd hwnd, Msg message, bool process) {
1551 MSG msg = new MSG ();
1554 queue = ThreadQueue(Thread.CurrentThread);
1556 queue.DispatchIdle = false;
1559 string key = hwnd.Handle + ":" + message;
1560 if (!messageHold.ContainsKey (key))
1561 messageHold.Add (key, 1);
1563 messageHold[key] = ((int)messageHold[key]) + 1;
1568 DebugHelper.WriteLine ("Waiting for message " + message + " on hwnd " + String.Format("0x{0:x}", hwnd.Handle.ToInt32 ()));
1569 DebugHelper.Indent ();
1571 if (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
1572 if ((Msg)msg.message == Msg.WM_QUIT) {
1573 PostQuitMessage (0);
1578 DebugHelper.WriteLine ("PeekMessage got " + msg);
1580 if (msg.hwnd == hwnd.Handle) {
1581 if ((Msg)msg.message == message) {
1583 TranslateMessage (ref msg);
1584 DispatchMessage (ref msg);
1588 else if ((Msg)msg.message == Msg.WM_DESTROY)
1592 TranslateMessage (ref msg);
1593 DispatchMessage (ref msg);
1597 done = !messageHold.ContainsKey (key) || ((int)messageHold[key] < 1) || done;
1600 messageHold.Remove (key);
1602 DebugHelper.Unindent ();
1603 DebugHelper.WriteLine ("Finished waiting for " + key);
1605 queue.DispatchIdle = true;
1609 void MapWindow(Hwnd hwnd, WindowType windows) {
1611 Form f = Control.FromHandle(hwnd.Handle) as Form;
1613 if (f.WindowState == FormWindowState.Normal) {
1614 f.waiting_showwindow = true;
1615 SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
1619 // it's possible that our Hwnd is no
1620 // longer valid after making that
1621 // SendMessage call, so check here.
1626 // Most window managers will respect the _NET_WM_STATE property.
1627 // If not, use XMapRaised to map the window at the top level as
1628 // a last ditch effort.
1629 if ((windows & WindowType.Whole) != 0) {
1630 XMapRaised(DisplayHandle, hwnd.whole_window);
1632 if ((windows & WindowType.Client) != 0) {
1633 XMapRaised(DisplayHandle, hwnd.client_window);
1636 if ((windows & WindowType.Whole) != 0) {
1637 XMapWindow(DisplayHandle, hwnd.whole_window);
1639 if ((windows & WindowType.Client) != 0) {
1640 XMapWindow(DisplayHandle, hwnd.client_window);
1647 if (f.waiting_showwindow) {
1648 WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
1649 CreateParams cp = f.GetCreateParams();
1650 if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
1651 !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
1652 WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
1659 void UnmapWindow(Hwnd hwnd, WindowType windows) {
1662 if (Control.FromHandle(hwnd.Handle) is Form) {
1663 f = Control.FromHandle(hwnd.Handle) as Form;
1664 if (f.WindowState == FormWindowState.Normal) {
1665 f.waiting_showwindow = true;
1666 SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, IntPtr.Zero, IntPtr.Zero);
1670 // it's possible that our Hwnd is no
1671 // longer valid after making that
1672 // SendMessage call, so check here.
1673 // FIXME: it is likely wrong, as it has already sent WM_SHOWWINDOW
1677 if ((windows & WindowType.Client) != 0) {
1678 XUnmapWindow(DisplayHandle, hwnd.client_window);
1680 if ((windows & WindowType.Whole) != 0) {
1681 XUnmapWindow(DisplayHandle, hwnd.whole_window);
1684 hwnd.mapped = false;
1687 if (f.waiting_showwindow) {
1688 WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
1689 CreateParams cp = f.GetCreateParams();
1690 if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
1691 !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
1692 WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
1699 void UpdateMessageQueue (XEventQueue queue) {
1700 UpdateMessageQueue(queue, true);
1703 void UpdateMessageQueue (XEventQueue queue, bool allowIdle) {
1708 now = DateTime.UtcNow;
1711 pending = XPending (DisplayHandle);
1714 if (pending == 0 && allowIdle) {
1715 if ((queue == null || queue.DispatchIdle) && Idle != null) {
1716 Idle (this, EventArgs.Empty);
1720 pending = XPending (DisplayHandle);
1727 if (queue != null) {
1728 if (queue.Paint.Count > 0)
1731 timeout = NextTimeout (queue.timer_list, now);
1736 int length = pollfds.Length - 1;
1737 lock (wake_waiting_lock) {
1738 if (wake_waiting == false) {
1740 wake_waiting = true;
1744 Syscall.poll (pollfds, (uint)length, timeout);
1745 // Clean out buffer, so we're not busy-looping on the same data
1746 if (length == pollfds.Length) {
1747 if (pollfds[1].revents != 0)
1748 wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None);
1749 lock (wake_waiting_lock) {
1750 wake_waiting = false;
1755 pending = XPending (DisplayHandle);
1761 CheckTimers (queue.timer_list, now);
1764 XEvent xevent = new XEvent ();
1767 if (XPending (DisplayHandle) == 0)
1770 XNextEvent (DisplayHandle, ref xevent);
1772 if (xevent.AnyEvent.type == XEventName.KeyPress ||
1773 xevent.AnyEvent.type == XEventName.KeyRelease) {
1774 // PreFilter() handles "shift key state updates.
1775 Keyboard.PreFilter (xevent);
1776 if (XFilterEvent (ref xevent, Keyboard.ClientWindow)) {
1777 // probably here we could raise WM_IME_KEYDOWN and
1778 // WM_IME_KEYUP, but I'm not sure it is worthy.
1782 else if (XFilterEvent (ref xevent, IntPtr.Zero))
1786 hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
1790 DebugHelper.WriteLine ("UpdateMessageQueue got Event: " + xevent.ToString ());
1792 switch (xevent.type) {
1793 case XEventName.Expose:
1794 AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
1797 case XEventName.SelectionClear: {
1798 // Should we do something?
1802 case XEventName.SelectionRequest: {
1803 if (Dnd.HandleSelectionRequestEvent (ref xevent))
1807 sel_event = new XEvent();
1808 sel_event.SelectionEvent.type = XEventName.SelectionNotify;
1809 sel_event.SelectionEvent.send_event = true;
1810 sel_event.SelectionEvent.display = DisplayHandle;
1811 sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
1812 sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
1813 sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
1814 sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
1815 sel_event.SelectionEvent.property = IntPtr.Zero;
1817 IntPtr format_atom = xevent.SelectionRequestEvent.target;
1819 // Seems that some apps support asking for supported types
1820 if (format_atom == TARGETS) {
1827 if (Clipboard.IsSourceText) {
1828 atoms[atom_count++] = (int)Atom.XA_STRING;
1829 atoms[atom_count++] = (int)OEMTEXT;
1830 atoms[atom_count++] = (int)UTF8_STRING;
1831 atoms[atom_count++] = (int)UTF16_STRING;
1832 atoms[atom_count++] = (int)RICHTEXTFORMAT;
1833 } else if (Clipboard.IsSourceImage) {
1834 atoms[atom_count++] = (int)Atom.XA_PIXMAP;
1835 atoms[atom_count++] = (int)Atom.XA_BITMAP;
1837 // FIXME - handle other types
1840 XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property,
1841 (IntPtr)xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
1842 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1843 } else if (format_atom == (IntPtr)RICHTEXTFORMAT) {
1844 string rtf_text = Clipboard.GetRtfText ();
1845 if (rtf_text != null) {
1846 // The RTF spec mentions that ascii is enough to contain it
1847 Byte [] bytes = Encoding.ASCII.GetBytes (rtf_text);
1848 int buflen = bytes.Length;
1849 IntPtr buffer = Marshal.AllocHGlobal (buflen);
1851 for (int i = 0; i < buflen; i++)
1852 Marshal.WriteByte (buffer, i, bytes[i]);
1854 XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property,
1855 (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
1856 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1857 Marshal.FreeHGlobal(buffer);
1859 } else if (Clipboard.IsSourceText &&
1860 (format_atom == (IntPtr)Atom.XA_STRING
1861 || format_atom == OEMTEXT
1862 || format_atom == UTF16_STRING
1863 || format_atom == UTF8_STRING)) {
1864 IntPtr buffer = IntPtr.Zero;
1866 Encoding encoding = null;
1870 // Select an encoding depending on the target
1871 IntPtr target_atom = xevent.SelectionRequestEvent.target;
1872 if (target_atom == (IntPtr)Atom.XA_STRING || target_atom == OEMTEXT)
1873 // FIXME - EOMTEXT should encode into ISO2022
1874 encoding = Encoding.ASCII;
1875 else if (target_atom == UTF16_STRING)
1876 encoding = Encoding.Unicode;
1877 else if (target_atom == UTF8_STRING)
1878 encoding = Encoding.UTF8;
1882 bytes = encoding.GetBytes (Clipboard.GetPlainText ());
1883 buffer = Marshal.AllocHGlobal (bytes.Length);
1884 buflen = bytes.Length;
1886 for (int i = 0; i < buflen; i++)
1887 Marshal.WriteByte (buffer, i, bytes [i]);
1889 if (buffer != IntPtr.Zero) {
1890 XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
1891 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1892 Marshal.FreeHGlobal(buffer);
1894 } else if (Clipboard.GetSource (format_atom.ToInt32 ()) != null) { // check if we have an available value of this format
1895 if (DataFormats.GetFormat (format_atom.ToInt32 ()).is_serializable) {
1896 object serializable = Clipboard.GetSource (format_atom.ToInt32 ());
1898 BinaryFormatter formatter = new BinaryFormatter ();
1899 MemoryStream memory_stream = new MemoryStream ();
1900 formatter.Serialize (memory_stream, serializable);
1902 int buflen = (int)memory_stream.Length;
1903 IntPtr buffer = Marshal.AllocHGlobal (buflen);
1904 memory_stream.Position = 0;
1905 for (int i = 0; i < buflen; i++)
1906 Marshal.WriteByte (buffer, i, (byte)memory_stream.ReadByte ());
1907 memory_stream.Close ();
1909 XChangeProperty (DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target,
1910 8, PropertyMode.Replace, buffer, buflen);
1911 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1912 Marshal.FreeHGlobal (buffer);
1915 } else if (Clipboard.IsSourceImage) {
1916 if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
1917 // FIXME - convert image and store as property
1918 } else if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
1919 // FIXME - convert image and store as property
1923 XSendEvent(DisplayHandle, xevent.SelectionRequestEvent.requestor, false, new IntPtr ((int)EventMask.NoEventMask), ref sel_event);
1927 case XEventName.SelectionNotify: {
1928 if (Clipboard.Enumerating) {
1929 Clipboard.Enumerating = false;
1930 if (xevent.SelectionEvent.property != IntPtr.Zero) {
1931 XDeleteProperty(DisplayHandle, FosterParent, (IntPtr)xevent.SelectionEvent.property);
1932 if (!Clipboard.Formats.Contains(xevent.SelectionEvent.property)) {
1933 Clipboard.Formats.Add(xevent.SelectionEvent.property);
1934 DriverDebug("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
1937 } else if (Clipboard.Retrieving) {
1938 Clipboard.Retrieving = false;
1939 if (xevent.SelectionEvent.property != IntPtr.Zero) {
1940 TranslatePropertyToClipboard(xevent.SelectionEvent.property);
1942 Clipboard.ClearSources ();
1943 Clipboard.Item = null;
1946 Dnd.HandleSelectionNotifyEvent (ref xevent);
1951 case XEventName.KeyRelease:
1952 if (!detectable_key_auto_repeat && XPending (DisplayHandle) != 0) {
1953 XEvent nextevent = new XEvent ();
1955 XPeekEvent (DisplayHandle, ref nextevent);
1957 if (nextevent.type == XEventName.KeyPress &&
1958 nextevent.KeyEvent.keycode == xevent.KeyEvent.keycode &&
1959 nextevent.KeyEvent.time == xevent.KeyEvent.time) {
1963 goto case XEventName.KeyPress;
1965 case XEventName.MotionNotify: {
1968 /* we can't do motion compression across threads, so just punt if we don't match up */
1969 if (Thread.CurrentThread == hwnd.Queue.Thread && hwnd.Queue.Count > 0) {
1970 peek = hwnd.Queue.Peek();
1971 if (peek.AnyEvent.type == XEventName.MotionNotify) {
1975 goto case XEventName.KeyPress;
1978 case XEventName.KeyPress:
1979 hwnd.Queue.EnqueueLocked (xevent);
1980 /* Process KeyPresses immediately. Otherwise multiple Compose messages as a result of a
1981 * single physical keypress are not processed correctly */
1983 case XEventName.ButtonPress:
1984 case XEventName.ButtonRelease:
1985 case XEventName.EnterNotify:
1986 case XEventName.LeaveNotify:
1987 case XEventName.CreateNotify:
1988 case XEventName.DestroyNotify:
1989 case XEventName.FocusIn:
1990 case XEventName.FocusOut:
1991 case XEventName.ClientMessage:
1992 case XEventName.ReparentNotify:
1993 case XEventName.MapNotify:
1994 case XEventName.UnmapNotify:
1995 hwnd.Queue.EnqueueLocked (xevent);
1998 case XEventName.ConfigureNotify:
1999 AddConfigureNotify(xevent);
2002 case XEventName.PropertyNotify:
2003 DriverDebug ("UpdateMessageQueue (), got Event: {0}", xevent.ToString ());
2004 if (xevent.PropertyEvent.atom == _NET_ACTIVE_WINDOW) {
2009 IntPtr prop = IntPtr.Zero;
2012 prev_active = ActiveWindow;
2013 XGetWindowProperty(DisplayHandle, RootWindow, _NET_ACTIVE_WINDOW, IntPtr.Zero, new IntPtr (1), false, (IntPtr)Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2014 if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
2015 ActiveWindow = Hwnd.GetHandleFromWindow((IntPtr)Marshal.ReadInt32(prop));
2018 DebugHelper.WriteLine ("PropertyNotify: _NET_ACTIVE_WINDOW: previous = 0x{0:x}, new = 0x{1:x}", prev_active.ToInt32 (), ActiveWindow.ToInt32 ());
2020 if (prev_active != ActiveWindow) {
2021 if (prev_active != IntPtr.Zero) {
2022 PostMessage(prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
2024 if (ActiveWindow != IntPtr.Zero) {
2025 PostMessage(ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
2028 if (ModalWindows.Count == 0) {
2031 // Modality Handling
2033 // If there is a modal window on the stack and the new active
2034 // window is MWF window, but not the modal one and not a non-modal
2035 // child of the modal one, switch back to the modal window.
2037 // To identify if a non-modal form is child of a modal form
2038 // we match their ApplicationContexts, which will be the same.
2039 // This is because each modal form runs the loop with a
2040 // new ApplicationContext, which is inherited by the non-modal
2043 Form activeForm = Control.FromHandle (ActiveWindow) as Form;
2044 if (activeForm != null) {
2045 Form modalForm = Control.FromHandle ((IntPtr)ModalWindows.Peek()) as Form;
2046 if (ActiveWindow != (IntPtr)ModalWindows.Peek() &&
2047 (modalForm == null || activeForm.context == modalForm.context)) {
2048 Activate((IntPtr)ModalWindows.Peek());
2055 else if (xevent.PropertyEvent.atom == _NET_WM_STATE) {
2056 // invalidate our cache - we'll query again the next time someone does GetWindowState.
2057 hwnd.cached_window_state = (FormWindowState)(-1);
2058 PostMessage (hwnd.Handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
2066 IntPtr GetMousewParam(int Delta) {
2069 if ((MouseState & MouseButtons.Left) != 0) {
2070 result |= (int)MsgButtons.MK_LBUTTON;
2073 if ((MouseState & MouseButtons.Middle) != 0) {
2074 result |= (int)MsgButtons.MK_MBUTTON;
2077 if ((MouseState & MouseButtons.Right) != 0) {
2078 result |= (int)MsgButtons.MK_RBUTTON;
2081 Keys mods = ModifierKeys;
2082 if ((mods & Keys.Control) != 0) {
2083 result |= (int)MsgButtons.MK_CONTROL;
2086 if ((mods & Keys.Shift) != 0) {
2087 result |= (int)MsgButtons.MK_SHIFT;
2090 result |= Delta << 16;
2092 return (IntPtr)result;
2094 IntPtr XGetParent(IntPtr handle) {
2101 XQueryTree(DisplayHandle, handle, out Root, out Parent, out Children, out ChildCount);
2104 if (Children!=IntPtr.Zero) {
2112 int HandleError (IntPtr display, ref XErrorEvent error_event)
2114 // we need to workaround a problem with the
2115 // ordering of destruction of Drawables and
2116 // Pictures that exists between cairo and
2117 // RENDER on the server.
2118 if (error_event.request_code == (XRequest)render_major_opcode
2119 && error_event.minor_code == 7 /* X_RenderFreePicture from render.h */
2120 && error_event.error_code == render_first_error + 1 /* BadPicture from render.h */) {
2124 if (ErrorExceptions) {
2125 XUngrabPointer (display, IntPtr.Zero);
2126 throw new XException (error_event.display, error_event.resourceid,
2127 error_event.serial, error_event.error_code,
2128 error_event.request_code, error_event.minor_code);
2130 Console.WriteLine("X11 Error encountered: {0}{1}\n",
2131 XException.GetMessage (error_event.display, error_event.resourceid,
2132 error_event.serial, error_event.error_code,
2133 error_event.request_code, error_event.minor_code),
2134 Environment.StackTrace);
2139 void AccumulateDestroyedHandles (Control c, ArrayList list)
2141 DebugHelper.Enter ();
2144 Control[] controls = c.Controls.GetAllControls ();
2146 DebugHelper.WriteLine ("Checking control:0x{0:x}", c.IsHandleCreated ? c.Handle.ToInt32() : 0);
2148 if (c.IsHandleCreated && !c.IsDisposed) {
2149 Hwnd hwnd = Hwnd.ObjectFromHandle(c.Handle);
2151 DriverDebug (" + adding {0} to the list of zombie windows", XplatUI.Window (hwnd.Handle));
2152 DriverDebug (" + parent X window is {0:X}", XGetParent (hwnd.whole_window).ToInt32());
2155 CleanupCachedWindows (hwnd);
2158 for (int i = 0; i < controls.Length; i ++) {
2159 AccumulateDestroyedHandles (controls[i], list);
2162 DebugHelper.Leave ();
2165 void CleanupCachedWindows (Hwnd hwnd)
2167 if (ActiveWindow == hwnd.Handle) {
2168 SendMessage(hwnd.client_window, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
2169 ActiveWindow = IntPtr.Zero;
2172 if (FocusWindow == hwnd.Handle) {
2173 SendMessage(hwnd.client_window, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
2174 FocusWindow = IntPtr.Zero;
2177 if (Grab.Hwnd == hwnd.Handle) {
2178 Grab.Hwnd = IntPtr.Zero;
2179 Grab.Confined = false;
2182 DestroyCaret (hwnd.Handle);
2185 void PerformNCCalc(Hwnd hwnd) {
2186 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
2190 rect = new Rectangle (0, 0, hwnd.Width, hwnd.Height);
2192 ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
2193 ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));
2195 ncp.rgrc1.left = rect.Left;
2196 ncp.rgrc1.top = rect.Top;
2197 ncp.rgrc1.right = rect.Right;
2198 ncp.rgrc1.bottom = rect.Bottom;
2200 Marshal.StructureToPtr(ncp, ptr, true);
2201 NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
2202 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
2203 Marshal.FreeHGlobal(ptr);
2206 rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
2207 hwnd.ClientRect = rect;
2209 rect = TranslateClientRectangleToXClientRectangle (hwnd);
2212 MoveResizeWindow (DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
2215 AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
2217 #endregion // Methods
2220 void MouseHover(object sender, EventArgs e) {
2224 HoverState.Timer.Enabled = false;
2226 if (HoverState.Window != IntPtr.Zero) {
2227 hwnd = Hwnd.GetObjectFromWindow(HoverState.Window);
2229 xevent = new XEvent ();
2231 xevent.type = XEventName.ClientMessage;
2232 xevent.ClientMessageEvent.display = DisplayHandle;
2233 xevent.ClientMessageEvent.window = HoverState.Window;
2234 xevent.ClientMessageEvent.message_type = HoverState.Atom;
2235 xevent.ClientMessageEvent.format = 32;
2236 xevent.ClientMessageEvent.ptr1 = (IntPtr) (HoverState.Y << 16 | HoverState.X);
2238 hwnd.Queue.EnqueueLocked (xevent);
2245 void CaretCallback(object sender, EventArgs e) {
2249 Caret.On = !Caret.On;
2251 XDrawLine(DisplayHandle, Caret.Hwnd, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
2253 #endregion // Callbacks
2255 #region Public Properties
2257 internal override int CaptionHeight {
2263 internal override Size CursorSize {
2268 if (XQueryBestCursor(DisplayHandle, RootWindow, 32, 32, out x, out y) != 0) {
2269 return new Size(x, y);
2271 return new Size(16, 16);
2276 internal override bool DragFullWindows {
2282 internal override Size DragSize {
2284 return new Size(4, 4);
2288 internal override Size FrameBorderSize {
2290 return new Size (4, 4);
2294 internal override Size IconSize {
2300 if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
2304 current = (long)list;
2307 size = new XIconSize();
2309 for (int i = 0; i < count; i++) {
2310 size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
2311 current += Marshal.SizeOf(size);
2313 // Look for our preferred size
2314 if (size.min_width == 32) {
2316 return new Size(32, 32);
2319 if (size.max_width == 32) {
2321 return new Size(32, 32);
2324 if (size.min_width < 32 && size.max_width > 32) {
2327 // check if we can fit one
2329 while (x < size.max_width) {
2330 x += size.width_inc;
2333 return new Size(32, 32);
2338 if (largest < size.max_width) {
2339 largest = size.max_width;
2343 // We didn't find a match or we wouldn't be here
2344 return new Size(largest, largest);
2347 return new Size(32, 32);
2352 internal override int KeyboardSpeed {
2355 // A lot harder: need to do:
2356 // XkbQueryExtension(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 1
2357 // XkbAllocKeyboard(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 0x080517a8
2358 // XkbGetControls(0x08051008, 1, 0x080517a8, 0xbfffdf54, 0xbfffdf58) = 0
2360 // And from that we can tell the repetition rate
2362 // Notice, the values must map to:
2363 // [0, 31] which maps to 2.5 to 30 repetitions per second.
2369 internal override int KeyboardDelay {
2372 // Return values must range from 0 to 4, 0 meaning 250ms,
2373 // and 4 meaning 1000 ms.
2375 return 1; // ie, 500 ms
2379 internal override Size MaxWindowTrackSize {
2381 return new Size (WorkingArea.Width, WorkingArea.Height);
2385 internal override bool MenuAccessKeysUnderlined {
2391 internal override Size MinimizedWindowSpacingSize {
2393 return new Size(1, 1);
2397 internal override Size MinimumWindowSize {
2399 return new Size(110, 22);
2403 internal override Size MinimumFixedToolWindowSize {
2404 get { return new Size (27, 22); }
2407 internal override Size MinimumSizeableToolWindowSize {
2408 get { return new Size (37, 22); }
2411 internal override Size MinimumNoBorderWindowSize {
2412 get { return new Size (2, 2); }
2415 internal override Keys ModifierKeys {
2417 return Keyboard.ModifierKeys;
2421 internal override Size SmallIconSize {
2427 if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
2431 current = (long)list;
2434 size = new XIconSize();
2436 for (int i = 0; i < count; i++) {
2437 size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
2438 current += Marshal.SizeOf(size);
2440 // Look for our preferred size
2441 if (size.min_width == 16) {
2443 return new Size(16, 16);
2446 if (size.max_width == 16) {
2448 return new Size(16, 16);
2451 if (size.min_width < 16 && size.max_width > 16) {
2454 // check if we can fit one
2456 while (x < size.max_width) {
2457 x += size.width_inc;
2460 return new Size(16, 16);
2465 if (smallest == 0 || smallest > size.min_width) {
2466 smallest = size.min_width;
2470 // We didn't find a match or we wouldn't be here
2471 return new Size(smallest, smallest);
2474 return new Size(16, 16);
2479 internal override int MouseButtonCount {
2485 internal override bool MouseButtonsSwapped {
2487 return false; // FIXME - how to detect?
2491 internal override Point MousePosition {
2493 return mouse_position;
2497 internal override Size MouseHoverSize {
2499 return new Size (1, 1);
2503 internal override int MouseHoverTime {
2505 return HoverState.Interval;
2511 internal override bool MouseWheelPresent {
2513 return true; // FIXME - how to detect?
2517 internal override MouseButtons MouseButtons {
2523 internal override Rectangle VirtualScreen {
2529 IntPtr prop = IntPtr.Zero;
2533 XGetWindowProperty(DisplayHandle, RootWindow, _NET_DESKTOP_GEOMETRY, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2534 if ((long)nitems < 2)
2537 width = Marshal.ReadIntPtr(prop, 0).ToInt32();
2538 height = Marshal.ReadIntPtr(prop, IntPtr.Size).ToInt32();
2542 return new Rectangle(0, 0, width, height);
2545 XWindowAttributes attributes=new XWindowAttributes();
2548 XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
2551 return new Rectangle(0, 0, attributes.width, attributes.height);
2555 internal override Rectangle WorkingArea {
2561 IntPtr prop = IntPtr.Zero;
2564 int current_desktop;
2568 XGetWindowProperty(DisplayHandle, RootWindow, _NET_CURRENT_DESKTOP, IntPtr.Zero, new IntPtr(1), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2569 if ((long)nitems < 1) {
2573 current_desktop = Marshal.ReadIntPtr(prop, 0).ToInt32();
2576 XGetWindowProperty(DisplayHandle, RootWindow, _NET_WORKAREA, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2577 if ((long)nitems < 4 * (current_desktop + 1)) {
2581 x = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop).ToInt32();
2582 y = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size).ToInt32();
2583 width = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size * 2).ToInt32();
2584 height = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size * 3).ToInt32();
2587 return new Rectangle(x, y, width, height);
2590 XWindowAttributes attributes=new XWindowAttributes();
2593 XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
2596 return new Rectangle(0, 0, attributes.width, attributes.height);
2600 internal override Screen[] AllScreens {
2602 if (!XineramaIsActive (DisplayHandle))
2605 IntPtr xineramaScreens = XineramaQueryScreens (DisplayHandle, out nScreens);
2606 var screens = new Screen [nScreens];
2607 IntPtr current = xineramaScreens;
2608 for (int i = 0; i < nScreens; i++) {
2609 var screen = (XineramaScreenInfo)Marshal.PtrToStructure (current,
2610 typeof (XineramaScreenInfo));
2611 var screenRect = new Rectangle (screen.x_org, screen.y_org, screen.width,
2613 var name = string.Format ("Display {0}", screen.screen_number);
2614 screens [i] = new Screen (i == 0, name, screenRect, screenRect);
2615 current = (IntPtr)( (ulong)current + (ulong)Marshal.SizeOf(typeof (XineramaScreenInfo)));
2617 XFree (xineramaScreens);
2622 internal override bool ThemesEnabled {
2624 return XplatUIX11.themes_enabled;
2629 #endregion // Public properties
2631 #region Public Static Methods
2632 internal override void RaiseIdle (EventArgs e)
2638 internal override IntPtr InitializeDriver()
2641 if (DisplayHandle==IntPtr.Zero) {
2642 SetDisplay(XOpenDisplay(IntPtr.Zero));
2648 internal override void ShutdownDriver(IntPtr token)
2651 if (DisplayHandle!=IntPtr.Zero) {
2652 XCloseDisplay(DisplayHandle);
2653 DisplayHandle=IntPtr.Zero;
2658 internal override void EnableThemes()
2660 themes_enabled = true;
2664 internal override void Activate(IntPtr handle)
2668 hwnd = Hwnd.ObjectFromHandle(handle);
2672 if (true /* the window manager supports NET_ACTIVE_WINDOW */) {
2673 SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
2674 XEventQueue q = null;
2675 lock (unattached_timer_list) {
2676 foreach (Timer t in unattached_timer_list) {
2678 q= (XEventQueue) MessageQueues [Thread.CurrentThread];
2679 t.thread = q.Thread;
2680 q.timer_list.Add (t);
2682 unattached_timer_list.Clear ();
2686 // XRaiseWindow(DisplayHandle, handle);
2692 internal override void AudibleAlert(AlertType alert)
2694 XBell(DisplayHandle, 0);
2699 internal override void CaretVisible(IntPtr handle, bool visible)
2701 if (Caret.Hwnd == handle) {
2703 if (!Caret.Visible) {
2704 Caret.Visible = true;
2706 Caret.Timer.Start();
2709 Caret.Visible = false;
2716 internal override bool CalculateWindowRect(ref Rectangle ClientRect, CreateParams cp, Menu menu, out Rectangle WindowRect)
2718 WindowRect = Hwnd.GetWindowRectangle (cp, menu, ClientRect);
2722 internal override void ClientToScreen(IntPtr handle, ref int x, ref int y)
2729 hwnd = Hwnd.ObjectFromHandle(handle);
2732 XTranslateCoordinates(DisplayHandle, hwnd.client_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
2739 internal override int[] ClipboardAvailableFormats(IntPtr handle)
2741 DataFormats.Format f;
2744 f = DataFormats.Format.List;
2746 if (XGetSelectionOwner(DisplayHandle, CLIPBOARD) == IntPtr.Zero) {
2750 Clipboard.Formats = new ArrayList();
2753 XConvertSelection(DisplayHandle, CLIPBOARD, (IntPtr)f.Id, (IntPtr)f.Id, FosterParent, IntPtr.Zero);
2755 var timeToWaitForSelectionFormats = TimeSpan.FromSeconds(4);
2756 var startTime = DateTime.Now;
2757 Clipboard.Enumerating = true;
2758 while (Clipboard.Enumerating) {
2759 UpdateMessageQueue(null, false);
2761 if (DateTime.Now - startTime > timeToWaitForSelectionFormats)
2767 result = new int[Clipboard.Formats.Count];
2769 for (int i = 0; i < Clipboard.Formats.Count; i++) {
2770 result[i] = ((IntPtr)Clipboard.Formats[i]).ToInt32 ();
2773 Clipboard.Formats = null;
2777 internal override void ClipboardClose(IntPtr handle)
2779 if (handle != ClipMagic) {
2780 throw new ArgumentException("handle is not a valid clipboard handle");
2785 internal override int ClipboardGetID(IntPtr handle, string format)
2787 if (handle != ClipMagic) {
2788 throw new ArgumentException("handle is not a valid clipboard handle");
2791 if (format == "Text" ) return (int)Atom.XA_STRING;
2792 else if (format == "Bitmap" ) return (int)Atom.XA_BITMAP;
2793 //else if (format == "MetaFilePict" ) return 3;
2794 //else if (format == "SymbolicLink" ) return 4;
2795 //else if (format == "DataInterchangeFormat" ) return 5;
2796 //else if (format == "Tiff" ) return 6;
2797 else if (format == "OEMText" ) return OEMTEXT.ToInt32();
2798 else if (format == "DeviceIndependentBitmap" ) return (int)Atom.XA_PIXMAP;
2799 else if (format == "Palette" ) return (int)Atom.XA_COLORMAP; // Useless
2800 //else if (format == "PenData" ) return 10;
2801 //else if (format == "RiffAudio" ) return 11;
2802 //else if (format == "WaveAudio" ) return 12;
2803 else if (format == "UnicodeText" ) return UTF16_STRING.ToInt32();
2804 //else if (format == "EnhancedMetafile" ) return 14;
2805 //else if (format == "FileDrop" ) return 15;
2806 //else if (format == "Locale" ) return 16;
2807 else if (format == "Rich Text Format") return RICHTEXTFORMAT.ToInt32 ();
2809 return XInternAtom(DisplayHandle, format, false).ToInt32();
2812 internal override IntPtr ClipboardOpen(bool primary_selection)
2814 if (!primary_selection)
2815 ClipMagic = CLIPBOARD;
2817 ClipMagic = PRIMARY;
2821 internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter)
2823 XConvertSelection(DisplayHandle, handle, (IntPtr)type, (IntPtr)type, FosterParent, IntPtr.Zero);
2825 Clipboard.Retrieving = true;
2826 while (Clipboard.Retrieving) {
2827 UpdateMessageQueue(null, false);
2830 return Clipboard.Item;
2833 internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter, bool copy)
2835 Clipboard.Converter = converter;
2838 Clipboard.AddSource (type, obj);
2839 XSetSelectionOwner (DisplayHandle, CLIPBOARD, FosterParent, IntPtr.Zero);
2843 var clipboardAtom = gdk_atom_intern ("CLIPBOARD", true);
2844 var clipboard = gtk_clipboard_get (clipboardAtom);
2845 if (clipboard != IntPtr.Zero) {
2846 // for now we only store text
2847 var text = Clipboard.GetRtfText ();
2848 if (string.IsNullOrEmpty (text))
2849 text = Clipboard.GetPlainText ();
2850 if (!string.IsNullOrEmpty (text)) {
2851 gtk_clipboard_set_text (clipboard, text, text.Length);
2852 gtk_clipboard_store (clipboard);
2856 // ignore any errors - most likely because gtk isn't installed?
2860 // Clearing the selection
2861 Clipboard.ClearSources ();
2862 XSetSelectionOwner (DisplayHandle, CLIPBOARD, IntPtr.Zero, IntPtr.Zero);
2866 internal override void CreateCaret (IntPtr handle, int width, int height)
2868 XGCValues gc_values;
2871 hwnd = Hwnd.ObjectFromHandle(handle);
2873 if (Caret.Hwnd != IntPtr.Zero) {
2874 DestroyCaret(Caret.Hwnd);
2877 Caret.Hwnd = handle;
2878 Caret.Window = hwnd.client_window;
2879 Caret.Width = width;
2880 Caret.Height = height;
2881 Caret.Visible = false;
2884 gc_values = new XGCValues();
2885 gc_values.line_width = width;
2887 Caret.gc = XCreateGC(DisplayHandle, Caret.Window, new IntPtr ((int)GCFunction.GCLineWidth), ref gc_values);
2888 if (Caret.gc == IntPtr.Zero) {
2889 Caret.Hwnd = IntPtr.Zero;
2893 XSetFunction(DisplayHandle, Caret.gc, GXFunction.GXinvert);
2896 internal override IntPtr CreateWindow (CreateParams cp)
2898 XSetWindowAttributes Attributes;
2900 Hwnd parent_hwnd = null;
2905 IntPtr ParentHandle;
2907 IntPtr ClientWindow;
2908 SetWindowValuemask ValueMask;
2913 Attributes = new XSetWindowAttributes();
2919 if (Width<1) Width=1;
2920 if (Height<1) Height=1;
2922 if (cp.Parent != IntPtr.Zero) {
2923 parent_hwnd = Hwnd.ObjectFromHandle(cp.Parent);
2924 ParentHandle = parent_hwnd.client_window;
2926 if (StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
2927 // We need to use our foster parent window until this poor child gets it's parent assigned
2928 ParentHandle=FosterParent;
2930 ParentHandle=RootWindow;
2934 // Set the default location location for forms.
2936 if (cp.control is Form) {
2937 next = Hwnd.GetNextStackedFormLocation (cp, parent_hwnd);
2941 ValueMask = SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
2943 Attributes.bit_gravity = Gravity.NorthWestGravity;
2944 Attributes.win_gravity = Gravity.NorthWestGravity;
2946 // Save what's under the toolwindow
2947 if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
2948 Attributes.save_under = true;
2949 ValueMask |= SetWindowValuemask.SaveUnder;
2953 // If we're a popup without caption we override the WM
2954 if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && !StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
2955 Attributes.override_redirect = true;
2956 ValueMask |= SetWindowValuemask.OverrideRedirect;
2962 hwnd.height = Height;
2963 hwnd.parent = Hwnd.ObjectFromHandle(cp.Parent);
2964 hwnd.initial_style = cp.WindowStyle;
2965 hwnd.initial_ex_style = cp.WindowExStyle;
2967 if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
2968 hwnd.enabled = false;
2971 ClientWindow = IntPtr.Zero;
2973 Size XWindowSize = TranslateWindowSizeToXWindowSize (cp);
2974 Rectangle XClientRect = TranslateClientRectangleToXClientRectangle (hwnd, cp.control);
2977 WholeWindow = XCreateWindow(DisplayHandle, ParentHandle, X, Y, XWindowSize.Width, XWindowSize.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, IntPtr.Zero, new UIntPtr ((uint)ValueMask), ref Attributes);
2978 if (WholeWindow != IntPtr.Zero) {
2979 ValueMask &= ~(SetWindowValuemask.OverrideRedirect | SetWindowValuemask.SaveUnder);
2981 if (CustomVisual != IntPtr.Zero && CustomColormap != IntPtr.Zero) {
2982 ValueMask = SetWindowValuemask.ColorMap;
2983 Attributes.colormap = CustomColormap;
2985 ClientWindow = XCreateWindow(DisplayHandle, WholeWindow, XClientRect.X, XClientRect.Y, XClientRect.Width, XClientRect.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, CustomVisual, new UIntPtr ((uint)ValueMask), ref Attributes);
2989 if ((WholeWindow == IntPtr.Zero) || (ClientWindow == IntPtr.Zero)) {
2990 throw new Exception("Could not create X11 windows");
2993 hwnd.Queue = ThreadQueue(Thread.CurrentThread);
2994 hwnd.WholeWindow = WholeWindow;
2995 hwnd.ClientWindow = ClientWindow;
2997 DriverDebug("Created window {0:X} / {1:X} parent {2:X}, Style {3}, ExStyle {4}", ClientWindow.ToInt32(), WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0, (WindowStyles)cp.Style, (WindowExStyles)cp.ExStyle);
2999 if (!StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
3000 if ((X != unchecked((int)0x80000000)) && (Y != unchecked((int)0x80000000))) {
3003 hints = new XSizeHints();
3006 hints.flags = (IntPtr)(XSizeHintsFlags.USPosition | XSizeHintsFlags.PPosition);
3007 XSetWMNormalHints(DisplayHandle, WholeWindow, ref hints);
3012 XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
3013 if (hwnd.whole_window != hwnd.client_window)
3014 XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | Keyboard.KeyEventMask)));
3017 if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST))
3018 SetTopmost(hwnd.whole_window, true);
3020 SetWMStyles(hwnd, cp);
3022 // set the group leader
3023 XWMHints wm_hints = new XWMHints ();
3025 wm_hints.flags = (IntPtr)(XWMHintsFlags.InputHint | XWMHintsFlags.StateHint | XWMHintsFlags.WindowGroupHint);
3026 wm_hints.input = !StyleSet (cp.Style, WindowStyles.WS_DISABLED);
3027 wm_hints.initial_state = StyleSet (cp.Style, WindowStyles.WS_MINIMIZE) ? XInitialState.IconicState : XInitialState.NormalState;
3029 if (ParentHandle != RootWindow) {
3030 wm_hints.window_group = hwnd.whole_window;
3032 wm_hints.window_group = ParentHandle;
3036 XSetWMHints(DisplayHandle, hwnd.whole_window, ref wm_hints );
3039 if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZE)) {
3040 SetWindowState(hwnd.Handle, FormWindowState.Minimized);
3041 } else if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZE)) {
3042 SetWindowState(hwnd.Handle, FormWindowState.Maximized);
3045 // for now make all windows dnd enabled
3046 Dnd.SetAllowDrop (hwnd, true);
3048 // Set caption/window title
3049 Text(hwnd.Handle, cp.Caption);
3051 SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1, IntPtr.Zero /* XXX unused */);
3052 SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);
3054 if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
3055 hwnd.visible = true;
3056 MapWindow(hwnd, WindowType.Both);
3057 if (!(Control.FromHandle(hwnd.Handle) is Form))
3058 SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
3064 internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height)
3066 CreateParams create_params = new CreateParams();
3068 create_params.Caption = "";
3069 create_params.X = X;
3070 create_params.Y = Y;
3071 create_params.Width = Width;
3072 create_params.Height = Height;
3074 create_params.ClassName=XplatUI.GetDefaultClassName (GetType ());
3075 create_params.ClassStyle = 0;
3076 create_params.ExStyle=0;
3077 create_params.Parent=IntPtr.Zero;
3078 create_params.Param=0;
3080 return CreateWindow(create_params);
3083 internal override IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot)
3086 Bitmap cursor_bitmap;
3094 IntPtr cursor_pixmap;
3101 if (XQueryBestCursor(DisplayHandle, RootWindow, bitmap.Width, bitmap.Height, out width, out height) == 0) {
3105 // Win32 only allows creation cursors of a certain size
3106 if ((bitmap.Width != width) || (bitmap.Width != height)) {
3107 cursor_bitmap = new Bitmap(bitmap, new Size(width, height));
3108 cursor_mask = new Bitmap(mask, new Size(width, height));
3110 cursor_bitmap = bitmap;
3114 width = cursor_bitmap.Width;
3115 height = cursor_bitmap.Height;
3117 cursor_bits = new Byte[(width / 8) * height];
3118 mask_bits = new Byte[(width / 8) * height];
3120 for (int y = 0; y < height; y++) {
3121 for (int x = 0; x < width; x++) {
3122 c_pixel = cursor_bitmap.GetPixel(x, y);
3123 m_pixel = cursor_mask.GetPixel(x, y);
3125 and = c_pixel == cursor_pixel;
3126 xor = m_pixel == mask_pixel;
3130 // cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8))); // The bit already is 0
3131 mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
3132 } else if (and && !xor) {
3134 cursor_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
3135 mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
3137 } else if (and && !xor) {
3139 } else if (and && xor) {
3142 // X11 doesn't know the 'reverse screen' concept, so we'll treat them the same
3143 // we want both to be 0 so nothing to be done
3144 //cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));
3145 //mask_bits[y * width / 8 + x / 8] |= (byte)(01 << (x % 8));
3151 cursor_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, cursor_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
3152 mask_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, mask_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
3156 fg.pixel = XWhitePixel(DisplayHandle, ScreenNo);
3157 fg.red = (ushort)65535;
3158 fg.green = (ushort)65535;
3159 fg.blue = (ushort)65535;
3161 bg.pixel = XBlackPixel(DisplayHandle, ScreenNo);
3163 cursor = XCreatePixmapCursor(DisplayHandle, cursor_pixmap, mask_pixmap, ref fg, ref bg, xHotSpot, yHotSpot);
3165 XFreePixmap(DisplayHandle, cursor_pixmap);
3166 XFreePixmap(DisplayHandle, mask_pixmap);
3171 internal override Bitmap DefineStdCursorBitmap (StdCursor id)
3173 CursorFontShape shape;
3180 shape = StdCursorToFontShape (id);
3181 name = shape.ToString ().Replace ("XC_", string.Empty);
3182 size = XcursorGetDefaultSize (DisplayHandle);
3183 theme = XcursorGetTheme (DisplayHandle);
3184 IntPtr images_ptr = XcursorLibraryLoadImages (name, theme, size);
3185 DriverDebug ("DefineStdCursorBitmap, id={0}, #id={1}, name{2}, size={3}, theme: {4}, images_ptr={5}", id, (int) id, name, size, Marshal.PtrToStringAnsi (theme), images_ptr);
3187 if (images_ptr == IntPtr.Zero) {
3191 XcursorImages images = (XcursorImages) Marshal.PtrToStructure (images_ptr, typeof (XcursorImages));
3192 DriverDebug ("DefineStdCursorBitmap, cursor has {0} images", images.nimage);
3194 if (images.nimage > 0) {
3195 // We only care about the first image.
3196 XcursorImage image = (XcursorImage)Marshal.PtrToStructure (Marshal.ReadIntPtr (images.images), typeof (XcursorImage));
3198 DriverDebug ("DefineStdCursorBitmap, loaded image <size={0}, height={1}, width={2}, xhot={3}, yhot={4}, pixels={5}", image.size, image.height, image.width, image.xhot, image.yhot, image.pixels);
3200 if (image.width <= short.MaxValue && image.height <= short.MaxValue) {
3201 int [] pixels = new int [image.width * image.height];
3202 Marshal.Copy (image.pixels, pixels, 0, pixels.Length);
3203 bmp = new Bitmap (image.width, image.height);
3204 for (int w = 0; w < image.width; w++) {
3205 for (int h = 0; h < image.height; h++) {
3206 bmp.SetPixel (w, h, Color.FromArgb (pixels [h * image.width + w]));
3212 XcursorImagesDestroy (images_ptr);
3214 } catch (DllNotFoundException ex) {
3215 Console.WriteLine ("Could not load libXcursor: " + ex.Message + " (" + ex.GetType ().Name + ")");
3223 internal override IntPtr DefineStdCursor(StdCursor id)
3225 CursorFontShape shape;
3228 shape = StdCursorToFontShape (id);
3231 cursor = XCreateFontCursor(DisplayHandle, shape);
3236 internal static CursorFontShape StdCursorToFontShape (StdCursor id)
3238 CursorFontShape shape;
3239 // FIXME - define missing shapes
3242 case StdCursor.AppStarting: {
3243 shape = CursorFontShape.XC_watch;
3247 case StdCursor.Arrow: {
3248 shape = CursorFontShape.XC_top_left_arrow;
3252 case StdCursor.Cross: {
3253 shape = CursorFontShape.XC_crosshair;
3257 case StdCursor.Default: {
3258 shape = CursorFontShape.XC_top_left_arrow;
3262 case StdCursor.Hand: {
3263 shape = CursorFontShape.XC_hand1;
3267 case StdCursor.Help: {
3268 shape = CursorFontShape.XC_question_arrow;
3272 case StdCursor.HSplit: {
3273 shape = CursorFontShape.XC_sb_v_double_arrow;
3277 case StdCursor.IBeam: {
3278 shape = CursorFontShape.XC_xterm;
3282 case StdCursor.No: {
3283 shape = CursorFontShape.XC_circle;
3287 case StdCursor.NoMove2D: {
3288 shape = CursorFontShape.XC_fleur;
3292 case StdCursor.NoMoveHoriz: {
3293 shape = CursorFontShape.XC_fleur;
3297 case StdCursor.NoMoveVert: {
3298 shape = CursorFontShape.XC_fleur;
3302 case StdCursor.PanEast: {
3303 shape = CursorFontShape.XC_fleur;
3307 case StdCursor.PanNE: {
3308 shape = CursorFontShape.XC_fleur;
3312 case StdCursor.PanNorth: {
3313 shape = CursorFontShape.XC_fleur;
3317 case StdCursor.PanNW: {
3318 shape = CursorFontShape.XC_fleur;
3322 case StdCursor.PanSE: {
3323 shape = CursorFontShape.XC_fleur;
3327 case StdCursor.PanSouth: {
3328 shape = CursorFontShape.XC_fleur;
3332 case StdCursor.PanSW: {
3333 shape = CursorFontShape.XC_fleur;
3337 case StdCursor.PanWest: {
3338 shape = CursorFontShape.XC_sizing;
3342 case StdCursor.SizeAll: {
3343 shape = CursorFontShape.XC_fleur;
3347 case StdCursor.SizeNESW: {
3348 shape = CursorFontShape.XC_top_right_corner;
3352 case StdCursor.SizeNS: {
3353 shape = CursorFontShape.XC_sb_v_double_arrow;
3357 case StdCursor.SizeNWSE: {
3358 shape = CursorFontShape.XC_top_left_corner;
3362 case StdCursor.SizeWE: {
3363 shape = CursorFontShape.XC_sb_h_double_arrow;
3367 case StdCursor.UpArrow: {
3368 shape = CursorFontShape.XC_center_ptr;
3372 case StdCursor.VSplit: {
3373 shape = CursorFontShape.XC_sb_h_double_arrow;
3377 case StdCursor.WaitCursor: {
3378 shape = CursorFontShape.XC_watch;
3383 shape = (CursorFontShape) 0;
3391 internal override IntPtr DefWndProc(ref Message msg)
3393 switch ((Msg)msg.Msg) {
3395 case Msg.WM_IME_COMPOSITION:
3396 string s = Keyboard.GetCompositionString ();
3397 foreach (char c in s)
3398 SendMessage (msg.HWnd, Msg.WM_IME_CHAR, (IntPtr) c, msg.LParam);
3401 case Msg.WM_IME_CHAR:
3402 // On Windows API it sends two WM_CHAR messages for each byte, but
3403 // I wonder if it is worthy to emulate it (also no idea how to
3404 // reconstruct those bytes into chars).
3405 SendMessage (msg.HWnd, Msg.WM_CHAR, msg.WParam, msg.LParam);
3408 case Msg.WM_PAINT: {
3411 hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3413 hwnd.expose_pending = false;
3419 case Msg.WM_NCPAINT: {
3422 hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3424 hwnd.nc_expose_pending = false;
3430 case Msg.WM_NCCALCSIZE: {
3433 if (msg.WParam == (IntPtr)1) {
3434 hwnd = Hwnd.GetObjectFromWindow (msg.HWnd);
3436 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
3437 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (msg.LParam, typeof (XplatUIWin32.NCCALCSIZE_PARAMS));
3439 // Add all the stuff X is supposed to draw.
3440 Control ctrl = Control.FromHandle (hwnd.Handle);
3443 Hwnd.Borders rect = Hwnd.GetBorders (ctrl.GetCreateParams (), null);
3445 ncp.rgrc1.top += rect.top;
3446 ncp.rgrc1.bottom -= rect.bottom;
3447 ncp.rgrc1.left += rect.left;
3448 ncp.rgrc1.right -= rect.right;
3450 Marshal.StructureToPtr (ncp, msg.LParam, true);
3457 case Msg.WM_CONTEXTMENU: {
3460 hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3462 if ((hwnd != null) && (hwnd.parent != null)) {
3463 SendMessage(hwnd.parent.client_window, Msg.WM_CONTEXTMENU, msg.WParam, msg.LParam);
3468 case Msg.WM_MOUSEWHEEL: {
3471 hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3473 if ((hwnd != null) && (hwnd.parent != null)) {
3474 SendMessage(hwnd.parent.client_window, Msg.WM_MOUSEWHEEL, msg.WParam, msg.LParam);
3475 if (msg.Result == IntPtr.Zero) {
3482 case Msg.WM_SETCURSOR: {
3485 hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3487 break; // not sure how this happens, but it does
3489 // Pass to parent window first
3490 while ((hwnd.parent != null) && (msg.Result == IntPtr.Zero)) {
3492 msg.Result = NativeWindow.WndProc(hwnd.Handle, Msg.WM_SETCURSOR, msg.HWnd, msg.LParam);
3495 if (msg.Result == IntPtr.Zero) {
3498 switch((HitTest)(msg.LParam.ToInt32() & 0xffff)) {
3499 case HitTest.HTBOTTOM: handle = Cursors.SizeNS.handle; break;
3500 case HitTest.HTBORDER: handle = Cursors.SizeNS.handle; break;
3501 case HitTest.HTBOTTOMLEFT: handle = Cursors.SizeNESW.handle; break;
3502 case HitTest.HTBOTTOMRIGHT: handle = Cursors.SizeNWSE.handle; break;
3503 case HitTest.HTERROR: if ((msg.LParam.ToInt32() >> 16) == (int)Msg.WM_LBUTTONDOWN) {
3504 AudibleAlert(AlertType.Default);
3506 handle = Cursors.Default.handle;
3509 case HitTest.HTHELP: handle = Cursors.Help.handle; break;
3510 case HitTest.HTLEFT: handle = Cursors.SizeWE.handle; break;
3511 case HitTest.HTRIGHT: handle = Cursors.SizeWE.handle; break;
3512 case HitTest.HTTOP: handle = Cursors.SizeNS.handle; break;
3513 case HitTest.HTTOPLEFT: handle = Cursors.SizeNWSE.handle; break;
3514 case HitTest.HTTOPRIGHT: handle = Cursors.SizeNESW.handle; break;
3517 case HitTest.HTGROWBOX:
3518 case HitTest.HTSIZE:
3519 case HitTest.HTZOOM:
3520 case HitTest.HTVSCROLL:
3521 case HitTest.HTSYSMENU:
3522 case HitTest.HTREDUCE:
3523 case HitTest.HTNOWHERE:
3524 case HitTest.HTMAXBUTTON:
3525 case HitTest.HTMINBUTTON:
3526 case HitTest.HTMENU:
3527 case HitTest.HSCROLL:
3528 case HitTest.HTBOTTOM:
3529 case HitTest.HTCAPTION:
3530 case HitTest.HTCLIENT:
3531 case HitTest.HTCLOSE:
3533 default: handle = Cursors.Default.handle; break;
3535 SetCursor(msg.HWnd, handle);
3543 internal override void DestroyCaret(IntPtr handle)
3545 if (Caret.Hwnd == handle) {
3546 if (Caret.Visible) {
3550 if (Caret.gc != IntPtr.Zero) {
3551 XFreeGC(DisplayHandle, Caret.gc);
3552 Caret.gc = IntPtr.Zero;
3554 Caret.Hwnd = IntPtr.Zero;
3555 Caret.Visible = false;
3560 internal override void DestroyCursor(IntPtr cursor)
3563 XFreeCursor(DisplayHandle, cursor);
3567 internal override void DestroyWindow(IntPtr handle)
3570 hwnd = Hwnd.ObjectFromHandle(handle);
3572 // The window should never ever be a zombie here, since we should
3573 // wait until it's completely dead before returning from
3574 // "destroying" calls, but just in case....
3575 if (hwnd == null || hwnd.zombie) {
3576 DriverDebug ("window {0:X} already destroyed", handle.ToInt32());
3580 DriverDebug ("Destroying window {0}", XplatUI.Window(hwnd.client_window));
3582 SendParentNotify (hwnd.Handle, Msg.WM_DESTROY, int.MaxValue, int.MaxValue);
3584 CleanupCachedWindows (hwnd);
3586 ArrayList windows = new ArrayList ();
3588 AccumulateDestroyedHandles (Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle), windows);
3591 foreach (Hwnd h in windows) {
3592 SendMessage (h.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
3597 if (hwnd.whole_window != IntPtr.Zero) {
3598 DriverDebug ("XDestroyWindow (whole_window = {0:X})", hwnd.whole_window.ToInt32());
3599 Keyboard.DestroyICForWindow (hwnd.whole_window);
3600 XDestroyWindow(DisplayHandle, hwnd.whole_window);
3602 else if (hwnd.client_window != IntPtr.Zero) {
3603 DriverDebug ("XDestroyWindow (client_window = {0:X})", hwnd.client_window.ToInt32());
3604 Keyboard.DestroyICForWindow (hwnd.client_window);
3605 XDestroyWindow(DisplayHandle, hwnd.client_window);
3611 internal override IntPtr DispatchMessage(ref MSG msg)
3613 return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
3616 IntPtr GetReversibleScreenGC (Color backColor)
3618 XGCValues gc_values;
3622 XColor xcolor = new XColor();
3623 xcolor.red = (ushort)(backColor.R * 257);
3624 xcolor.green = (ushort)(backColor.G * 257);
3625 xcolor.blue = (ushort)(backColor.B * 257);
3626 XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3627 pixel = (uint)xcolor.pixel.ToInt32();
3630 gc_values = new XGCValues();
3632 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
3633 gc_values.foreground = (IntPtr)pixel;
3635 gc = XCreateGC(DisplayHandle, RootWindow, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCForeground)), ref gc_values);
3636 XSetForeground(DisplayHandle, gc, (UIntPtr)pixel);
3637 XSetFunction(DisplayHandle, gc, GXFunction.GXxor);
3642 IntPtr GetReversibleControlGC (Control control, int line_width)
3644 XGCValues gc_values;
3647 gc_values = new XGCValues();
3649 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
3650 gc_values.line_width = line_width;
3651 gc_values.foreground = XBlackPixel(DisplayHandle, ScreenNo);
3653 // This logic will give us true rubber bands: (libsx, SANE_XOR)
3654 //mask = foreground ^ background;
3655 //XSetForeground(DisplayHandle, gc, 0xffffffff);
3656 //XSetBackground(DisplayHandle, gc, background);
3657 //XSetFunction(DisplayHandle, gc, GXxor);
3658 //XSetPlaneMask(DisplayHandle, gc, mask);
3661 gc = XCreateGC(DisplayHandle, control.Handle, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground)), ref gc_values);
3665 XColor xcolor = new XColor();
3667 xcolor.red = (ushort)(control.ForeColor.R * 257);
3668 xcolor.green = (ushort)(control.ForeColor.G * 257);
3669 xcolor.blue = (ushort)(control.ForeColor.B * 257);
3670 XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3671 foreground = (uint)xcolor.pixel.ToInt32();
3673 xcolor.red = (ushort)(control.BackColor.R * 257);
3674 xcolor.green = (ushort)(control.BackColor.G * 257);
3675 xcolor.blue = (ushort)(control.BackColor.B * 257);
3676 XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3677 background = (uint)xcolor.pixel.ToInt32();
3679 uint mask = foreground ^ background;
3681 XSetForeground(DisplayHandle, gc, (UIntPtr)0xffffffff);
3682 XSetBackground(DisplayHandle, gc, (UIntPtr)background);
3683 XSetFunction(DisplayHandle, gc, GXFunction.GXxor);
3684 XSetPlaneMask(DisplayHandle, gc, (IntPtr)mask);
3689 internal override void DrawReversibleLine(Point start, Point end, Color backColor)
3691 if (backColor.GetBrightness() < 0.5)
3692 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3694 IntPtr gc = GetReversibleScreenGC (backColor);
3696 XDrawLine (DisplayHandle, RootWindow, gc, start.X, start.Y, end.X, end.Y);
3698 XFreeGC(DisplayHandle, gc);
3701 internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style)
3703 if (backColor.GetBrightness() < 0.5)
3704 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3706 IntPtr gc = GetReversibleScreenGC (backColor);
3708 if (rectangle.Width < 0) {
3709 rectangle.X += rectangle.Width;
3710 rectangle.Width = -rectangle.Width;
3712 if (rectangle.Height < 0) {
3713 rectangle.Y += rectangle.Height;
3714 rectangle.Height = -rectangle.Height;
3718 GCLineStyle line_style = GCLineStyle.LineSolid;
3719 GCCapStyle cap_style = GCCapStyle.CapButt;
3720 GCJoinStyle join_style = GCJoinStyle.JoinMiter;
3723 case FrameStyle.Dashed:
3724 line_style = GCLineStyle.LineOnOffDash;
3726 case FrameStyle.Thick:
3731 XSetLineAttributes (DisplayHandle, gc, line_width, line_style, cap_style, join_style);
3733 XDrawRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
3735 XFreeGC(DisplayHandle, gc);
3738 internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor)
3740 if (backColor.GetBrightness() < 0.5)
3741 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3743 IntPtr gc = GetReversibleScreenGC (backColor);
3745 if (rectangle.Width < 0) {
3746 rectangle.X += rectangle.Width;
3747 rectangle.Width = -rectangle.Width;
3749 if (rectangle.Height < 0) {
3750 rectangle.Y += rectangle.Height;
3751 rectangle.Height = -rectangle.Height;
3753 XFillRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
3755 XFreeGC(DisplayHandle, gc);
3758 internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width)
3761 Control control = Control.FromHandle(handle);
3763 gc = GetReversibleControlGC (control, line_width);
3765 if ((rect.Width > 0) && (rect.Height > 0)) {
3766 XDrawRectangle(DisplayHandle, control.Handle, gc, rect.Left, rect.Top, rect.Width, rect.Height);
3768 if (rect.Width > 0) {
3769 XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.Right, rect.Y);
3771 XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.X, rect.Bottom);
3774 XFreeGC(DisplayHandle, gc);
3777 internal override void DoEvents()
3779 DebugHelper.Enter ();
3781 MSG msg = new MSG ();
3784 if (OverrideCursorHandle != IntPtr.Zero) {
3785 OverrideCursorHandle = IntPtr.Zero;
3788 queue = ThreadQueue(Thread.CurrentThread);
3790 queue.DispatchIdle = false;
3793 while (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
3794 Message m = Message.Create (msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);
3796 if (Application.FilterMessage (ref m))
3799 TranslateMessage (ref msg);
3800 DispatchMessage (ref msg);
3802 string key = msg.hwnd + ":" + msg.message;
3803 if (messageHold[key] != null) {
3804 messageHold[key] = ((int)messageHold[key]) - 1;
3805 DebugHelper.WriteLine ("Got " + msg + " for " + key);
3809 in_doevents = false;
3810 queue.DispatchIdle = true;
3812 DebugHelper.Leave ();
3815 internal override void EnableWindow(IntPtr handle, bool Enable)
3819 hwnd = Hwnd.ObjectFromHandle(handle);
3821 hwnd.Enabled = Enable;
3825 internal override void EndLoop(Thread thread)
3827 // This is where we one day will shut down the loop for the thread
3830 internal override IntPtr GetActive()
3836 IntPtr prop = IntPtr.Zero;
3837 IntPtr active = IntPtr.Zero;
3839 XGetWindowProperty(DisplayHandle, RootWindow, _NET_ACTIVE_WINDOW, IntPtr.Zero, new IntPtr (1), false, (IntPtr)Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
3840 if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
3841 active = (IntPtr)Marshal.ReadInt32(prop);
3844 // The window manager does not support _NET_ACTIVE_WINDOW. Fall back to XGetInputFocus.
3845 IntPtr revert_to = IntPtr.Zero;
3846 XGetInputFocus(DisplayHandle, out active, out revert_to);
3849 if (active != IntPtr.Zero) {
3852 hwnd = Hwnd.GetObjectFromWindow(active);
3854 active = hwnd.Handle;
3856 active = IntPtr.Zero;
3862 internal override Region GetClipRegion(IntPtr handle)
3866 hwnd = Hwnd.ObjectFromHandle(handle);
3868 return hwnd.UserClip;
3874 internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y)
3882 internal override void GetDisplaySize(out Size size)
3884 XWindowAttributes attributes=new XWindowAttributes();
3887 // FIXME - use _NET_WM messages instead?
3888 XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
3891 size = new Size(attributes.width, attributes.height);
3894 internal override SizeF GetAutoScaleSize(Font font)
3898 string magic_string = "The quick brown fox jumped over the lazy dog.";
3899 double magic_number = 44.549996948242189;
3901 g = Graphics.FromHwnd(FosterParent);
3903 width = (float) (g.MeasureString (magic_string, font).Width / magic_number);
3904 return new SizeF(width, font.Height);
3907 internal override IntPtr GetParent(IntPtr handle)
3911 hwnd = Hwnd.ObjectFromHandle(handle);
3912 if (hwnd != null && hwnd.parent != null) {
3913 return hwnd.parent.Handle;
3918 // This is a nop on win32 and x11
3919 internal override IntPtr GetPreviousWindow(IntPtr handle)
3924 internal override void GetCursorPos(IntPtr handle, out int x, out int y)
3935 if (handle != IntPtr.Zero) {
3936 use_handle = Hwnd.ObjectFromHandle(handle).client_window;
3938 use_handle = RootWindow;
3942 QueryPointer (DisplayHandle, use_handle, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
3945 if (handle != IntPtr.Zero) {
3954 internal override IntPtr GetFocus()
3960 internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent)
3962 FontFamily ff = font.FontFamily;
3963 ascent = ff.GetCellAscent (font.Style);
3964 descent = ff.GetCellDescent (font.Style);
3968 internal override Point GetMenuOrigin(IntPtr handle)
3972 hwnd = Hwnd.ObjectFromHandle(handle);
3975 return hwnd.MenuOrigin;
3980 [MonoTODO("Implement filtering")]
3981 internal override bool GetMessage(Object queue_id, ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
3989 if (((XEventQueue)queue_id).Count > 0) {
3990 xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
3992 UpdateMessageQueue ((XEventQueue)queue_id);
3994 if (((XEventQueue)queue_id).Count > 0) {
3995 xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
3996 } else if (((XEventQueue)queue_id).Paint.Count > 0) {
3997 xevent = ((XEventQueue)queue_id).Paint.Dequeue();
3999 msg.hwnd= IntPtr.Zero;
4000 msg.message = Msg.WM_ENTERIDLE;
4005 hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
4007 #if DriverDebugDestroy
4010 Console.WriteLine ( "GetMessage zombie, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
4012 Console.WriteLine ( "GetMessage, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
4014 // Handle messages for windows that are already or are about to be destroyed.
4016 // we need a special block for this because unless we remove the hwnd from the paint
4017 // queue it will always stay there (since we don't handle the expose), and we'll
4018 // effectively loop infinitely trying to repaint a non-existant window.
4019 if (hwnd != null && hwnd.zombie && xevent.type == XEventName.Expose) {
4020 hwnd.expose_pending = hwnd.nc_expose_pending = false;
4021 hwnd.Queue.Paint.Remove (hwnd);
4022 goto ProcessNextMessage;
4025 // We need to make sure we only allow DestroyNotify events through for zombie
4026 // hwnds, since much of the event handling code makes requests using the hwnd's
4027 // client_window, and that'll result in BadWindow errors if there's some lag
4028 // between the XDestroyWindow call and the DestroyNotify event.
4029 if (hwnd == null || hwnd.zombie && xevent.AnyEvent.type != XEventName.ClientMessage) {
4030 DriverDebug("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
4031 goto ProcessNextMessage;
4035 // If we get here, that means the window is no more but there are Client Messages
4036 // to be processed, probably a Posted message (for instance, an WM_ACTIVATE message)
4037 // We don't want anything else to run but the ClientMessage block, so reset all hwnd
4038 // properties that might cause other processing to occur.
4040 hwnd.resizing_or_moving = false;
4043 if (hwnd.client_window == xevent.AnyEvent.window) {
4045 //Console.WriteLine("Client message {1}, sending to window {0:X}", msg.hwnd.ToInt32(), xevent.type);
4048 //Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
4051 msg.hwnd = hwnd.Handle;
4053 // Windows sends WM_ENTERSIZEMOVE when a form resize/move operation starts and WM_EXITSIZEMOVE
4054 // when it is done. The problem in X11 is that there is no concept of start-end of a moving/sizing.
4055 // Configure events ("this window has resized/moved") are sent for each step of the resize. We send a
4056 // WM_ENTERSIZEMOVE when we get the first Configure event. The problem is the WM_EXITSIZEMOVE.
4058 // - There is no way for us to know which is the last Configure event. We can't traverse the events
4059 // queue, because the next configure event might not be pending yet.
4060 // - We can't get ButtonPress/Release events for the window decorations, because they are not part
4061 // of the window(s) we manage.
4062 // - We can't rely on the mouse state to change to "up" before the last Configure event. It doesn't.
4064 // We are almost 100% guaranteed to get another event (e.g Expose or other), but we can't know for sure
4065 // which, so we have here to check if the mouse buttons state is "up" and send the WM_EXITSIZEMOVE
4067 if (hwnd.resizing_or_moving) {
4068 int root_x, root_y, win_x, win_y, keys_buttons;
4070 XQueryPointer (DisplayHandle, hwnd.Handle, out root, out child, out root_x, out root_y,
4071 out win_x, out win_y, out keys_buttons);
4072 if ((keys_buttons & (int)MouseKeyMasks.Button1Mask) == 0 &&
4073 (keys_buttons & (int)MouseKeyMasks.Button2Mask) == 0 &&
4074 (keys_buttons & (int)MouseKeyMasks.Button3Mask) == 0) {
4075 hwnd.resizing_or_moving = false;
4076 SendMessage (hwnd.Handle, Msg.WM_EXITSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
4081 // If you add a new event to this switch make sure to add it in
4082 // UpdateMessage also unless it is not coming through the X event system.
4084 switch(xevent.type) {
4085 case XEventName.KeyPress: {
4086 Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
4088 // F1 key special case - WM_HELP sending
4089 if (msg.wParam == (IntPtr)VirtualKeys.VK_F1 || msg.wParam == (IntPtr)VirtualKeys.VK_HELP) {
4090 // Send wM_HELP and then return it as a keypress message in
4091 // case it needs to be preproccessed.
4092 HELPINFO helpInfo = new HELPINFO ();
4093 GetCursorPos (IntPtr.Zero, out helpInfo.MousePos.x, out helpInfo.MousePos.y);
4094 IntPtr helpInfoPtr = Marshal.AllocHGlobal (Marshal.SizeOf (helpInfo));
4095 Marshal.StructureToPtr (helpInfo, helpInfoPtr, true);
4096 NativeWindow.WndProc (FocusWindow, Msg.WM_HELP, IntPtr.Zero, helpInfoPtr);
4097 Marshal.FreeHGlobal (helpInfoPtr);
4102 case XEventName.KeyRelease: {
4103 Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
4107 case XEventName.ButtonPress: {
4108 switch(xevent.ButtonEvent.button) {
4110 MouseState |= MouseButtons.Left;
4112 msg.message = Msg.WM_LBUTTONDOWN;
4113 msg.wParam = GetMousewParam (0);
4115 msg.message = Msg.WM_NCLBUTTONDOWN;
4116 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4117 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4123 MouseState |= MouseButtons.Middle;
4125 msg.message = Msg.WM_MBUTTONDOWN;
4126 msg.wParam = GetMousewParam (0);
4128 msg.message = Msg.WM_NCMBUTTONDOWN;
4129 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4130 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4136 MouseState |= MouseButtons.Right;
4138 msg.message = Msg.WM_RBUTTONDOWN;
4139 msg.wParam = GetMousewParam (0);
4141 msg.message = Msg.WM_NCRBUTTONDOWN;
4142 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4143 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4149 msg.hwnd = FocusWindow;
4150 msg.message=Msg.WM_MOUSEWHEEL;
4151 msg.wParam=GetMousewParam(120);
4156 msg.hwnd = FocusWindow;
4157 msg.message=Msg.WM_MOUSEWHEEL;
4158 msg.wParam=GetMousewParam(-120);
4164 msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
4165 mouse_position.X = xevent.ButtonEvent.x;
4166 mouse_position.Y = xevent.ButtonEvent.y;
4168 if (!hwnd.Enabled) {
4171 msg.hwnd = hwnd.EnabledHwnd;
4172 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);
4173 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4176 if (Grab.Hwnd != IntPtr.Zero) {
4177 msg.hwnd = Grab.Hwnd;
4180 if (ClickPending.Pending && ((((long)xevent.ButtonEvent.time - ClickPending.Time) < DoubleClickInterval) && (msg.wParam == ClickPending.wParam) && (msg.lParam == ClickPending.lParam) && (msg.message == ClickPending.Message))) {
4181 // Looks like a genuine double click, clicked twice on the same spot with the same keys
4182 switch(xevent.ButtonEvent.button) {
4184 msg.message = client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK;
4189 msg.message = client ? Msg.WM_MBUTTONDBLCLK : Msg.WM_NCMBUTTONDBLCLK;
4194 msg.message = client ? Msg.WM_RBUTTONDBLCLK : Msg.WM_NCRBUTTONDBLCLK;
4198 ClickPending.Pending = false;
4200 ClickPending.Pending = true;
4201 ClickPending.Hwnd = msg.hwnd;
4202 ClickPending.Message = msg.message;
4203 ClickPending.wParam = msg.wParam;
4204 ClickPending.lParam = msg.lParam;
4205 ClickPending.Time = (long)xevent.ButtonEvent.time;
4208 if (msg.message == Msg.WM_LBUTTONDOWN || msg.message == Msg.WM_MBUTTONDOWN || msg.message == Msg.WM_RBUTTONDOWN) {
4209 SendParentNotify(msg.hwnd, msg.message, mouse_position.X, mouse_position.Y);
4215 case XEventName.ButtonRelease: {
4216 switch(xevent.ButtonEvent.button) {
4219 msg.message = Msg.WM_LBUTTONUP;
4221 msg.message = Msg.WM_NCLBUTTONUP;
4222 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4223 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4225 MouseState &= ~MouseButtons.Left;
4226 msg.wParam = GetMousewParam (0);
4232 msg.message = Msg.WM_MBUTTONUP;
4234 msg.message = Msg.WM_NCMBUTTONUP;
4235 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4236 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4238 MouseState &= ~MouseButtons.Middle;
4239 msg.wParam = GetMousewParam (0);
4245 msg.message = Msg.WM_RBUTTONUP;
4247 msg.message = Msg.WM_NCRBUTTONUP;
4248 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4249 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4251 MouseState &= ~MouseButtons.Right;
4252 msg.wParam = GetMousewParam (0);
4257 goto ProcessNextMessage;
4261 goto ProcessNextMessage;
4265 if (!hwnd.Enabled) {
4268 msg.hwnd = hwnd.EnabledHwnd;
4269 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);
4270 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4273 if (Grab.Hwnd != IntPtr.Zero) {
4274 msg.hwnd = Grab.Hwnd;
4277 msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
4278 mouse_position.X = xevent.ButtonEvent.x;
4279 mouse_position.Y = xevent.ButtonEvent.y;
4281 // Win32 splurts MouseMove events all over the place, regardless of whether the mouse is actually moving or
4282 // not, especially after mousedown and mouseup. To support apps relying on mousemove events between and after
4283 // mouse clicks to repaint or whatever, we generate a mousemove event here. *sigh*
4284 if (msg.message == Msg.WM_LBUTTONUP || msg.message == Msg.WM_MBUTTONUP || msg.message == Msg.WM_RBUTTONUP) {
4285 XEvent motionEvent = new XEvent ();
4286 motionEvent.type = XEventName.MotionNotify;
4287 motionEvent.MotionEvent.display = DisplayHandle;
4288 motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
4289 motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
4290 motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
4291 hwnd.Queue.EnqueueLocked (motionEvent);
4296 case XEventName.MotionNotify: {
4298 DriverDebug("GetMessage(): Window {0:X} MotionNotify x={1} y={2}",
4299 client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
4300 xevent.MotionEvent.x, xevent.MotionEvent.y);
4302 if (Grab.Hwnd != IntPtr.Zero) {
4303 msg.hwnd = Grab.Hwnd;
4306 NativeWindow.WndProc(msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
4310 if (xevent.MotionEvent.is_hint != 0)
4314 XQueryPointer (DisplayHandle, xevent.AnyEvent.window,
4315 out root, out child,
4316 out xevent.MotionEvent.x_root,
4317 out xevent.MotionEvent.y_root,
4318 out xevent.MotionEvent.x,
4319 out xevent.MotionEvent.y, out mask);
4322 msg.message = Msg.WM_MOUSEMOVE;
4323 msg.wParam = GetMousewParam(0);
4324 msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
4326 if (!hwnd.Enabled) {
4329 msg.hwnd = hwnd.EnabledHwnd;
4330 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);
4331 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4334 mouse_position.X = xevent.MotionEvent.x;
4335 mouse_position.Y = xevent.MotionEvent.y;
4337 if ((HoverState.Timer.Enabled) &&
4338 (((mouse_position.X + HoverState.Size.Width) < HoverState.X) ||
4339 ((mouse_position.X - HoverState.Size.Width) > HoverState.X) ||
4340 ((mouse_position.Y + HoverState.Size.Height) < HoverState.Y) ||
4341 ((mouse_position.Y - HoverState.Size.Height) > HoverState.Y))) {
4342 HoverState.Timer.Stop();
4343 HoverState.Timer.Start();
4344 HoverState.X = mouse_position.X;
4345 HoverState.Y = mouse_position.Y;
4353 DriverDebug("GetMessage(): non-client area {0:X} MotionNotify x={1} y={2}",
4354 client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
4355 xevent.MotionEvent.x, xevent.MotionEvent.y);
4356 msg.message = Msg.WM_NCMOUSEMOVE;
4358 if (!hwnd.Enabled) {
4359 msg.hwnd = hwnd.EnabledHwnd;
4360 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);
4361 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4364 ht = NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4365 NativeWindow.WndProc(hwnd.client_window, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)ht);
4367 mouse_position.X = xevent.MotionEvent.x;
4368 mouse_position.Y = xevent.MotionEvent.y;
4374 case XEventName.EnterNotify: {
4375 if (!hwnd.Enabled) {
4376 goto ProcessNextMessage;
4378 if (xevent.CrossingEvent.mode == NotifyMode.NotifyGrab || xevent.AnyEvent.window != hwnd.client_window) {
4379 goto ProcessNextMessage;
4381 if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) { // Pseudo motion caused by grabbing
4382 if (LastPointerWindow == xevent.AnyEvent.window)
4383 goto ProcessNextMessage;
4385 if (LastPointerWindow != IntPtr.Zero) {
4386 Point enter_loc = new Point (xevent.ButtonEvent.x, xevent.ButtonEvent.y);
4388 // We need this due to EnterNotify being fired on all the parent controls
4389 // of the Control being grabbed, and obviously in that scenario we are not
4390 // actuallty entering them
4391 Control ctrl = Control.FromHandle (hwnd.client_window);
4392 foreach (Control child_control in ctrl.Controls.GetAllControls ())
4393 if (child_control.Bounds.Contains (enter_loc))
4394 goto ProcessNextMessage;
4396 // A MouseLeave/LeaveNotify event is sent to the previous window
4397 // until the mouse is ungrabbed, not when actually leaving its bounds
4398 int x = xevent.CrossingEvent.x_root;
4399 int y = xevent.CrossingEvent.y_root;
4400 ScreenToClient (LastPointerWindow, ref x, ref y);
4402 XEvent leaveEvent = new XEvent ();
4403 leaveEvent.type = XEventName.LeaveNotify;
4404 leaveEvent.CrossingEvent.display = DisplayHandle;
4405 leaveEvent.CrossingEvent.window = LastPointerWindow;
4406 leaveEvent.CrossingEvent.x = x;
4407 leaveEvent.CrossingEvent.y = y;
4408 leaveEvent.CrossingEvent.mode = NotifyMode.NotifyNormal;
4409 Hwnd last_pointer_hwnd = Hwnd.ObjectFromHandle (LastPointerWindow);
4410 last_pointer_hwnd.Queue.EnqueueLocked (leaveEvent);
4414 LastPointerWindow = xevent.AnyEvent.window;
4416 msg.message = Msg.WM_MOUSE_ENTER;
4417 HoverState.X = xevent.CrossingEvent.x;
4418 HoverState.Y = xevent.CrossingEvent.y;
4419 HoverState.Timer.Enabled = true;
4420 HoverState.Window = xevent.CrossingEvent.window;
4422 // Win32 sends a WM_MOUSEMOVE after mouse enter
4423 XEvent motionEvent = new XEvent ();
4424 motionEvent.type = XEventName.MotionNotify;
4425 motionEvent.MotionEvent.display = DisplayHandle;
4426 motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
4427 motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
4428 motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
4429 hwnd.Queue.EnqueueLocked (motionEvent);
4433 case XEventName.LeaveNotify: {
4434 if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) {
4435 WindowUngrabbed (hwnd.Handle);
4436 goto ProcessNextMessage;
4438 if (!hwnd.Enabled) {
4439 goto ProcessNextMessage;
4441 if ((xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) || (xevent.CrossingEvent.window != hwnd.client_window)) {
4442 goto ProcessNextMessage;
4444 // If a grab is taking place, ignore it - we handle it in EnterNotify
4445 if (Grab.Hwnd != IntPtr.Zero)
4446 goto ProcessNextMessage;
4448 // Reset the cursor explicitly on X11.
4449 // X11 remembers the last set cursor for the window and in cases where
4450 // the control won't get a WM_SETCURSOR X11 will restore the last
4451 // known cursor, which we don't want.
4453 SetCursor (hwnd.client_window, IntPtr.Zero);
4455 msg.message=Msg.WM_MOUSELEAVE;
4456 HoverState.Timer.Enabled = false;
4457 HoverState.Window = IntPtr.Zero;
4462 case XEventName.CreateNotify: {
4463 if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {
4464 msg.message = WM_CREATE;
4465 // Set up CreateStruct
4467 goto ProcessNextMessage;
4474 case XEventName.ReparentNotify: {
4475 if (hwnd.parent == null) { // Toplevel
4476 if ((xevent.ReparentEvent.parent != IntPtr.Zero) && (xevent.ReparentEvent.window == hwnd.whole_window)) {
4477 hwnd.Reparented = true;
4479 // The location given by the event is not reliable between different wm's,
4480 // so use an alternative way of getting it.
4481 Point location = GetTopLevelWindowLocation (hwnd);
4482 hwnd.X = location.X;
4483 hwnd.Y = location.Y;
4485 if (hwnd.opacity != 0xffffffff) {
4488 opacity = (IntPtr)(Int32)hwnd.opacity;
4489 XChangeProperty(DisplayHandle, XGetParent(hwnd.whole_window), _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
4491 SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, msg.wParam, msg.lParam);
4492 goto ProcessNextMessage;
4494 hwnd.Reparented = false;
4495 goto ProcessNextMessage;
4498 goto ProcessNextMessage;
4501 case XEventName.ConfigureNotify: {
4502 if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
4503 DriverDebug("GetMessage(): Window {0:X} ConfigureNotify x={1} y={2} width={3} height={4}",
4504 hwnd.client_window.ToInt32(), xevent.ConfigureEvent.x,
4505 xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
4507 lock (hwnd.configure_lock) {
4508 Form form = Control.FromHandle (hwnd.client_window) as Form;
4509 if (form != null && !hwnd.resizing_or_moving) {
4510 if (hwnd.x != form.Bounds.X || hwnd.y != form.Bounds.Y) {
4511 SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_MOVE, IntPtr.Zero);
4512 hwnd.resizing_or_moving = true;
4513 } else if (hwnd.width != form.Bounds.Width || hwnd.height != form.Bounds.Height) {
4514 SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_SIZE, IntPtr.Zero);
4515 hwnd.resizing_or_moving = true;
4517 if (hwnd.resizing_or_moving)
4518 SendMessage (form.Handle, Msg.WM_ENTERSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
4521 SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
4522 hwnd.configure_pending = false;
4524 // We need to adjust our client window to track the resize of whole_window
4525 if (hwnd.whole_window != hwnd.client_window)
4526 PerformNCCalc(hwnd);
4529 goto ProcessNextMessage;
4532 case XEventName.FocusIn: {
4533 // We received focus. We use X11 focus only to know if the app window does or does not have focus
4534 // We do not track the actual focussed window via it. Instead, this is done via FocusWindow internally
4535 // Receiving focus means we've gotten activated and therefore we need to let the actual FocusWindow know
4536 // about it having focus again
4537 if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
4538 goto ProcessNextMessage;
4542 if (FocusWindow == IntPtr.Zero) {
4543 Control c = Control.FromHandle (hwnd.client_window);
4546 goto ProcessNextMessage;
4547 Form form = c.FindForm ();
4549 goto ProcessNextMessage;
4551 if (ActiveWindow != form.Handle) {
4552 ActiveWindow = form.Handle;
4553 SendMessage (ActiveWindow, Msg.WM_ACTIVATE, (IntPtr) WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
4555 goto ProcessNextMessage;
4557 Keyboard.FocusIn (FocusWindow);
4558 SendMessage(FocusWindow, Msg.WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero);
4559 goto ProcessNextMessage;
4562 case XEventName.FocusOut: {
4563 // Se the comment for our FocusIn handler
4564 if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
4565 goto ProcessNextMessage;
4568 while (Keyboard.ResetKeyState(FocusWindow, ref msg)) {
4569 SendMessage(FocusWindow, msg.message, msg.wParam, msg.lParam);
4572 Keyboard.FocusOut(hwnd.client_window);
4573 SendMessage(FocusWindow, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
4574 goto ProcessNextMessage;
4577 // We are already firing WM_SHOWWINDOW messages in the proper places, but I'm leaving this code
4578 // in case we break a scenario not taken into account in the tests
4579 case XEventName.MapNotify: {
4580 /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
4582 msg.message = Msg.WM_SHOWWINDOW;
4583 msg.wParam = (IntPtr) 1;
4584 // XXX we're missing the lParam..
4587 goto ProcessNextMessage;
4590 case XEventName.UnmapNotify: {
4591 /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
4592 hwnd.mapped = false;
4593 msg.message = Msg.WM_SHOWWINDOW;
4594 msg.wParam = (IntPtr) 0;
4595 // XXX we're missing the lParam..
4598 goto ProcessNextMessage;
4601 case XEventName.Expose: {
4604 hwnd.expose_pending = false;
4606 hwnd.nc_expose_pending = false;
4608 goto ProcessNextMessage;
4612 if (!hwnd.expose_pending) {
4613 goto ProcessNextMessage;
4616 if (!hwnd.nc_expose_pending) {
4617 goto ProcessNextMessage;
4620 switch (hwnd.border_style) {
4621 case FormBorderStyle.Fixed3D: {
4624 g = Graphics.FromHwnd(hwnd.whole_window);
4625 if (hwnd.border_static)
4626 ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.SunkenOuter);
4628 ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.Sunken);
4633 case FormBorderStyle.FixedSingle: {
4636 g = Graphics.FromHwnd(hwnd.whole_window);
4637 ControlPaint.DrawBorder(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Color.Black, ButtonBorderStyle.Solid);
4642 DriverDebug("GetMessage(): Window {0:X} Exposed non-client area {1},{2} {3}x{4}",
4643 hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y,
4644 xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4646 Rectangle rect = new Rectangle (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4647 Region region = new Region (rect);
4648 IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
4649 msg.message = Msg.WM_NCPAINT;
4650 msg.wParam = hrgn == IntPtr.Zero ? (IntPtr)1 : hrgn;
4651 msg.refobject = region;
4654 DriverDebug("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}",
4655 hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y,
4656 xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4657 if (Caret.Visible == true) {
4658 Caret.Paused = true;
4662 if (Caret.Visible == true) {
4664 Caret.Paused = false;
4666 msg.message = Msg.WM_PAINT;
4670 case XEventName.DestroyNotify: {
4672 // This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
4673 hwnd = Hwnd.ObjectFromHandle(xevent.DestroyWindowEvent.window);
4675 // We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
4676 if ((hwnd != null) && (hwnd.client_window == xevent.DestroyWindowEvent.window)) {
4677 CleanupCachedWindows (hwnd);
4679 DriverDebug("Received X11 Destroy Notification for {0}", XplatUI.Window(hwnd.client_window));
4681 msg.hwnd = hwnd.client_window;
4682 msg.message=Msg.WM_DESTROY;
4685 goto ProcessNextMessage;
4691 case XEventName.ClientMessage: {
4692 if (Dnd.HandleClientMessage (ref xevent)) {
4693 goto ProcessNextMessage;
4696 if (xevent.ClientMessageEvent.message_type == AsyncAtom) {
4697 XplatUIDriverSupport.ExecuteClientMessage((GCHandle)xevent.ClientMessageEvent.ptr1);
4698 goto ProcessNextMessage;
4701 if (xevent.ClientMessageEvent.message_type == HoverState.Atom) {
4702 msg.message = Msg.WM_MOUSEHOVER;
4703 msg.wParam = GetMousewParam(0);
4704 msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
4708 if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {
4709 DebugHelper.Indent ();
4710 DebugHelper.WriteLine (String.Format ("Posted message:" + (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 () + " for 0x{0:x}", xevent.ClientMessageEvent.ptr1.ToInt32 ()));
4711 DebugHelper.Unindent ();
4712 msg.hwnd = xevent.ClientMessageEvent.ptr1;
4713 msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
4714 msg.wParam = xevent.ClientMessageEvent.ptr3;
4715 msg.lParam = xevent.ClientMessageEvent.ptr4;
4716 if (msg.message == (Msg)Msg.WM_QUIT)
4722 if (xevent.ClientMessageEvent.message_type == _XEMBED) {
4723 #if DriverDebugXEmbed
4724 Console.WriteLine("GOT EMBED MESSAGE {0:X}, detail {1:X}", xevent.ClientMessageEvent.ptr2.ToInt32(), xevent.ClientMessageEvent.ptr3.ToInt32());
4727 if (xevent.ClientMessageEvent.ptr2.ToInt32() == (int)XEmbedMessage.EmbeddedNotify) {
4728 XSizeHints hints = new XSizeHints();
4731 XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
4733 hwnd.width = hints.max_width;
4734 hwnd.height = hints.max_height;
4735 hwnd.ClientRect = Rectangle.Empty;
4736 SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
4740 if (xevent.ClientMessageEvent.message_type == WM_PROTOCOLS) {
4741 if (xevent.ClientMessageEvent.ptr1 == WM_DELETE_WINDOW) {
4742 SendMessage (msg.hwnd, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_CLOSE, IntPtr.Zero);
4743 msg.message = Msg.WM_CLOSE;
4747 // We should not get this, but I'll leave the code in case we need it in the future
4748 if (xevent.ClientMessageEvent.ptr1 == WM_TAKE_FOCUS) {
4749 goto ProcessNextMessage;
4752 goto ProcessNextMessage;
4756 goto ProcessNextMessage;
4763 HitTest NCHitTest (Hwnd hwnd, int x, int y)
4765 // The hit test is sent in screen coordinates
4767 int screen_x, screen_y;
4768 XTranslateCoordinates (DisplayHandle, hwnd.WholeWindow, RootWindow, x, y, out screen_x, out screen_y, out dummy);
4769 return (HitTest) NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero,
4770 (IntPtr) (screen_y << 16 | screen_x & 0xFFFF));
4773 // Our very basic implementation of MoveResize - we can extend it later
4775 internal override void BeginMoveResize (IntPtr handle)
4777 // We *need* to ungrab the pointer in the current display
4778 XplatUI.UngrabWindow (Grab.Hwnd);
4781 GetCursorPos (IntPtr.Zero, out x_root, out y_root);
4783 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
4784 SendNetWMMessage (hwnd.whole_window, _NET_WM_MOVERESIZE, (IntPtr) x_root, (IntPtr) y_root,
4785 (IntPtr) NetWmMoveResize._NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT,
4786 (IntPtr) 1); // left button
4789 internal override bool GetText(IntPtr handle, out string text)
4797 IntPtr prop = IntPtr.Zero;
4799 XGetWindowProperty(DisplayHandle, handle,
4800 _NET_WM_NAME, IntPtr.Zero, new IntPtr (1), false,
4801 UTF8_STRING, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
4803 if ((long)nitems > 0 && prop != IntPtr.Zero) {
4804 text = Marshal.PtrToStringUni (prop, (int)nitems);
4809 // fallback on the non-_NET property
4812 textptr = IntPtr.Zero;
4814 XFetchName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, ref textptr);
4815 if (textptr != IntPtr.Zero) {
4816 text = Marshal.PtrToStringAnsi(textptr);
4827 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)
4831 hwnd = Hwnd.ObjectFromHandle(handle);
4837 height = hwnd.height;
4839 PerformNCCalc(hwnd);
4841 client_width = hwnd.ClientRect.Width;
4842 client_height = hwnd.ClientRect.Height;
4847 // Should we throw an exception or fail silently?
4848 // throw new ArgumentException("Called with an invalid window handle", "handle");
4858 internal override FormWindowState GetWindowState(IntPtr handle)
4862 hwnd = Hwnd.ObjectFromHandle(handle);
4864 if (hwnd.cached_window_state == (FormWindowState)(-1))
4865 hwnd.cached_window_state = UpdateWindowState (handle);
4867 return hwnd.cached_window_state;
4870 FormWindowState UpdateWindowState (IntPtr handle) {
4875 IntPtr prop = IntPtr.Zero;
4879 XWindowAttributes attributes;
4882 hwnd = Hwnd.ObjectFromHandle(handle);
4886 XGetWindowProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_ATOM, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
4887 if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
4888 for (int i = 0; i < (long)nitems; i++) {
4889 atom = (IntPtr)Marshal.ReadInt32(prop, i * 4);
4890 if ((atom == _NET_WM_STATE_MAXIMIZED_HORZ) || (atom == _NET_WM_STATE_MAXIMIZED_VERT)) {
4892 } else if (atom == _NET_WM_STATE_HIDDEN) {
4900 return FormWindowState.Minimized;
4901 } else if (maximized == 2) {
4902 return FormWindowState.Maximized;
4905 attributes = new XWindowAttributes();
4906 XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
4907 if (attributes.map_state == MapState.IsUnmapped) {
4908 return (FormWindowState)(-1);
4912 return FormWindowState.Normal;
4915 internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea)
4918 GrabConfined = Grab.Confined;
4919 GrabArea = Grab.Area;
4922 internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle)
4925 IntPtr confine_to_window;
4927 confine_to_window = IntPtr.Zero;
4929 if (confine_to_handle != IntPtr.Zero) {
4930 XWindowAttributes attributes = new XWindowAttributes();
4932 hwnd = Hwnd.ObjectFromHandle(confine_to_handle);
4935 XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
4937 Grab.Area.X = attributes.x;
4938 Grab.Area.Y = attributes.y;
4939 Grab.Area.Width = attributes.width;
4940 Grab.Area.Height = attributes.height;
4941 Grab.Confined = true;
4942 confine_to_window = hwnd.client_window;
4947 hwnd = Hwnd.ObjectFromHandle(handle);
4950 XGrabPointer(DisplayHandle, hwnd.client_window, false,
4951 EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
4952 EventMask.ButtonReleaseMask | EventMask.PointerMotionMask |
4953 EventMask.PointerMotionHintMask | EventMask.LeaveWindowMask,
4954 GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, IntPtr.Zero, IntPtr.Zero);
4958 internal override void UngrabWindow(IntPtr hwnd)
4961 XUngrabPointer(DisplayHandle, IntPtr.Zero);
4962 XFlush(DisplayHandle);
4964 WindowUngrabbed (hwnd);
4967 void WindowUngrabbed (IntPtr hwnd) {
4968 bool was_grabbed = Grab.Hwnd != IntPtr.Zero;
4970 Grab.Hwnd = IntPtr.Zero;
4971 Grab.Confined = false;
4974 // lparam should be the handle to the window gaining the mouse capture,
4975 // but X doesn't seem to give us that information.
4976 // Also only generate WM_CAPTURECHANGED if the window actually was grabbed.
4977 // X will send a NotifyUngrab, but since it comes late sometimes we're
4978 // calling WindowUngrabbed directly from UngrabWindow in order to send
4979 // this WM right away.
4980 SendMessage (hwnd, Msg.WM_CAPTURECHANGED, IntPtr.Zero, IntPtr.Zero);
4984 internal override void HandleException(Exception e)
4986 StackTrace st = new StackTrace(e, true);
4987 Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
4988 Console.WriteLine("{0}{1}", e.Message, st.ToString());
4991 internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear)
4995 hwnd = Hwnd.ObjectFromHandle(handle);
4998 AddExpose (hwnd, true, hwnd.X, hwnd.Y, hwnd.Width, hwnd.Height);
5000 AddExpose (hwnd, true, rc.X, rc.Y, rc.Width, rc.Height);
5004 internal override void InvalidateNC (IntPtr handle)
5008 hwnd = Hwnd.ObjectFromHandle(handle);
5010 AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
5013 internal override bool IsEnabled(IntPtr handle)
5015 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5016 return (hwnd != null && hwnd.Enabled);
5019 internal override bool IsVisible(IntPtr handle)
5021 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5022 return (hwnd != null && hwnd.visible);
5025 internal override void KillTimer(Timer timer)
5027 XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
5029 if (queue == null) {
5030 // This isn't really an error, MS doesn't start the timer if
5031 // it has no assosciated queue. In this case, remove the timer
5032 // from the list of unattached timers (if it was enabled).
5033 lock (unattached_timer_list) {
5034 if (unattached_timer_list.Contains (timer))
5035 unattached_timer_list.Remove (timer);
5039 queue.timer_list.Remove (timer);
5042 internal override void MenuToScreen(IntPtr handle, ref int x, ref int y)
5049 hwnd = Hwnd.ObjectFromHandle(handle);
5052 XTranslateCoordinates(DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
5059 internal override void OverrideCursor(IntPtr cursor)
5061 if (Grab.Hwnd != IntPtr.Zero) {
5062 XChangeActivePointerGrab (DisplayHandle,
5063 EventMask.ButtonMotionMask |
5064 EventMask.PointerMotionMask |
5065 EventMask.PointerMotionHintMask |
5066 EventMask.ButtonPressMask |
5067 EventMask.ButtonReleaseMask,
5068 cursor, IntPtr.Zero);
5072 OverrideCursorHandle = cursor;
5075 internal override PaintEventArgs PaintEventStart(ref Message msg, IntPtr handle, bool client)
5077 PaintEventArgs paint_event;
5082 // handle (and paint_hwnd) refers to the window that is should be painted.
5083 // msg.HWnd (and hwnd) refers to the window that got the paint message.
5086 hwnd = Hwnd.ObjectFromHandle(msg.HWnd);
5087 if (msg.HWnd == handle) {
5090 paint_hwnd = Hwnd.ObjectFromHandle (handle);
5093 if (Caret.Visible == true) {
5094 Caret.Paused = true;
5101 dc = Graphics.FromHwnd (paint_hwnd.client_window);
5103 Region clip_region = new Region ();
5104 clip_region.MakeEmpty();
5106 foreach (Rectangle r in hwnd.ClipRectangles) {
5107 /* Expand the region slightly.
5110 Rectangle r2 = Rectangle.FromLTRB (r.Left, r.Top, r.Right, r.Bottom + 1);
5111 clip_region.Union (r2);
5114 if (hwnd.UserClip != null) {
5115 clip_region.Intersect(hwnd.UserClip);
5118 dc.Clip = clip_region;
5119 paint_event = new PaintEventArgs(dc, hwnd.Invalid);
5120 hwnd.expose_pending = false;
5122 hwnd.ClearInvalidArea();
5124 hwnd.drawing_stack.Push (paint_event);
5125 hwnd.drawing_stack.Push (dc);
5129 dc = Graphics.FromHwnd (paint_hwnd.whole_window);
5131 if (!hwnd.nc_invalid.IsEmpty) {
5132 dc.SetClip (hwnd.nc_invalid);
5133 paint_event = new PaintEventArgs(dc, hwnd.nc_invalid);
5135 paint_event = new PaintEventArgs(dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
5137 hwnd.nc_expose_pending = false;
5139 hwnd.ClearNcInvalidArea ();
5141 hwnd.drawing_stack.Push (paint_event);
5142 hwnd.drawing_stack.Push (dc);
5148 internal override void PaintEventEnd(ref Message msg, IntPtr handle, bool client)
5152 hwnd = Hwnd.ObjectFromHandle (msg.HWnd);
5154 Graphics dc = (Graphics)hwnd.drawing_stack.Pop ();
5158 PaintEventArgs pe = (PaintEventArgs)hwnd.drawing_stack.Pop();
5159 pe.SetGraphics (null);
5162 if (Caret.Visible == true) {
5164 Caret.Paused = false;
5168 [MonoTODO("Implement filtering and PM_NOREMOVE")]
5169 internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
5171 XEventQueue queue = (XEventQueue) queue_id;
5174 if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
5175 throw new NotImplementedException("PeekMessage PM_NOREMOVE is not implemented yet"); // FIXME - Implement PM_NOREMOVE flag
5179 if (queue.Count > 0) {
5182 // Only call UpdateMessageQueue if real events are pending
5183 // otherwise we go to sleep on the socket
5184 if (XPending(DisplayHandle) != 0) {
5185 UpdateMessageQueue((XEventQueue)queue_id);
5187 } else if (((XEventQueue)queue_id).Paint.Count > 0) {
5192 CheckTimers(queue.timer_list, DateTime.UtcNow);
5197 return GetMessage(queue_id, ref msg, hWnd, wFilterMin, wFilterMax);
5200 internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam)
5202 XEvent xevent = new XEvent ();
5203 Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5205 xevent.type = XEventName.ClientMessage;
5206 xevent.ClientMessageEvent.display = DisplayHandle;
5209 xevent.ClientMessageEvent.window = hwnd.whole_window;
5211 xevent.ClientMessageEvent.window = IntPtr.Zero;
5214 xevent.ClientMessageEvent.message_type = (IntPtr) PostAtom;
5215 xevent.ClientMessageEvent.format = 32;
5216 xevent.ClientMessageEvent.ptr1 = handle;
5217 xevent.ClientMessageEvent.ptr2 = (IntPtr) message;
5218 xevent.ClientMessageEvent.ptr3 = wparam;
5219 xevent.ClientMessageEvent.ptr4 = lparam;
5222 hwnd.Queue.EnqueueLocked (xevent);
5224 ThreadQueue(Thread.CurrentThread).EnqueueLocked (xevent);
5229 internal override void PostQuitMessage(int exitCode)
5231 ApplicationContext ctx = Application.MWFThread.Current.Context;
5232 Form f = ctx != null ? ctx.MainForm : null;
5234 PostMessage (Application.MWFThread.Current.Context.MainForm.window.Handle, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
5236 PostMessage (FosterParent, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
5237 XFlush(DisplayHandle);
5240 internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave)
5245 internal override void RequestNCRecalc(IntPtr handle)
5249 hwnd = Hwnd.ObjectFromHandle(handle);
5255 PerformNCCalc(hwnd);
5256 SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5257 InvalidateNC(handle);
5260 internal override void ResetMouseHover(IntPtr handle)
5264 hwnd = Hwnd.ObjectFromHandle(handle);
5269 HoverState.Timer.Enabled = true;
5270 HoverState.X = mouse_position.X;
5271 HoverState.Y = mouse_position.Y;
5272 HoverState.Window = handle;
5276 internal override void ScreenToClient(IntPtr handle, ref int x, ref int y)
5283 hwnd = Hwnd.ObjectFromHandle(handle);
5286 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.client_window, x, y, out dest_x_return, out dest_y_return, out child);
5293 internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y)
5300 hwnd = Hwnd.ObjectFromHandle(handle);
5303 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.whole_window, x, y, out dest_x_return, out dest_y_return, out child);
5306 Form form = Control.FromHandle (handle) as Form;
5307 if (form != null && form.window_manager != null) {
5308 dest_y_return -= form.window_manager.TitleBarHeight;
5315 bool GraphicsExposePredicate (IntPtr display, ref XEvent xevent, IntPtr arg)
5317 return (xevent.type == XEventName.GraphicsExpose || xevent.type == XEventName.NoExpose) &&
5318 arg == xevent.GraphicsExposeEvent.drawable;
5321 delegate bool EventPredicate (IntPtr display, ref XEvent xevent, IntPtr arg);
5323 void ProcessGraphicsExpose (Hwnd hwnd)
5325 XEvent xevent = new XEvent ();
5326 IntPtr handle = Hwnd.HandleFromObject (hwnd);
5327 EventPredicate predicate = GraphicsExposePredicate;
5330 XIfEvent (Display, ref xevent, predicate, handle);
5331 if (xevent.type != XEventName.GraphicsExpose)
5334 AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.GraphicsExposeEvent.x, xevent.GraphicsExposeEvent.y,
5335 xevent.GraphicsExposeEvent.width, xevent.GraphicsExposeEvent.height);
5337 if (xevent.GraphicsExposeEvent.count == 0)
5342 internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children)
5346 XGCValues gc_values;
5348 hwnd = Hwnd.ObjectFromHandle(handle);
5350 Rectangle r = Rectangle.Intersect (hwnd.Invalid, area);
5352 /* We have an invalid area in the window we're scrolling.
5353 Adjust our stored invalid rectangle to to match the scrolled amount */
5368 if (area.Contains (hwnd.Invalid))
5369 hwnd.ClearInvalidArea ();
5370 hwnd.AddInvalidArea(r);
5373 gc_values = new XGCValues();
5375 if (with_children) {
5376 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
5379 gc = XCreateGC(DisplayHandle, hwnd.client_window, IntPtr.Zero, ref gc_values);
5381 Rectangle visible_rect = GetTotalVisibleArea (hwnd.client_window);
5382 visible_rect.Intersect (area);
5384 Rectangle dest_rect = visible_rect;
5385 dest_rect.Y += YAmount;
5386 dest_rect.X += XAmount;
5387 dest_rect.Intersect (area);
5389 Point src = new Point (dest_rect.X - XAmount, dest_rect.Y - YAmount);
5390 XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src.X, src.Y,
5391 dest_rect.Width, dest_rect.Height, dest_rect.X, dest_rect.Y);
5393 Rectangle dirty_area = GetDirtyArea (area, dest_rect, XAmount, YAmount);
5394 AddExpose (hwnd, true, dirty_area.X, dirty_area.Y, dirty_area.Width, dirty_area.Height);
5396 ProcessGraphicsExpose (hwnd);
5398 XFreeGC(DisplayHandle, gc);
5401 internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children)
5406 hwnd = Hwnd.GetObjectFromWindow(handle);
5408 rect = hwnd.ClientRect;
5411 ScrollWindow(handle, rect, XAmount, YAmount, with_children);
5414 Rectangle GetDirtyArea (Rectangle total_area, Rectangle valid_area, int XAmount, int YAmount)
5416 Rectangle dirty_area = total_area;
5419 dirty_area.Height -= valid_area.Height;
5420 else if (YAmount < 0) {
5421 dirty_area.Height -= valid_area.Height;
5422 dirty_area.Y += valid_area.Height;
5426 dirty_area.Width -= valid_area.Width;
5427 else if (XAmount < 0) {
5428 dirty_area.Width -= valid_area.Width;
5429 dirty_area.X += valid_area.Width;
5435 Rectangle GetTotalVisibleArea (IntPtr handle)
5437 Control c = Control.FromHandle (handle);
5439 Rectangle visible_area = c.ClientRectangle;
5440 visible_area.Location = c.PointToScreen (Point.Empty);
5442 for (Control parent = c.Parent; parent != null; parent = parent.Parent) {
5443 if (!parent.IsHandleCreated || !parent.Visible)
5444 return visible_area; // Non visible, not need to finish computations
5446 Rectangle r = parent.ClientRectangle;
5447 r.Location = parent.PointToScreen (Point.Empty);
5449 visible_area.Intersect (r);
5452 visible_area.Location = c.PointToClient (visible_area.Location);
5453 return visible_area;
5456 internal override void SendAsyncMethod (AsyncMethodData method)
5459 XEvent xevent = new XEvent ();
5461 hwnd = Hwnd.ObjectFromHandle(method.Handle);
5463 xevent.type = XEventName.ClientMessage;
5464 xevent.ClientMessageEvent.display = DisplayHandle;
5465 xevent.ClientMessageEvent.window = method.Handle;
5466 xevent.ClientMessageEvent.message_type = (IntPtr)AsyncAtom;
5467 xevent.ClientMessageEvent.format = 32;
5468 xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
5470 hwnd.Queue.EnqueueLocked (xevent);
5475 delegate IntPtr WndProcDelegate (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam);
5477 internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam)
5480 h = Hwnd.ObjectFromHandle(hwnd);
5482 if (h != null && h.queue != ThreadQueue (Thread.CurrentThread)) {
5483 AsyncMethodResult result;
5484 AsyncMethodData data;
5486 result = new AsyncMethodResult ();
5487 data = new AsyncMethodData ();
5490 data.Method = new WndProcDelegate (NativeWindow.WndProc);
5491 data.Args = new object[] { hwnd, message, wParam, lParam };
5492 data.Result = result;
5494 SendAsyncMethod (data);
5495 DriverDebug("Sending {0} message across.", message);
5499 string key = hwnd + ":" + message;
5500 if (messageHold[key] != null)
5501 messageHold[key] = ((int)messageHold[key]) - 1;
5502 return NativeWindow.WndProc(hwnd, message, wParam, lParam);
5505 internal override int SendInput(IntPtr handle, Queue keys)
5507 if (handle == IntPtr.Zero)
5510 int count = keys.Count;
5511 Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5513 while (keys.Count > 0) {
5515 MSG msg = (MSG)keys.Dequeue();
5517 XEvent xevent = new XEvent ();
5519 xevent.type = (msg.message == Msg.WM_KEYUP ? XEventName.KeyRelease : XEventName.KeyPress);
5520 xevent.KeyEvent.display = DisplayHandle;
5523 xevent.KeyEvent.window = hwnd.whole_window;
5525 xevent.KeyEvent.window = IntPtr.Zero;
5528 xevent.KeyEvent.keycode = Keyboard.ToKeycode((int)msg.wParam);
5530 hwnd.Queue.EnqueueLocked (xevent);
5535 internal override void SetAllowDrop (IntPtr handle, bool value)
5537 // We allow drop on all windows
5540 internal override DragDropEffects StartDrag (IntPtr handle, object data,
5541 DragDropEffects allowed_effects)
5543 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5546 throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");
5548 return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
5551 internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style)
5553 Form form = Control.FromHandle (handle) as Form;
5554 if (form != null && form.window_manager == null) {
5555 CreateParams cp = form.GetCreateParams ();
5556 if (border_style == FormBorderStyle.FixedToolWindow ||
5557 border_style == FormBorderStyle.SizableToolWindow ||
5558 cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
5559 form.window_manager = new ToolWindowManager (form);
5563 RequestNCRecalc(handle);
5566 internal override void SetCaretPos(IntPtr handle, int x, int y)
5568 if (Caret.Hwnd == handle) {
5575 Keyboard.SetCaretPos (Caret, handle, x, y);
5577 if (Caret.Visible == true) {
5579 Caret.Timer.Start();
5584 internal override void SetClipRegion(IntPtr handle, Region region)
5588 hwnd = Hwnd.ObjectFromHandle(handle);
5593 hwnd.UserClip = region;
5596 internal override void SetCursor(IntPtr handle, IntPtr cursor)
5600 if (OverrideCursorHandle == IntPtr.Zero) {
5601 if ((LastCursorWindow == handle) && (LastCursorHandle == cursor)) {
5605 LastCursorHandle = cursor;
5606 LastCursorWindow = handle;
5608 hwnd = Hwnd.ObjectFromHandle(handle);
5610 if (cursor != IntPtr.Zero) {
5611 XDefineCursor(DisplayHandle, hwnd.whole_window, cursor);
5613 XUndefineCursor(DisplayHandle, hwnd.whole_window);
5615 XFlush(DisplayHandle);
5620 hwnd = Hwnd.ObjectFromHandle(handle);
5622 XDefineCursor(DisplayHandle, hwnd.whole_window, OverrideCursorHandle);
5626 void QueryPointer (IntPtr display, IntPtr w, out IntPtr root, out IntPtr child,
5627 out int root_x, out int root_y, out int child_x, out int child_y,
5630 /* this code was written with the help of
5631 glance at gdk. I never would have realized we
5632 needed a loop in order to traverse down in the
5633 hierarchy. I would have assumed you'd get the
5634 most deeply nested child and have to do
5635 XQueryTree to move back up the hierarchy..
5636 stupid me, of course. */
5639 XGrabServer (display);
5641 XQueryPointer(display, w, out root, out c,
5642 out root_x, out root_y, out child_x, out child_y,
5648 IntPtr child_last = IntPtr.Zero;
5649 while (c != IntPtr.Zero) {
5651 XQueryPointer(display, c, out root, out c,
5652 out root_x, out root_y, out child_x, out child_y,
5655 XUngrabServer (display);
5661 internal override void SetCursorPos(IntPtr handle, int x, int y)
5663 if (handle == IntPtr.Zero) {
5666 int root_x, root_y, child_x, child_y, mask;
5669 * QueryPointer before warping
5670 * because if the warp is on
5671 * the RootWindow, the x/y are
5672 * relative to the current
5675 QueryPointer (DisplayHandle, RootWindow,
5678 out root_x, out root_y,
5679 out child_x, out child_y,
5682 XWarpPointer(DisplayHandle, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x - root_x, y - root_y);
5684 XFlush (DisplayHandle);
5686 /* then we need to a
5687 * QueryPointer after warping
5688 * to manually generate a
5689 * motion event for the window
5692 QueryPointer (DisplayHandle, RootWindow,
5695 out root_x, out root_y,
5696 out child_x, out child_y,
5699 Hwnd child_hwnd = Hwnd.ObjectFromHandle(child);
5700 if (child_hwnd == null) {
5704 XEvent xevent = new XEvent ();
5706 xevent.type = XEventName.MotionNotify;
5707 xevent.MotionEvent.display = DisplayHandle;
5708 xevent.MotionEvent.window = child_hwnd.client_window;
5709 xevent.MotionEvent.root = RootWindow;
5710 xevent.MotionEvent.x = child_x;
5711 xevent.MotionEvent.y = child_y;
5712 xevent.MotionEvent.x_root = root_x;
5713 xevent.MotionEvent.y_root = root_y;
5714 xevent.MotionEvent.state = mask;
5716 child_hwnd.Queue.EnqueueLocked (xevent);
5721 hwnd = Hwnd.ObjectFromHandle(handle);
5723 XWarpPointer(DisplayHandle, IntPtr.Zero, hwnd.client_window, 0, 0, 0, 0, x, y);
5728 internal override void SetFocus(IntPtr handle)
5731 IntPtr prev_focus_window;
5733 hwnd = Hwnd.ObjectFromHandle(handle);
5735 if (hwnd.client_window == FocusWindow) {
5739 // Win32 doesn't do anything if disabled
5743 prev_focus_window = FocusWindow;
5744 FocusWindow = hwnd.client_window;
5746 if (prev_focus_window != IntPtr.Zero) {
5747 SendMessage(prev_focus_window, Msg.WM_KILLFOCUS, FocusWindow, IntPtr.Zero);
5749 Keyboard.FocusIn (FocusWindow);
5750 SendMessage(FocusWindow, Msg.WM_SETFOCUS, prev_focus_window, IntPtr.Zero);
5752 //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
5755 internal override void SetIcon(IntPtr handle, Icon icon)
5759 hwnd = Hwnd.ObjectFromHandle(handle);
5761 SetIcon(hwnd, icon);
5765 internal override void SetMenu(IntPtr handle, Menu menu)
5769 hwnd = Hwnd.ObjectFromHandle(handle);
5772 RequestNCRecalc(handle);
5775 internal override void SetModal(IntPtr handle, bool Modal)
5778 ModalWindows.Push(handle);
5780 if (ModalWindows.Contains(handle)) {
5783 if (ModalWindows.Count > 0) {
5784 Activate((IntPtr)ModalWindows.Peek());
5788 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5789 Control ctrl = Control.FromHandle (handle);
5790 SetWMStyles (hwnd, ctrl.GetCreateParams ());
5793 internal override IntPtr SetParent(IntPtr handle, IntPtr parent)
5797 hwnd = Hwnd.ObjectFromHandle(handle);
5798 hwnd.parent = Hwnd.ObjectFromHandle(parent);
5801 DriverDebug("Parent for window {0} = {1}", XplatUI.Window(hwnd.Handle), XplatUI.Window(hwnd.parent != null ? hwnd.parent.Handle : IntPtr.Zero));
5802 XReparentWindow(DisplayHandle, hwnd.whole_window, hwnd.parent == null ? FosterParent : hwnd.parent.client_window, hwnd.x, hwnd.y);
5808 internal override void SetTimer (Timer timer)
5810 XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
5812 if (queue == null) {
5813 // This isn't really an error, MS doesn't start the timer if
5814 // it has no assosciated queue at this stage (it will be
5815 // enabled when a window is activated).
5816 unattached_timer_list.Add (timer);
5819 queue.timer_list.Add (timer);
5823 internal override bool SetTopmost(IntPtr handle, bool enabled)
5826 Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5827 hwnd.topmost = enabled;
5832 SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_ADD, _NET_WM_STATE_ABOVE, IntPtr.Zero);
5834 int[] atoms = new int[8];
5835 atoms[0] = _NET_WM_STATE_ABOVE.ToInt32();
5836 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
5842 SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_REMOVE, _NET_WM_STATE_ABOVE, IntPtr.Zero);
5844 XDeleteProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE);
5850 internal override bool SetOwner(IntPtr handle, IntPtr handle_owner)
5855 hwnd = Hwnd.ObjectFromHandle(handle);
5857 if (handle_owner != IntPtr.Zero) {
5858 hwnd_owner = Hwnd.ObjectFromHandle(handle_owner);
5864 atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
5865 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
5867 if (hwnd_owner != null) {
5868 XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd_owner.whole_window);
5870 XSetTransientForHint(DisplayHandle, hwnd.whole_window, RootWindow);
5875 XDeleteProperty(DisplayHandle, hwnd.whole_window, (IntPtr)Atom.XA_WM_TRANSIENT_FOR);
5881 internal override bool SetVisible (IntPtr handle, bool visible, bool activate)
5885 hwnd = Hwnd.ObjectFromHandle(handle);
5886 hwnd.visible = visible;
5890 MapWindow(hwnd, WindowType.Both);
5892 if (Control.FromHandle(handle) is Form) {
5895 s = ((Form)Control.FromHandle(handle)).WindowState;
5898 case FormWindowState.Minimized: SetWindowState(handle, FormWindowState.Minimized); break;
5899 case FormWindowState.Maximized: SetWindowState(handle, FormWindowState.Maximized); break;
5903 SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5906 UnmapWindow(hwnd, WindowType.Both);
5912 internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max)
5914 Control ctrl = Control.FromHandle (handle);
5915 SetWindowMinMax (handle, maximized, min, max, ctrl != null ? ctrl.GetCreateParams () : null);
5918 internal void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max, CreateParams cp)
5924 hwnd = Hwnd.ObjectFromHandle(handle);
5929 min.Width = Math.Max (min.Width, SystemInformation.MinimumWindowSize.Width);
5930 min.Height = Math.Max (min.Height, SystemInformation.MinimumWindowSize.Height);
5932 hints = new XSizeHints();
5934 XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
5935 if ((min != Size.Empty) && (min.Width > 0) && (min.Height > 0)) {
5937 min = TranslateWindowSizeToXWindowSize (cp, min);
5938 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
5939 hints.min_width = min.Width;
5940 hints.min_height = min.Height;
5943 if ((max != Size.Empty) && (max.Width > 0) && (max.Height > 0)) {
5945 max = TranslateWindowSizeToXWindowSize (cp, max);
5946 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
5947 hints.max_width = max.Width;
5948 hints.max_height = max.Height;
5951 if (hints.flags != IntPtr.Zero) {
5952 // The Metacity team has decided that they won't care about this when clicking the maximize icon,
5953 // they will maximize the window to fill the screen/parent no matter what.
5954 // http://bugzilla.ximian.com/show_bug.cgi?id=80021
5955 XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints);
5958 if ((maximized != Rectangle.Empty) && (maximized.Width > 0) && (maximized.Height > 0)) {
5960 maximized.Size = TranslateWindowSizeToXWindowSize (cp);
5961 hints.flags = (IntPtr)XSizeHintsFlags.PPosition;
5962 hints.x = maximized.X;
5963 hints.y = maximized.Y;
5964 hints.width = maximized.Width;
5965 hints.height = maximized.Height;
5967 // Metacity does not seem to follow this constraint for maximized (zoomed) windows
5968 XSetZoomHints(DisplayHandle, hwnd.whole_window, ref hints);
5973 internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height)
5977 hwnd = Hwnd.ObjectFromHandle(handle);
5983 // Win32 automatically changes negative width/height to 0.
5989 // X requires a sanity check for width & height; otherwise it dies
5990 if (hwnd.zero_sized && width > 0 && height > 0) {
5992 MapWindow(hwnd, WindowType.Whole);
5994 hwnd.zero_sized = false;
5997 if ((width < 1) || (height < 1)) {
5998 hwnd.zero_sized = true;
5999 UnmapWindow(hwnd, WindowType.Whole);
6002 // Save a server roundtrip (and prevent a feedback loop)
6003 if ((hwnd.x == x) && (hwnd.y == y) &&
6004 (hwnd.width == width) && (hwnd.height == height)) {
6008 if (!hwnd.zero_sized) {
6013 hwnd.height = height;
6014 SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
6016 if (hwnd.fixed_size) {
6017 SetWindowMinMax(handle, Rectangle.Empty, new Size(width, height), new Size(width, height));
6021 Control ctrl = Control.FromHandle (handle);
6022 Size TranslatedSize = TranslateWindowSizeToXWindowSize (ctrl.GetCreateParams (), new Size (width, height));
6023 MoveResizeWindow (DisplayHandle, hwnd.whole_window, x, y, TranslatedSize.Width, TranslatedSize.Height);
6024 PerformNCCalc(hwnd);
6028 // Update our position/size immediately, so
6029 // that future calls to SetWindowPos aren't
6030 // kept from calling XMoveResizeWindow (by the
6031 // "Save a server roundtrip" block above).
6035 hwnd.height = height;
6036 hwnd.ClientRect = Rectangle.Empty;
6039 internal override void SetWindowState(IntPtr handle, FormWindowState state)
6041 FormWindowState current_state;
6044 hwnd = Hwnd.ObjectFromHandle(handle);
6046 current_state = GetWindowState(handle);
6048 if (current_state == state) {
6053 case FormWindowState.Normal: {
6055 if (current_state == FormWindowState.Minimized) {
6056 MapWindow(hwnd, WindowType.Both);
6057 } else if (current_state == FormWindowState.Maximized) {
6058 SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
6065 case FormWindowState.Minimized: {
6067 if (current_state == FormWindowState.Maximized) {
6068 SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
6070 XIconifyWindow(DisplayHandle, hwnd.whole_window, ScreenNo);
6075 case FormWindowState.Maximized: {
6077 if (current_state == FormWindowState.Minimized) {
6078 MapWindow(hwnd, WindowType.Both);
6081 SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)1 /* Add */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
6089 internal override void SetWindowStyle(IntPtr handle, CreateParams cp)
6093 hwnd = Hwnd.ObjectFromHandle(handle);
6094 SetHwndStyles(hwnd, cp);
6095 SetWMStyles(hwnd, cp);
6098 internal override double GetWindowTransparency(IntPtr handle)
6103 internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key)
6108 hwnd = Hwnd.ObjectFromHandle(handle);
6114 hwnd.opacity = (uint)(0xffffffff * transparency);
6115 opacity = (IntPtr)hwnd.opacity;
6117 if (transparency >= 1.0) {
6118 XDeleteProperty (DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_OPACITY);
6120 XChangeProperty (DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
6124 internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool top, bool bottom)
6126 Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
6134 XRaiseWindow(DisplayHandle, hwnd.whole_window);
6137 } else if (!bottom) {
6138 Hwnd after_hwnd = null;
6140 if (after_handle != IntPtr.Zero) {
6141 after_hwnd = Hwnd.ObjectFromHandle(after_handle);
6144 XWindowChanges values = new XWindowChanges();
6146 if (after_hwnd == null) {
6147 // Work around metacity 'issues'
6151 atoms[0] = unixtime();
6152 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_USER_TIME, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, atoms, 1);
6154 XRaiseWindow(DisplayHandle, hwnd.whole_window);
6155 SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
6157 //throw new ArgumentNullException("after_handle", "Need sibling to adjust z-order");
6160 values.sibling = after_hwnd.whole_window;
6161 values.stack_mode = StackMode.Below;
6164 XConfigureWindow(DisplayHandle, hwnd.whole_window, ChangeWindowFlags.CWStackMode | ChangeWindowFlags.CWSibling, ref values);
6169 XLowerWindow(DisplayHandle, hwnd.whole_window);
6176 internal override void ShowCursor(bool show)
6178 ; // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
6181 internal override object StartLoop(Thread thread)
6183 XEventQueue q = ThreadQueue(thread);
6187 internal override TransparencySupport SupportsTransparency()
6189 // We need to check if the x compositing manager is running
6190 return TransparencySupport.Set;
6193 internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt)
6195 GetSystrayManagerWindow();
6197 if (SystrayMgrWindow != IntPtr.Zero) {
6198 XSizeHints size_hints;
6201 hwnd = Hwnd.ObjectFromHandle(handle);
6202 DriverDebug("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
6205 if (hwnd.client_window != hwnd.whole_window) {
6206 Keyboard.DestroyICForWindow (hwnd.client_window);
6207 XDestroyWindow(DisplayHandle, hwnd.client_window);
6208 hwnd.client_window = hwnd.whole_window;
6211 /* by virtue of the way the tests are ordered when determining if it's PAINT
6212 or NCPAINT, client_window == whole_window will always be PAINT. So, if we're
6213 waiting on an nc_expose, drop it and remove the hwnd from the list (unless
6214 there's a pending expose). */
6215 if (hwnd.nc_expose_pending) {
6216 hwnd.nc_expose_pending = false;
6217 if (!hwnd.expose_pending)
6218 hwnd.Queue.Paint.Remove (hwnd);
6221 // We are going to be directly mapped by the system tray, so mark as mapped
6222 // so we can later properly unmap it.
6225 size_hints = new XSizeHints();
6227 size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
6229 size_hints.min_width = 24;
6230 size_hints.min_height = 24;
6231 size_hints.max_width = 24;
6232 size_hints.max_height = 24;
6233 size_hints.base_width = 24;
6234 size_hints.base_height = 24;
6236 XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints);
6238 int[] atoms = new int[2];
6239 atoms [0] = 1; // Version 1
6240 atoms [1] = 1; // we want to be mapped
6242 // This line cost me 3 days...
6243 XChangeProperty(DisplayHandle, hwnd.whole_window, _XEMBED_INFO, _XEMBED_INFO, 32, PropertyMode.Replace, atoms, 2);
6245 // Need to pick some reasonable defaults
6247 tt.AutomaticDelay = 350;
6248 tt.InitialDelay = 250;
6249 tt.ReshowDelay = 250;
6250 tt.ShowAlways = true;
6252 if ((tip != null) && (tip != string.Empty)) {
6253 tt.SetToolTip(Control.FromHandle(handle), tip);
6259 SendNetClientMessage(SystrayMgrWindow, _NET_SYSTEM_TRAY_OPCODE, IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
6267 internal override bool SystrayChange(IntPtr handle, string tip, Icon icon, ref ToolTip tt)
6271 control = Control.FromHandle(handle);
6272 if (control != null && tt != null) {
6273 tt.SetToolTip(control, tip);
6275 SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
6282 internal override void SystrayRemove(IntPtr handle, ref ToolTip tt)
6285 SetVisible (handle, false, false);
6287 // The caller can now re-dock it later...
6292 // Close any balloon window *we* fired.
6293 ThemeEngine.Current.HideBalloonWindow (handle);
6296 internal override void SystrayBalloon(IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
6298 ThemeEngine.Current.ShowBalloonWindow (handle, timeout, title, text, icon);
6299 SendMessage(handle, Msg.WM_USER, IntPtr.Zero, (IntPtr) Msg.NIN_BALLOONSHOW);
6302 internal override bool Text(IntPtr handle, string text)
6306 hwnd = Hwnd.ObjectFromHandle(handle);
6309 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_NAME, UTF8_STRING, 8,
6310 PropertyMode.Replace, text, Encoding.UTF8.GetByteCount (text));
6312 // XXX this has problems with UTF8.
6313 // we need to either use the actual
6314 // text if it's latin-1, or convert it
6315 // to compound text if it's in a
6316 // different charset.
6317 XStoreName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, text);
6322 internal override bool TranslateMessage(ref MSG msg)
6324 return Keyboard.TranslateMessage (ref msg);
6327 internal override void UpdateWindow(IntPtr handle)
6331 hwnd = Hwnd.ObjectFromHandle(handle);
6333 if (!hwnd.visible || !hwnd.expose_pending || !hwnd.Mapped) {
6337 SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
6338 hwnd.Queue.Paint.Remove(hwnd);
6341 internal override void CreateOffscreenDrawable (IntPtr handle,
6342 int width, int height,
6343 out object offscreen_drawable)
6346 int x_out, y_out, width_out, height_out, border_width_out, depth_out;
6348 XGetGeometry (DisplayHandle, handle,
6350 out x_out, out y_out,
6351 out width_out, out height_out,
6352 out border_width_out, out depth_out);
6354 IntPtr pixmap = XCreatePixmap (DisplayHandle, handle, width, height, depth_out);
6356 offscreen_drawable = pixmap;
6360 internal override void DestroyOffscreenDrawable (object offscreen_drawable)
6362 XFreePixmap (DisplayHandle, (IntPtr)offscreen_drawable);
6365 internal override Graphics GetOffscreenGraphics (object offscreen_drawable)
6367 return Graphics.FromHwnd ((IntPtr) offscreen_drawable);
6370 internal override void BlitFromOffscreen (IntPtr dest_handle,
6372 object offscreen_drawable,
6373 Graphics offscreen_dc,
6376 XGCValues gc_values;
6379 gc_values = new XGCValues();
6381 gc = XCreateGC (DisplayHandle, dest_handle, IntPtr.Zero, ref gc_values);
6383 XCopyArea (DisplayHandle, (IntPtr)offscreen_drawable, dest_handle,
6384 gc, r.X, r.Y, r.Width, r.Height, r.X, r.Y);
6386 XFreeGC (DisplayHandle, gc);
6389 #endregion // Public Static Methods
6392 internal override event EventHandler Idle;
6393 #endregion // Events
6398 #region Xcursor imports
6399 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
6400 internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
6402 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
6403 internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
6405 [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
6406 internal extern static void XcursorImagesDestroy (IntPtr images);
6408 [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
6409 internal extern static int XcursorGetDefaultSize (IntPtr display);
6411 [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
6412 internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
6414 [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
6415 internal extern static IntPtr XcursorGetTheme (IntPtr display);
6418 [DllImport ("libX11", EntryPoint="XOpenDisplay")]
6419 internal extern static IntPtr XOpenDisplay(IntPtr display);
6420 [DllImport ("libX11", EntryPoint="XCloseDisplay")]
6421 internal extern static int XCloseDisplay(IntPtr display);
6422 [DllImport ("libX11", EntryPoint="XSynchronize")]
6423 internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
6425 [DllImport ("libX11", EntryPoint="XCreateWindow")]
6426 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, UIntPtr valuemask, ref XSetWindowAttributes attributes);
6427 internal static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes)
6429 DebugHelper.TraceWriteLine ("XCreateWindow");
6430 return _XCreateWindow(display, parent, x, y, width, height,
6431 border_width, depth, xclass, visual, valuemask, ref attributes);
6433 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
6434 internal extern static IntPtr _XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
6435 internal static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background)
6437 DebugHelper.TraceWriteLine ("XCreateSimpleWindow");
6438 return _XCreateSimpleWindow(display, parent, x, y, width, height, border_width, border, background);
6440 [DllImport ("libX11", EntryPoint="XMapWindow")]
6441 internal extern static int _XMapWindow(IntPtr display, IntPtr window);
6442 internal static int XMapWindow(IntPtr display, IntPtr window)
6444 DebugHelper.TraceWriteLine ("XMapWindow");
6445 return _XMapWindow(display, window);
6447 [DllImport ("libX11", EntryPoint="XMapRaised")]
6448 internal extern static int _XMapRaised(IntPtr display, IntPtr window);
6449 internal static int XMapRaised(IntPtr display, IntPtr window)
6451 DebugHelper.TraceWriteLine ("XMapRaised");
6452 return _XMapRaised(display, window);
6454 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
6455 internal extern static int _XUnmapWindow(IntPtr display, IntPtr window);
6456 internal static int XUnmapWindow(IntPtr display, IntPtr window)
6458 DebugHelper.TraceWriteLine ("XUnmapWindow");
6459 return _XUnmapWindow(display, window);
6461 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
6462 internal extern static int _XMapSubindows(IntPtr display, IntPtr window);
6463 internal static int XMapSubindows(IntPtr display, IntPtr window)
6465 DebugHelper.TraceWriteLine ("XMapSubindows");
6466 return _XMapSubindows(display, window);
6468 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
6469 internal extern static int _XUnmapSubwindows(IntPtr display, IntPtr window);
6470 internal static int XUnmapSubwindows(IntPtr display, IntPtr window)
6472 DebugHelper.TraceWriteLine ("XUnmapSubwindows");
6473 return _XUnmapSubwindows(display, window);
6475 [DllImport ("libX11", EntryPoint="XRootWindow")]
6476 internal extern static IntPtr _XRootWindow(IntPtr display, int screen_number);
6477 internal static IntPtr XRootWindow(IntPtr display, int screen_number)
6479 DebugHelper.TraceWriteLine ("XRootWindow");
6480 return _XRootWindow(display, screen_number);
6482 [DllImport ("libX11", EntryPoint="XNextEvent")]
6483 internal extern static IntPtr _XNextEvent(IntPtr display, ref XEvent xevent);
6484 internal static IntPtr XNextEvent(IntPtr display, ref XEvent xevent)
6486 DebugHelper.TraceWriteLine ("XNextEvent");
6487 return _XNextEvent(display, ref xevent);
6489 [DllImport ("libX11", EntryPoint="XConnectionNumber")]
6490 internal extern static int _XConnectionNumber (IntPtr display);
6491 internal static int XConnectionNumber (IntPtr display)
6493 DebugHelper.TraceWriteLine ("XConnectionNumber");
6494 return _XConnectionNumber (display);
6496 [DllImport ("libX11", EntryPoint="XPending")]
6497 internal extern static int _XPending (IntPtr display);
6498 internal static int XPending (IntPtr display)
6500 DebugHelper.TraceWriteLine ("XPending");
6501 DebugHelper.DumpCallers (3);
6502 return _XPending (display);
6504 [DllImport ("libX11", EntryPoint="XSelectInput")]
6505 internal extern static IntPtr _XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
6506 internal static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask)
6508 DebugHelper.TraceWriteLine ("XSelectInput");
6509 return _XSelectInput(display, window, mask);
6512 [DllImport ("libX11", EntryPoint="XDestroyWindow")]
6513 internal extern static int _XDestroyWindow(IntPtr display, IntPtr window);
6514 internal static int XDestroyWindow(IntPtr display, IntPtr window)
6516 DebugHelper.TraceWriteLine ("XDestroyWindow 0x{0:x}", window.ToInt32());
6517 return _XDestroyWindow(display, window);
6520 [DllImport ("libX11", EntryPoint="XReparentWindow")]
6521 internal extern static int _XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
6522 internal static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y)
6524 DebugHelper.TraceWriteLine ("XReparentWindow");
6525 return _XReparentWindow(display, window, parent, x, y);
6528 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
6529 extern static int _XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
6530 static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height) {
6531 DebugHelper.TraceWriteLine ("XMoveResizeWindow");
6532 return _XMoveResizeWindow(display, window, x, y, width, height);
6535 internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
6537 int ret = XMoveResizeWindow (display, window, x, y, width, height);
6538 Keyboard.MoveCurrentCaretPos ();
6542 [DllImport ("libX11", EntryPoint="XResizeWindow")]
6543 internal extern static int _XResizeWindow(IntPtr display, IntPtr window, int width, int height);
6544 internal static int XResizeWindow(IntPtr display, IntPtr window, int width, int height)
6546 DebugHelper.TraceWriteLine ("XResizeWindow");
6547 return _XResizeWindow(display, window, width, height);
6550 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
6551 internal extern static int _XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
6552 internal static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes)
6554 DebugHelper.TraceWriteLine ("XGetWindowAttributes");
6555 return _XGetWindowAttributes(display, window, ref attributes);
6558 [DllImport ("libX11", EntryPoint="XFlush")]
6559 internal extern static int _XFlush(IntPtr display);
6560 internal static int XFlush(IntPtr display)
6562 DebugHelper.TraceWriteLine ("XFlush");
6563 return _XFlush(display);
6566 [DllImport ("libX11", EntryPoint="XSetWMName")]
6567 internal extern static int _XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
6568 internal static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop)
6570 DebugHelper.TraceWriteLine ("XSetWMName");
6571 return _XSetWMName(display, window, ref text_prop);
6574 [DllImport ("libX11", EntryPoint="XStoreName")]
6575 internal extern static int _XStoreName(IntPtr display, IntPtr window, string window_name);
6576 internal static int XStoreName(IntPtr display, IntPtr window, string window_name)
6578 DebugHelper.TraceWriteLine ("XStoreName");
6579 return _XStoreName(display, window, window_name);
6582 [DllImport ("libX11", EntryPoint="XFetchName")]
6583 internal extern static int _XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
6584 internal static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name)
6586 DebugHelper.TraceWriteLine ("XFetchName");
6587 return _XFetchName(display, window, ref window_name);
6590 [DllImport ("libX11", EntryPoint="XSendEvent")]
6591 internal extern static int _XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
6592 internal static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event)
6594 DebugHelper.TraceWriteLine ("XSendEvent");
6595 return _XSendEvent(display, window, propagate, event_mask, ref send_event);
6598 [DllImport ("libX11", EntryPoint="XQueryTree")]
6599 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);
6600 internal static int XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return)
6602 DebugHelper.TraceWriteLine ("XQueryTree");
6603 return _XQueryTree(display, window, out root_return, out parent_return, out children_return, out nchildren_return);
6606 [DllImport ("libX11", EntryPoint="XFree")]
6607 internal extern static int _XFree(IntPtr data);
6608 internal static int XFree(IntPtr data)
6610 DebugHelper.TraceWriteLine ("XFree");
6611 return _XFree(data);
6614 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
6615 internal extern static int _XRaiseWindow(IntPtr display, IntPtr window);
6616 internal static int XRaiseWindow(IntPtr display, IntPtr window)
6618 DebugHelper.TraceWriteLine ("XRaiseWindow");
6619 return _XRaiseWindow(display, window);
6622 [DllImport ("libX11", EntryPoint="XLowerWindow")]
6623 internal extern static uint _XLowerWindow(IntPtr display, IntPtr window);
6624 internal static uint XLowerWindow(IntPtr display, IntPtr window)
6626 DebugHelper.TraceWriteLine ("XLowerWindow");
6627 return _XLowerWindow(display, window);
6630 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
6631 internal extern static uint _XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
6632 internal static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values)
6634 DebugHelper.TraceWriteLine ("XConfigureWindow");
6635 return _XConfigureWindow(display, window, value_mask, ref values);
6638 [DllImport ("libX11", EntryPoint="XInternAtom")]
6639 internal extern static IntPtr _XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
6640 internal static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists)
6642 DebugHelper.TraceWriteLine ("XInternAtom");
6643 return _XInternAtom(display, atom_name, only_if_exists);
6646 [DllImport ("libX11", EntryPoint="XInternAtoms")]
6647 internal extern static int _XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
6648 internal static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms)
6650 DebugHelper.TraceWriteLine ("XInternAtoms");
6651 return _XInternAtoms(display, atom_names, atom_count, only_if_exists, atoms);
6654 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
6655 internal extern static int _XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
6656 internal static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count)
6658 DebugHelper.TraceWriteLine ("XSetWMProtocols");
6659 return _XSetWMProtocols(display, window, protocols, count);
6662 [DllImport ("libX11", EntryPoint="XGrabPointer")]
6663 internal extern static int _XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp);
6664 internal static int XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp)
6666 DebugHelper.TraceWriteLine ("XGrabPointer");
6667 return _XGrabPointer(display, window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, timestamp);
6670 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
6671 internal extern static int _XUngrabPointer(IntPtr display, IntPtr timestamp);
6672 internal static int XUngrabPointer(IntPtr display, IntPtr timestamp)
6674 DebugHelper.TraceWriteLine ("XUngrabPointer");
6675 return _XUngrabPointer(display, timestamp);
6678 [DllImport ("libX11", EntryPoint="XQueryPointer")]
6679 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);
6680 internal 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)
6682 DebugHelper.TraceWriteLine ("XQueryPointer");
6683 return _XQueryPointer(display, window, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
6686 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
6687 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);
6688 internal 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)
6690 DebugHelper.TraceWriteLine ("XTranslateCoordinates");
6691 return _XTranslateCoordinates (display, src_w, dest_w, src_x, src_y, out intdest_x_return, out dest_y_return, out child_return);
6694 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6695 internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth);
6696 internal static bool XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth)
6698 DebugHelper.TraceWriteLine ("XGetGeometry");
6699 return _XGetGeometry(display, window, out root, out x, out y, out width, out height, out border_width, out depth);
6702 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6703 internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, out int width, out int height, IntPtr border_width, IntPtr depth);
6704 internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, out int width, out int height, IntPtr border_width, IntPtr depth)
6706 DebugHelper.TraceWriteLine ("XGetGeometry");
6707 return _XGetGeometry(display, window, root, out x, out y, out width, out height, border_width, depth);
6710 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6711 internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth);
6712 internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth)
6714 DebugHelper.TraceWriteLine ("XGetGeometry");
6715 return _XGetGeometry(display, window, root, out x, out y, width, height, border_width, depth);
6718 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6719 internal extern static bool _XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth);
6720 internal static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth)
6722 DebugHelper.TraceWriteLine ("XGetGeometry");
6723 return _XGetGeometry(display, window, root, x, y, out width, out height, border_width, depth);
6726 [DllImport ("libX11", EntryPoint="XWarpPointer")]
6727 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);
6728 internal 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)
6730 DebugHelper.TraceWriteLine ("XWarpPointer");
6731 return _XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width, src_height, dest_x, dest_y);
6734 [DllImport ("libX11", EntryPoint="XClearWindow")]
6735 internal extern static int _XClearWindow(IntPtr display, IntPtr window);
6736 internal static int XClearWindow(IntPtr display, IntPtr window)
6738 DebugHelper.TraceWriteLine ("XClearWindow");
6739 return _XClearWindow(display, window);
6742 [DllImport ("libX11", EntryPoint="XClearArea")]
6743 internal extern static int _XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
6744 internal static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures)
6746 DebugHelper.TraceWriteLine ("XClearArea");
6747 return _XClearArea(display, window, x, y, width, height, exposures);
6751 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
6752 internal extern static IntPtr _XDefaultScreenOfDisplay(IntPtr display);
6753 internal static IntPtr XDefaultScreenOfDisplay(IntPtr display)
6755 DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6756 return _XDefaultScreenOfDisplay(display);
6759 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
6760 internal extern static int _XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
6761 internal static int XDefaultScreenOfDisplay(IntPtr display, IntPtr Screen)
6763 DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6764 return _XScreenNumberOfScreen(display, Screen);
6767 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
6768 internal extern static IntPtr _XDefaultVisual(IntPtr display, int screen_number);
6769 internal static IntPtr XDefaultScreenOfDisplay(IntPtr display, int screen_number)
6771 DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6772 return _XDefaultVisual(display, screen_number);
6775 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
6776 internal extern static uint _XDefaultDepth(IntPtr display, int screen_number);
6777 internal static uint XDefaultDepth(IntPtr display, int screen_number)
6779 DebugHelper.TraceWriteLine ("XDefaultDepth");
6780 return _XDefaultDepth(display, screen_number);
6783 [DllImport ("libX11", EntryPoint="XDefaultScreen")]
6784 internal extern static int _XDefaultScreen(IntPtr display);
6785 internal static int XDefaultScreen(IntPtr display)
6787 DebugHelper.TraceWriteLine ("XDefaultScreen");
6788 return _XDefaultScreen(display);
6791 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
6792 internal extern static IntPtr _XDefaultColormap(IntPtr display, int screen_number);
6793 internal static IntPtr XDefaultColormap(IntPtr display, int screen_number)
6795 DebugHelper.TraceWriteLine ("XDefaultColormap");
6796 return _XDefaultColormap(display, screen_number);
6799 [DllImport ("libX11", EntryPoint="XLookupColor")]
6800 internal extern static int _XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
6801 internal static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color)
6803 DebugHelper.TraceWriteLine ("XLookupColor");
6804 return _XLookupColor(display, Colormap, Coloranem, ref exact_def_color, ref screen_def_color);
6807 [DllImport ("libX11", EntryPoint="XAllocColor")]
6808 internal extern static int _XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
6809 internal static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def)
6811 DebugHelper.TraceWriteLine ("XAllocColor");
6812 return _XAllocColor(display, Colormap, ref colorcell_def);
6815 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
6816 internal extern static int _XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
6817 internal static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window)
6819 DebugHelper.TraceWriteLine ("XSetTransientForHint");
6820 return _XSetTransientForHint(display, window, prop_window);
6823 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6824 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
6825 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements)
6827 DebugHelper.TraceWriteLine ("XChangeProperty");
6828 return _XChangeProperty(display, window, property, type, format, mode, ref data, nelements);
6831 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6832 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
6833 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements)
6835 DebugHelper.TraceWriteLine ("XChangeProperty");
6836 return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
6839 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6840 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
6841 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements)
6843 DebugHelper.TraceWriteLine ("XChangeProperty");
6844 return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
6847 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6848 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
6849 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements)
6851 DebugHelper.TraceWriteLine ("XChangeProperty");
6852 return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6855 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6856 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
6857 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements)
6859 DebugHelper.TraceWriteLine ("XChangeProperty");
6860 return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6863 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6864 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
6865 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements)
6867 DebugHelper.TraceWriteLine ("XChangeProperty");
6868 return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6871 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6872 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
6873 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements)
6875 DebugHelper.TraceWriteLine ("XChangeProperty");
6876 return _XChangeProperty(display, window, property, type, format, mode, atoms, nelements);
6879 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
6880 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
6881 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length)
6883 DebugHelper.TraceWriteLine ("XChangeProperty");
6884 return _XChangeProperty(display, window, property, type, format, mode, text, text_length);
6887 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
6888 internal extern static int _XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
6889 internal static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property)
6891 DebugHelper.TraceWriteLine ("XDeleteProperty");
6892 return _XDeleteProperty(display, window, property);
6896 [DllImport ("libX11", EntryPoint="XCreateGC")]
6897 internal extern static IntPtr _XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
6898 internal static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values)
6900 DebugHelper.TraceWriteLine ("XCreateGC");
6901 return _XCreateGC(display, window, valuemask, ref values);
6904 [DllImport ("libX11", EntryPoint="XFreeGC")]
6905 internal extern static int _XFreeGC(IntPtr display, IntPtr gc);
6906 internal static int XFreeGC(IntPtr display, IntPtr gc)
6908 DebugHelper.TraceWriteLine ("XFreeGC");
6909 return _XFreeGC(display, gc);
6912 [DllImport ("libX11", EntryPoint="XSetFunction")]
6913 internal extern static int _XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
6914 internal static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function)
6916 DebugHelper.TraceWriteLine ("XSetFunction");
6917 return _XSetFunction(display, gc, function);
6920 [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
6921 internal extern static int _XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
6922 internal static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style)
6924 DebugHelper.TraceWriteLine ("XSetLineAttributes");
6925 return _XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style);
6928 [DllImport ("libX11", EntryPoint="XDrawLine")]
6929 internal extern static int _XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
6930 internal static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2)
6932 DebugHelper.TraceWriteLine ("XDrawLine");
6933 return _XDrawLine(display, drawable, gc, x1, y1, x2, y2);
6936 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
6937 internal extern static int _XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
6938 internal static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height)
6940 DebugHelper.TraceWriteLine ("XDrawRectangle");
6941 return _XDrawRectangle(display, drawable, gc, x1, y1, width, height);
6944 [DllImport ("libX11", EntryPoint="XFillRectangle")]
6945 internal extern static int _XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
6946 internal static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height)
6948 DebugHelper.TraceWriteLine ("XFillRectangle");
6949 return _XFillRectangle(display, drawable, gc, x1, y1, width, height);
6952 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
6953 internal extern static int _XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
6954 internal static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background)
6956 DebugHelper.TraceWriteLine ("XSetWindowBackground");
6957 return _XSetWindowBackground(display, window, background);
6960 [DllImport ("libX11", EntryPoint="XCopyArea")]
6961 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);
6962 internal 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)
6964 DebugHelper.TraceWriteLine ("XCopyArea");
6965 return _XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y);
6968 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
6969 internal extern static int _XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop);
6970 internal static int XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop)
6972 DebugHelper.TraceWriteLine ("XGetWindowProperty");
6973 return _XGetWindowProperty(display, window, atom, long_offset, long_length, delete, req_type, out actual_type, out actual_format, out nitems, out bytes_after, ref prop);
6976 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
6977 internal extern static int _XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
6978 internal static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time)
6980 DebugHelper.TraceWriteLine ("XSetInputFocus");
6981 return _XSetInputFocus(display, window, revert_to, time);
6984 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
6985 internal extern static int _XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
6986 internal static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number)
6988 DebugHelper.TraceWriteLine ("XIconifyWindow");
6989 return _XIconifyWindow(display, window, screen_number);
6992 [DllImport ("libX11", EntryPoint="XDefineCursor")]
6993 internal extern static int _XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
6994 internal static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor)
6996 DebugHelper.TraceWriteLine ("XDefineCursor");
6997 return _XDefineCursor(display, window, cursor);
7000 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
7001 internal extern static int _XUndefineCursor(IntPtr display, IntPtr window);
7002 internal static int XUndefineCursor(IntPtr display, IntPtr window)
7004 DebugHelper.TraceWriteLine ("XUndefineCursor");
7005 return _XUndefineCursor(display, window);
7008 [DllImport ("libX11", EntryPoint="XFreeCursor")]
7009 internal extern static int _XFreeCursor(IntPtr display, IntPtr cursor);
7010 internal static int XFreeCursor(IntPtr display, IntPtr cursor)
7012 DebugHelper.TraceWriteLine ("XFreeCursor");
7013 return _XFreeCursor(display, cursor);
7016 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
7017 internal extern static IntPtr _XCreateFontCursor(IntPtr display, CursorFontShape shape);
7018 internal static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape)
7020 DebugHelper.TraceWriteLine ("XCreateFontCursor");
7021 return _XCreateFontCursor(display, shape);
7024 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
7025 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);
7026 internal static IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot)
7028 DebugHelper.TraceWriteLine ("XCreatePixmapCursor");
7029 return _XCreatePixmapCursor(display, source, mask, ref foreground_color, ref background_color, x_hot, y_hot);
7032 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
7033 internal extern static IntPtr _XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
7034 internal static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth)
7036 DebugHelper.TraceWriteLine ("XCreatePixmapFromBitmapData");
7037 return _XCreatePixmapFromBitmapData(display, drawable, data, width, height, fg, bg, depth);
7040 [DllImport ("libX11", EntryPoint="XCreatePixmap")]
7041 internal extern static IntPtr _XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
7042 internal static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth)
7044 DebugHelper.TraceWriteLine ("XCreatePixmap");
7045 return _XCreatePixmap(display, d, width, height, depth);
7048 [DllImport ("libX11", EntryPoint="XFreePixmap")]
7049 internal extern static IntPtr _XFreePixmap(IntPtr display, IntPtr pixmap);
7050 internal static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap)
7052 DebugHelper.TraceWriteLine ("XFreePixmap");
7053 return _XFreePixmap(display, pixmap);
7056 [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
7057 internal extern static int _XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
7058 internal static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height)
7060 DebugHelper.TraceWriteLine ("XQueryBestCursor");
7061 return _XQueryBestCursor(display, drawable, width, height, out best_width, out best_height);
7064 [DllImport ("libX11", EntryPoint="XQueryExtension")]
7065 internal extern static int _XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
7066 internal static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error)
7068 DebugHelper.TraceWriteLine ("XQueryExtension");
7069 return _XQueryExtension(display, extension_name, ref major, ref first_event, ref first_error);
7072 [DllImport ("libX11", EntryPoint="XWhitePixel")]
7073 internal extern static IntPtr _XWhitePixel(IntPtr display, int screen_no);
7074 internal static IntPtr XWhitePixel(IntPtr display, int screen_no)
7076 DebugHelper.TraceWriteLine ("XWhitePixel");
7077 return _XWhitePixel(display, screen_no);
7080 [DllImport ("libX11", EntryPoint="XBlackPixel")]
7081 internal extern static IntPtr _XBlackPixel(IntPtr display, int screen_no);
7082 internal static IntPtr XBlackPixel(IntPtr display, int screen_no)
7084 DebugHelper.TraceWriteLine ("XBlackPixel");
7085 return _XBlackPixel(display, screen_no);
7088 [DllImport ("libX11", EntryPoint="XGrabServer")]
7089 internal extern static void _XGrabServer(IntPtr display);
7090 internal static void XGrabServer(IntPtr display)
7092 DebugHelper.TraceWriteLine ("XGrabServer");
7093 _XGrabServer(display);
7096 [DllImport ("libX11", EntryPoint="XUngrabServer")]
7097 internal extern static void _XUngrabServer(IntPtr display);
7098 internal static void XUngrabServer(IntPtr display)
7100 DebugHelper.TraceWriteLine ("XUngrabServer");
7101 _XUngrabServer(display);
7104 [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
7105 internal extern static void _XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
7106 internal static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return)
7108 DebugHelper.TraceWriteLine ("XGetWMNormalHints");
7109 _XGetWMNormalHints(display, window, ref hints, out supplied_return);
7112 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
7113 internal extern static void _XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7114 internal static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints)
7116 DebugHelper.TraceWriteLine ("XSetWMNormalHints");
7117 _XSetWMNormalHints(display, window, ref hints);
7120 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
7121 internal extern static void _XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7122 internal static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints)
7124 DebugHelper.TraceWriteLine ("XSetZoomHints");
7125 _XSetZoomHints(display, window, ref hints);
7128 [DllImport ("libX11", EntryPoint="XSetWMHints")]
7129 internal extern static void _XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
7130 internal static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints)
7132 DebugHelper.TraceWriteLine ("XSetWMHints");
7133 _XSetWMHints(display, window, ref wmhints);
7136 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
7137 internal extern static int _XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
7138 internal static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count)
7140 DebugHelper.TraceWriteLine ("XGetIconSizes");
7141 return _XGetIconSizes(display, window, out size_list, out count);
7144 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
7145 internal extern static IntPtr _XSetErrorHandler(XErrorHandler error_handler);
7146 internal static IntPtr XSetErrorHandler(XErrorHandler error_handler)
7148 DebugHelper.TraceWriteLine ("XSetErrorHandler");
7149 return _XSetErrorHandler(error_handler);
7152 [DllImport ("libX11", EntryPoint="XGetErrorText")]
7153 internal extern static IntPtr _XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
7154 internal static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length)
7156 DebugHelper.TraceWriteLine ("XGetErrorText");
7157 return _XGetErrorText(display, code, buffer, length);
7160 [DllImport ("libX11", EntryPoint="XInitThreads")]
7161 internal extern static int _XInitThreads();
7162 internal static int XInitThreads()
7164 DebugHelper.TraceWriteLine ("XInitThreads");
7165 return _XInitThreads();
7168 [DllImport ("libX11", EntryPoint="XConvertSelection")]
7169 internal extern static int _XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
7170 internal static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time)
7172 DebugHelper.TraceWriteLine ("XConvertSelection");
7173 return _XConvertSelection(display, selection, target, property, requestor, time);
7176 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
7177 internal extern static IntPtr _XGetSelectionOwner(IntPtr display, IntPtr selection);
7178 internal static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection)
7180 DebugHelper.TraceWriteLine ("XGetSelectionOwner");
7181 return _XGetSelectionOwner(display, selection);
7184 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
7185 internal extern static int _XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
7186 internal static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time)
7188 DebugHelper.TraceWriteLine ("XSetSelectionOwner");
7189 return _XSetSelectionOwner(display, selection, owner, time);
7192 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
7193 internal extern static int _XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
7194 internal static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask)
7196 DebugHelper.TraceWriteLine ("XSetPlaneMask");
7197 return _XSetPlaneMask(display, gc, mask);
7200 [DllImport ("libX11", EntryPoint="XSetForeground")]
7201 internal extern static int _XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
7202 internal static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground)
7204 DebugHelper.TraceWriteLine ("XSetForeground");
7205 return _XSetForeground(display, gc, foreground);
7208 [DllImport ("libX11", EntryPoint="XSetBackground")]
7209 internal extern static int _XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
7210 internal static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background)
7212 DebugHelper.TraceWriteLine ("XSetBackground");
7213 return _XSetBackground(display, gc, background);
7216 [DllImport ("libX11", EntryPoint="XBell")]
7217 internal extern static int _XBell(IntPtr display, int percent);
7218 internal static int XBell(IntPtr display, int percent)
7220 DebugHelper.TraceWriteLine ("XBell");
7221 return _XBell(display, percent);
7224 [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
7225 internal extern static int _XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
7226 internal static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time)
7228 DebugHelper.TraceWriteLine ("XChangeActivePointerGrab");
7229 return _XChangeActivePointerGrab (display, event_mask, cursor, time);
7232 [DllImport ("libX11", EntryPoint="XFilterEvent")]
7233 internal extern static bool _XFilterEvent(ref XEvent xevent, IntPtr window);
7234 internal static bool XFilterEvent(ref XEvent xevent, IntPtr window)
7236 DebugHelper.TraceWriteLine ("XFilterEvent");
7237 return _XFilterEvent(ref xevent, window);
7240 [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
7241 internal extern static void _XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
7242 internal static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported)
7244 DebugHelper.TraceWriteLine ("XkbSetDetectableAutoRepeat");
7245 _XkbSetDetectableAutoRepeat (display, detectable, supported);
7248 [DllImport ("libX11", EntryPoint="XPeekEvent")]
7249 internal extern static void _XPeekEvent (IntPtr display, ref XEvent xevent);
7250 internal static void XPeekEvent (IntPtr display, ref XEvent xevent)
7252 DebugHelper.TraceWriteLine ("XPeekEvent");
7253 _XPeekEvent (display, ref xevent);
7256 [DllImport ("libX11", EntryPoint="XIfEvent")]
7257 internal extern static void _XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
7258 internal static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg)
7260 DebugHelper.TraceWriteLine ("XIfEvent");
7261 _XIfEvent (display, ref xevent, event_predicate, arg);
7265 #region Xinerama imports
7266 [DllImport ("libXinerama", EntryPoint="XineramaQueryScreens")]
7267 extern static IntPtr _XineramaQueryScreens (IntPtr display, out int number);
7268 internal static IntPtr XineramaQueryScreens (IntPtr display, out int number)
7270 DebugHelper.TraceWriteLine ("XineramaQueryScreens");
7271 return _XineramaQueryScreens (display, out number);
7274 [DllImport ("libXinerama", EntryPoint="XineramaIsActive")]
7275 extern static bool _XineramaIsActive (IntPtr display);
7276 static bool XineramaNotInstalled;
7278 internal static bool XineramaIsActive (IntPtr display)
7280 DebugHelper.TraceWriteLine ("XineramaIsActive");
7282 if (XineramaNotInstalled)
7285 return _XineramaIsActive (display);
7286 } catch (DllNotFoundException) {
7287 // Xinerama isn't installed
7288 XineramaNotInstalled = true;
7294 #else //no TRACE defined
7296 #region Xcursor imports
7297 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
7298 internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
7300 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
7301 internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
7303 [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
7304 internal extern static void XcursorImagesDestroy (IntPtr images);
7306 [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
7307 internal extern static int XcursorGetDefaultSize (IntPtr display);
7309 [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
7310 internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
7312 [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
7313 internal extern static IntPtr XcursorGetTheme (IntPtr display);
7316 [DllImport ("libX11", EntryPoint="XOpenDisplay")]
7317 internal extern static IntPtr XOpenDisplay(IntPtr display);
7318 [DllImport ("libX11", EntryPoint="XCloseDisplay")]
7319 internal extern static int XCloseDisplay(IntPtr display);
7320 [DllImport ("libX11", EntryPoint="XSynchronize")]
7321 internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
7323 [DllImport ("libX11", EntryPoint="XCreateWindow")]
7324 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, UIntPtr valuemask, ref XSetWindowAttributes attributes);
7326 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
7327 internal extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
7329 [DllImport ("libX11", EntryPoint="XMapWindow")]
7330 internal extern static int XMapWindow(IntPtr display, IntPtr window);
7332 [DllImport ("libX11", EntryPoint="XMapRaised")]
7333 internal extern static int XMapRaised(IntPtr display, IntPtr window);
7335 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
7336 internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
7338 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
7339 internal extern static int XMapSubindows(IntPtr display, IntPtr window);
7341 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
7342 internal extern static int XUnmapSubwindows(IntPtr display, IntPtr window);
7344 [DllImport ("libX11", EntryPoint="XRootWindow")]
7345 internal extern static IntPtr XRootWindow(IntPtr display, int screen_number);
7347 [DllImport ("libX11", EntryPoint="XNextEvent")]
7348 internal extern static IntPtr XNextEvent(IntPtr display, ref XEvent xevent);
7350 [DllImport ("libX11", EntryPoint="XConnectionNumber")]
7351 internal extern static int XConnectionNumber (IntPtr display);
7353 [DllImport ("libX11", EntryPoint="XPending")]
7354 internal extern static int XPending (IntPtr display);
7356 [DllImport ("libX11", EntryPoint="XSelectInput")]
7357 internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
7359 [DllImport ("libX11", EntryPoint="XDestroyWindow")]
7360 internal extern static int XDestroyWindow(IntPtr display, IntPtr window);
7362 [DllImport ("libX11", EntryPoint="XReparentWindow")]
7363 internal extern static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
7365 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
7366 extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
7367 internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
7369 int ret = XMoveResizeWindow (display, window, x, y, width, height);
7370 Keyboard.MoveCurrentCaretPos ();
7374 [DllImport ("libX11", EntryPoint="XResizeWindow")]
7375 internal extern static int XResizeWindow(IntPtr display, IntPtr window, int width, int height);
7377 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
7378 internal extern static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
7380 [DllImport ("libX11", EntryPoint="XFlush")]
7381 internal extern static int XFlush(IntPtr display);
7383 [DllImport ("libX11", EntryPoint="XSetWMName")]
7384 internal extern static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
7386 [DllImport ("libX11", EntryPoint="XStoreName")]
7387 internal extern static int XStoreName(IntPtr display, IntPtr window, string window_name);
7389 [DllImport ("libX11", EntryPoint="XFetchName")]
7390 internal extern static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
7392 [DllImport ("libX11", EntryPoint="XSendEvent")]
7393 internal extern static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
7395 [DllImport ("libX11", EntryPoint="XQueryTree")]
7396 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);
7398 [DllImport ("libX11", EntryPoint="XFree")]
7399 internal extern static int XFree(IntPtr data);
7401 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
7402 internal extern static int XRaiseWindow(IntPtr display, IntPtr window);
7404 [DllImport ("libX11", EntryPoint="XLowerWindow")]
7405 internal extern static uint XLowerWindow(IntPtr display, IntPtr window);
7407 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
7408 internal extern static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
7410 [DllImport ("libX11", EntryPoint="XInternAtom")]
7411 internal extern static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
7413 [DllImport ("libX11", EntryPoint="XInternAtoms")]
7414 internal extern static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
7416 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
7417 internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
7419 [DllImport ("libX11", EntryPoint="XGrabPointer")]
7420 internal extern static int XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, IntPtr cursor, IntPtr timestamp);
7422 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
7423 internal extern static int XUngrabPointer(IntPtr display, IntPtr timestamp);
7425 [DllImport ("libX11", EntryPoint="XQueryPointer")]
7426 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);
7428 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
7429 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);
7431 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7432 internal extern static bool XGetGeometry(IntPtr display, IntPtr window, out IntPtr root, out int x, out int y, out int width, out int height, out int border_width, out int depth);
7434 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7435 internal extern static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, out int width, out int height, IntPtr border_width, IntPtr depth);
7437 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7438 internal extern static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, out int x, out int y, IntPtr width, IntPtr height, IntPtr border_width, IntPtr depth);
7440 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7441 internal extern static bool XGetGeometry(IntPtr display, IntPtr window, IntPtr root, IntPtr x, IntPtr y, out int width, out int height, IntPtr border_width, IntPtr depth);
7443 [DllImport ("libX11", EntryPoint="XWarpPointer")]
7444 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);
7446 [DllImport ("libX11", EntryPoint="XClearWindow")]
7447 internal extern static int XClearWindow(IntPtr display, IntPtr window);
7449 [DllImport ("libX11", EntryPoint="XClearArea")]
7450 internal extern static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
7453 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
7454 internal extern static IntPtr XDefaultScreenOfDisplay(IntPtr display);
7456 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
7457 internal extern static int XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
7459 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
7460 internal extern static IntPtr XDefaultVisual(IntPtr display, int screen_number);
7462 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
7463 internal extern static uint XDefaultDepth(IntPtr display, int screen_number);
7465 [DllImport ("libX11", EntryPoint="XDefaultScreen")]
7466 internal extern static int XDefaultScreen(IntPtr display);
7468 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
7469 internal extern static IntPtr XDefaultColormap(IntPtr display, int screen_number);
7471 [DllImport ("libX11", EntryPoint="XLookupColor")]
7472 internal extern static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
7474 [DllImport ("libX11", EntryPoint="XAllocColor")]
7475 internal extern static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
7477 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
7478 internal extern static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
7480 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7481 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
7483 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7484 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
7486 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7487 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
7489 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7490 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
7492 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7493 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
7495 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7496 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
7498 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7499 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
7501 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
7502 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
7504 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
7505 internal extern static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
7508 [DllImport ("libX11", EntryPoint="XCreateGC")]
7509 internal extern static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
7511 [DllImport ("libX11", EntryPoint="XFreeGC")]
7512 internal extern static int XFreeGC(IntPtr display, IntPtr gc);
7514 [DllImport ("libX11", EntryPoint="XSetFunction")]
7515 internal extern static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
7517 [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
7518 internal extern static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
7520 [DllImport ("libX11", EntryPoint="XDrawLine")]
7521 internal extern static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
7523 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
7524 internal extern static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
7526 [DllImport ("libX11", EntryPoint="XFillRectangle")]
7527 internal extern static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
7529 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
7530 internal extern static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
7532 [DllImport ("libX11", EntryPoint="XCopyArea")]
7533 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);
7535 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
7536 internal extern static int XGetWindowProperty(IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, out int actual_format, out IntPtr nitems, out IntPtr bytes_after, ref IntPtr prop);
7538 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
7539 internal extern static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
7541 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
7542 internal extern static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
7544 [DllImport ("libX11", EntryPoint="XDefineCursor")]
7545 internal extern static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
7547 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
7548 internal extern static int XUndefineCursor(IntPtr display, IntPtr window);
7550 [DllImport ("libX11", EntryPoint="XFreeCursor")]
7551 internal extern static int XFreeCursor(IntPtr display, IntPtr cursor);
7553 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
7554 internal extern static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape);
7556 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
7557 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);
7559 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
7560 internal extern static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
7562 [DllImport ("libX11", EntryPoint="XCreatePixmap")]
7563 internal extern static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
7565 [DllImport ("libX11", EntryPoint="XFreePixmap")]
7566 internal extern static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap);
7568 [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
7569 internal extern static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
7571 [DllImport ("libX11", EntryPoint="XQueryExtension")]
7572 internal extern static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
7574 [DllImport ("libX11", EntryPoint="XWhitePixel")]
7575 internal extern static IntPtr XWhitePixel(IntPtr display, int screen_no);
7577 [DllImport ("libX11", EntryPoint="XBlackPixel")]
7578 internal extern static IntPtr XBlackPixel(IntPtr display, int screen_no);
7580 [DllImport ("libX11", EntryPoint="XGrabServer")]
7581 internal extern static void XGrabServer(IntPtr display);
7583 [DllImport ("libX11", EntryPoint="XUngrabServer")]
7584 internal extern static void XUngrabServer(IntPtr display);
7586 [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
7587 internal extern static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
7589 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
7590 internal extern static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7592 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
7593 internal extern static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7595 [DllImport ("libX11", EntryPoint="XSetWMHints")]
7596 internal extern static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
7598 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
7599 internal extern static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
7601 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
7602 internal extern static IntPtr XSetErrorHandler(XErrorHandler error_handler);
7604 [DllImport ("libX11", EntryPoint="XGetErrorText")]
7605 internal extern static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
7607 [DllImport ("libX11", EntryPoint="XInitThreads")]
7608 internal extern static int XInitThreads();
7610 [DllImport ("libX11", EntryPoint="XConvertSelection")]
7611 internal extern static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
7613 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
7614 internal extern static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection);
7616 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
7617 internal extern static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
7619 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
7620 internal extern static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
7622 [DllImport ("libX11", EntryPoint="XSetForeground")]
7623 internal extern static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
7625 [DllImport ("libX11", EntryPoint="XSetBackground")]
7626 internal extern static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
7628 [DllImport ("libX11", EntryPoint="XBell")]
7629 internal extern static int XBell(IntPtr display, int percent);
7631 [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
7632 internal extern static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
7634 [DllImport ("libX11", EntryPoint="XFilterEvent")]
7635 internal extern static bool XFilterEvent(ref XEvent xevent, IntPtr window);
7637 [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
7638 internal extern static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
7640 [DllImport ("libX11", EntryPoint="XPeekEvent")]
7641 internal extern static void XPeekEvent (IntPtr display, ref XEvent xevent);
7643 [DllImport ("libX11", EntryPoint="XIfEvent")]
7644 internal extern static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
7646 [DllImport ("libX11", EntryPoint="XGetInputFocus")]
7647 internal extern static void XGetInputFocus (IntPtr display, out IntPtr focus, out IntPtr revert_to);
7649 #region Gtk/Gdk imports
7650 [DllImport("libgdk-x11-2.0")]
7651 internal extern static IntPtr gdk_atom_intern (string atomName, bool onlyIfExists);
7653 [DllImport("libgtk-x11-2.0")]
7654 internal extern static IntPtr gtk_clipboard_get (IntPtr atom);
7656 [DllImport("libgtk-x11-2.0")]
7657 internal extern static void gtk_clipboard_store (IntPtr clipboard);
7659 [DllImport("libgtk-x11-2.0")]
7660 internal extern static void gtk_clipboard_set_text (IntPtr clipboard, string text, int len);
7664 #region Xinerama imports
7665 [DllImport ("libXinerama")]
7666 internal extern static IntPtr XineramaQueryScreens (IntPtr display, out int number);
7668 [DllImport ("libXinerama", EntryPoint = "XineramaIsActive")]
7669 extern static bool _XineramaIsActive (IntPtr display);
7670 static bool XineramaNotInstalled;
7672 internal static bool XineramaIsActive (IntPtr display)
7674 if (XineramaNotInstalled)
7677 return _XineramaIsActive (display);
7678 } catch (DllNotFoundException) {
7679 // Xinerama isn't installed
7680 XineramaNotInstalled = true;