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 you 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
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 Clipboard.Item = Marshal.PtrToStringUni (prop, Encoding.Unicode.GetMaxCharCount ((int)nitems));
1300 } else if (property == RICHTEXTFORMAT)
1301 Clipboard.Item = Marshal.PtrToStringAnsi(prop);
1302 else if (DataFormats.ContainsFormat (property.ToInt32 ())) {
1303 if (DataFormats.GetFormat (property.ToInt32 ()).is_serializable) {
1304 MemoryStream memory_stream = new MemoryStream ((int)nitems);
1305 for (int i = 0; i < (int)nitems; i++)
1306 memory_stream.WriteByte (Marshal.ReadByte (prop, i));
1308 memory_stream.Position = 0;
1309 BinaryFormatter formatter = new BinaryFormatter ();
1310 Clipboard.Item = formatter.Deserialize (memory_stream);
1311 memory_stream.Close ();
1319 string UnescapeUnicodeFromAnsi (string value)
1321 if (value == null || value.IndexOf ("\\u") == -1)
1324 StringBuilder sb = new StringBuilder (value.Length);
1328 while (start < value.Length) {
1329 pos = value.IndexOf ("\\u", start);
1333 sb.Append (value, start, pos - start);
1338 while (pos < value.Length) {
1339 if (!ValidHexDigit (value [pos]))
1346 if (!Int32.TryParse (value.Substring (start, length), System.Globalization.NumberStyles.HexNumber,
1348 return value; // Error, return the unescaped original value.
1350 sb.Append ((char)res);
1354 // Append any remaining data.
1355 if (start < value.Length)
1356 sb.Append (value, start, value.Length - start);
1358 return sb.ToString ();
1361 private static bool ValidHexDigit (char e)
1363 return Char.IsDigit (e) || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
1366 void AddExpose (Hwnd hwnd, bool client, int x, int y, int width, int height) {
1368 if ((hwnd == null) || (x > hwnd.Width) || (y > hwnd.Height) || ((x + width) < 0) || ((y + height) < 0)) {
1372 // Keep the invalid area as small as needed
1373 if ((x + width) > hwnd.width) {
1374 width = hwnd.width - x;
1377 if ((y + height) > hwnd.height) {
1378 height = hwnd.height - y;
1382 hwnd.AddInvalidArea(x, y, width, height);
1383 if (!hwnd.expose_pending) {
1384 if (!hwnd.nc_expose_pending) {
1385 hwnd.Queue.Paint.Enqueue(hwnd);
1387 hwnd.expose_pending = true;
1390 hwnd.AddNcInvalidArea (x, y, width, height);
1392 if (!hwnd.nc_expose_pending) {
1393 if (!hwnd.expose_pending) {
1394 hwnd.Queue.Paint.Enqueue(hwnd);
1396 hwnd.nc_expose_pending = true;
1401 static Hwnd.Borders FrameExtents (IntPtr window)
1407 IntPtr prop = IntPtr.Zero;
1408 Hwnd.Borders rect = new Hwnd.Borders ();
1410 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);
1411 if (prop != IntPtr.Zero) {
1412 if (nitems.ToInt32 () == 4) {
1413 rect.left = Marshal.ReadInt32 (prop, 0);
1414 rect.right = Marshal.ReadInt32 (prop, IntPtr.Size);
1415 rect.top = Marshal.ReadInt32 (prop, 2 * IntPtr.Size);
1416 rect.bottom = Marshal.ReadInt32 (prop, 3 * IntPtr.Size);
1424 void AddConfigureNotify (XEvent xevent) {
1427 hwnd = Hwnd.GetObjectFromWindow(xevent.ConfigureEvent.window);
1430 if (hwnd == null || hwnd.zombie) {
1433 if ((xevent.ConfigureEvent.window == hwnd.whole_window)/* && (xevent.ConfigureEvent.window == xevent.ConfigureEvent.xevent)*/) {
1434 if (hwnd.parent == null) {
1435 // The location given by the event is not reliable between different wm's,
1436 // so use an alternative way of getting it.
1437 Point location = GetTopLevelWindowLocation (hwnd);
1438 hwnd.x = location.X;
1439 hwnd.y = location.Y;
1442 // XXX this sucks. this isn't thread safe
1443 Control ctrl = Control.FromHandle (hwnd.Handle);
1444 Size TranslatedSize;
1446 TranslatedSize = TranslateXWindowSizeToWindowSize (ctrl.GetCreateParams (), xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
1448 TranslatedSize = new Size (xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
1450 hwnd.width = TranslatedSize.Width;
1451 hwnd.height = TranslatedSize.Height;
1452 hwnd.ClientRect = Rectangle.Empty;
1454 DriverDebug ("AddConfigureNotify (hwnd.Handle = {1}, final hwnd.rect = {0}, reported rect={2})",
1455 new Rectangle (hwnd.x, hwnd.y, hwnd.width, hwnd.height), hwnd.Handle,
1456 new Rectangle (xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.width));
1457 lock (hwnd.configure_lock) {
1458 if (!hwnd.configure_pending) {
1459 hwnd.Queue.EnqueueLocked (xevent);
1460 hwnd.configure_pending = true;
1464 // We drop configure events for Client windows
1468 if ((Caret.gc == IntPtr.Zero) || Caret.On) {
1474 XDrawLine(DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1479 if ((Caret.gc == IntPtr.Zero) || !Caret.On) {
1485 XDrawLine(DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
1489 int NextTimeout (ArrayList timers, DateTime now) {
1492 foreach (Timer timer in timers) {
1493 int next = (int) (timer.Expires - now).TotalMilliseconds;
1495 return 0; // Have a timer that has already expired
1498 if (next < timeout) {
1502 if (timeout < Timer.Minimum) {
1503 timeout = Timer.Minimum;
1511 void CheckTimers (ArrayList timers, DateTime now) {
1514 count = timers.Count;
1519 for (int i = 0; i < timers.Count; i++) {
1522 timer = (Timer) timers [i];
1524 if (timer.Enabled && timer.Expires <= now && !timer.Busy) {
1526 // - Before MainForm.OnLoad if DoEvents () is called.
1527 // - After MainForm.OnLoad if not.
1530 (Application.MWFThread.Current.Context != null &&
1531 (Application.MWFThread.Current.Context.MainForm == null ||
1532 Application.MWFThread.Current.Context.MainForm.IsLoaded))) {
1542 void WaitForHwndMessage (Hwnd hwnd, Msg message) {
1543 WaitForHwndMessage (hwnd, message, false);
1547 void WaitForHwndMessage (Hwnd hwnd, Msg message, bool process) {
1548 MSG msg = new MSG ();
1551 queue = ThreadQueue(Thread.CurrentThread);
1553 queue.DispatchIdle = false;
1556 string key = hwnd.Handle + ":" + message;
1557 if (!messageHold.ContainsKey (key))
1558 messageHold.Add (key, 1);
1560 messageHold[key] = ((int)messageHold[key]) + 1;
1565 DebugHelper.WriteLine ("Waiting for message " + message + " on hwnd " + String.Format("0x{0:x}", hwnd.Handle.ToInt32 ()));
1566 DebugHelper.Indent ();
1568 if (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
1569 if ((Msg)msg.message == Msg.WM_QUIT) {
1570 PostQuitMessage (0);
1575 DebugHelper.WriteLine ("PeekMessage got " + msg);
1577 if (msg.hwnd == hwnd.Handle) {
1578 if ((Msg)msg.message == message) {
1580 TranslateMessage (ref msg);
1581 DispatchMessage (ref msg);
1585 else if ((Msg)msg.message == Msg.WM_DESTROY)
1589 TranslateMessage (ref msg);
1590 DispatchMessage (ref msg);
1594 done = !messageHold.ContainsKey (key) || ((int)messageHold[key] < 1) || done;
1597 messageHold.Remove (key);
1599 DebugHelper.Unindent ();
1600 DebugHelper.WriteLine ("Finished waiting for " + key);
1602 queue.DispatchIdle = true;
1606 void MapWindow(Hwnd hwnd, WindowType windows) {
1608 Form f = Control.FromHandle(hwnd.Handle) as Form;
1610 if (f.WindowState == FormWindowState.Normal) {
1611 f.waiting_showwindow = true;
1612 SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
1616 // it's possible that our Hwnd is no
1617 // longer valid after making that
1618 // SendMessage call, so check here.
1623 // Most window managers will respect the _NET_WM_STATE property.
1624 // If not, use XMapRaised to map the window at the top level as
1625 // a last ditch effort.
1626 if ((windows & WindowType.Whole) != 0) {
1627 XMapRaised(DisplayHandle, hwnd.whole_window);
1629 if ((windows & WindowType.Client) != 0) {
1630 XMapRaised(DisplayHandle, hwnd.client_window);
1633 if ((windows & WindowType.Whole) != 0) {
1634 XMapWindow(DisplayHandle, hwnd.whole_window);
1636 if ((windows & WindowType.Client) != 0) {
1637 XMapWindow(DisplayHandle, hwnd.client_window);
1644 if (f.waiting_showwindow) {
1645 WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
1646 CreateParams cp = f.GetCreateParams();
1647 if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
1648 !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
1649 WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
1656 void UnmapWindow(Hwnd hwnd, WindowType windows) {
1659 if (Control.FromHandle(hwnd.Handle) is Form) {
1660 f = Control.FromHandle(hwnd.Handle) as Form;
1661 if (f.WindowState == FormWindowState.Normal) {
1662 f.waiting_showwindow = true;
1663 SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, IntPtr.Zero, IntPtr.Zero);
1667 // it's possible that our Hwnd is no
1668 // longer valid after making that
1669 // SendMessage call, so check here.
1670 // FIXME: it is likely wrong, as it has already sent WM_SHOWWINDOW
1674 if ((windows & WindowType.Client) != 0) {
1675 XUnmapWindow(DisplayHandle, hwnd.client_window);
1677 if ((windows & WindowType.Whole) != 0) {
1678 XUnmapWindow(DisplayHandle, hwnd.whole_window);
1681 hwnd.mapped = false;
1684 if (f.waiting_showwindow) {
1685 WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
1686 CreateParams cp = f.GetCreateParams();
1687 if (!ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_MDICHILD) &&
1688 !StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
1689 WaitForHwndMessage (hwnd, Msg.WM_ACTIVATE, true);
1696 void UpdateMessageQueue (XEventQueue queue) {
1697 UpdateMessageQueue(queue, true);
1700 void UpdateMessageQueue (XEventQueue queue, bool allowIdle) {
1705 now = DateTime.UtcNow;
1708 pending = XPending (DisplayHandle);
1711 if (pending == 0 && allowIdle) {
1712 if ((queue == null || queue.DispatchIdle) && Idle != null) {
1713 Idle (this, EventArgs.Empty);
1717 pending = XPending (DisplayHandle);
1724 if (queue != null) {
1725 if (queue.Paint.Count > 0)
1728 timeout = NextTimeout (queue.timer_list, now);
1733 int length = pollfds.Length - 1;
1734 lock (wake_waiting_lock) {
1735 if (wake_waiting == false) {
1737 wake_waiting = true;
1741 Syscall.poll (pollfds, (uint)length, timeout);
1742 // Clean out buffer, so we're not busy-looping on the same data
1743 if (length == pollfds.Length) {
1744 if (pollfds[1].revents != 0)
1745 wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None);
1746 lock (wake_waiting_lock) {
1747 wake_waiting = false;
1752 pending = XPending (DisplayHandle);
1758 CheckTimers (queue.timer_list, now);
1761 XEvent xevent = new XEvent ();
1764 if (XPending (DisplayHandle) == 0)
1767 XNextEvent (DisplayHandle, ref xevent);
1769 if (xevent.AnyEvent.type == XEventName.KeyPress ||
1770 xevent.AnyEvent.type == XEventName.KeyRelease) {
1771 // PreFilter() handles "shift key state updates.
1772 Keyboard.PreFilter (xevent);
1773 if (XFilterEvent (ref xevent, Keyboard.ClientWindow)) {
1774 // probably here we could raise WM_IME_KEYDOWN and
1775 // WM_IME_KEYUP, but I'm not sure it is worthy.
1779 else if (XFilterEvent (ref xevent, IntPtr.Zero))
1783 hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
1787 DebugHelper.WriteLine ("UpdateMessageQueue got Event: " + xevent.ToString ());
1789 switch (xevent.type) {
1790 case XEventName.Expose:
1791 AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
1794 case XEventName.SelectionClear: {
1795 // Should we do something?
1799 case XEventName.SelectionRequest: {
1800 if (Dnd.HandleSelectionRequestEvent (ref xevent))
1804 sel_event = new XEvent();
1805 sel_event.SelectionEvent.type = XEventName.SelectionNotify;
1806 sel_event.SelectionEvent.send_event = true;
1807 sel_event.SelectionEvent.display = DisplayHandle;
1808 sel_event.SelectionEvent.selection = xevent.SelectionRequestEvent.selection;
1809 sel_event.SelectionEvent.target = xevent.SelectionRequestEvent.target;
1810 sel_event.SelectionEvent.requestor = xevent.SelectionRequestEvent.requestor;
1811 sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
1812 sel_event.SelectionEvent.property = IntPtr.Zero;
1814 IntPtr format_atom = xevent.SelectionRequestEvent.target;
1816 // Seems that some apps support asking for supported types
1817 if (format_atom == TARGETS) {
1824 if (Clipboard.IsSourceText) {
1825 atoms[atom_count++] = (int)Atom.XA_STRING;
1826 atoms[atom_count++] = (int)OEMTEXT;
1827 atoms[atom_count++] = (int)UTF8_STRING;
1828 atoms[atom_count++] = (int)UTF16_STRING;
1829 atoms[atom_count++] = (int)RICHTEXTFORMAT;
1830 } else if (Clipboard.IsSourceImage) {
1831 atoms[atom_count++] = (int)Atom.XA_PIXMAP;
1832 atoms[atom_count++] = (int)Atom.XA_BITMAP;
1834 // FIXME - handle other types
1837 XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property,
1838 (IntPtr)xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
1839 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1840 } else if (format_atom == (IntPtr)RICHTEXTFORMAT) {
1841 string rtf_text = Clipboard.GetRtfText ();
1842 if (rtf_text != null) {
1843 // The RTF spec mentions that ascii is enough to contain it
1844 Byte [] bytes = Encoding.ASCII.GetBytes (rtf_text);
1845 int buflen = bytes.Length;
1846 IntPtr buffer = Marshal.AllocHGlobal (buflen);
1848 for (int i = 0; i < buflen; i++)
1849 Marshal.WriteByte (buffer, i, bytes[i]);
1851 XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property,
1852 (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
1853 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1854 Marshal.FreeHGlobal(buffer);
1856 } else if (Clipboard.IsSourceText &&
1857 (format_atom == (IntPtr)Atom.XA_STRING
1858 || format_atom == OEMTEXT
1859 || format_atom == UTF16_STRING
1860 || format_atom == UTF8_STRING)) {
1861 IntPtr buffer = IntPtr.Zero;
1863 Encoding encoding = null;
1867 // Select an encoding depending on the target
1868 IntPtr target_atom = xevent.SelectionRequestEvent.target;
1869 if (target_atom == (IntPtr)Atom.XA_STRING || target_atom == OEMTEXT)
1870 // FIXME - EOMTEXT should encode into ISO2022
1871 encoding = Encoding.ASCII;
1872 else if (target_atom == UTF16_STRING)
1873 encoding = Encoding.Unicode;
1874 else if (target_atom == UTF8_STRING)
1875 encoding = Encoding.UTF8;
1879 bytes = encoding.GetBytes (Clipboard.GetPlainText ());
1880 buffer = Marshal.AllocHGlobal (bytes.Length);
1881 buflen = bytes.Length;
1883 for (int i = 0; i < buflen; i++)
1884 Marshal.WriteByte (buffer, i, bytes [i]);
1886 if (buffer != IntPtr.Zero) {
1887 XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target, 8, PropertyMode.Replace, buffer, buflen);
1888 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1889 Marshal.FreeHGlobal(buffer);
1891 } else if (Clipboard.GetSource (format_atom.ToInt32 ()) != null) { // check if we have an available value of this format
1892 if (DataFormats.GetFormat (format_atom.ToInt32 ()).is_serializable) {
1893 object serializable = Clipboard.GetSource (format_atom.ToInt32 ());
1895 BinaryFormatter formatter = new BinaryFormatter ();
1896 MemoryStream memory_stream = new MemoryStream ();
1897 formatter.Serialize (memory_stream, serializable);
1899 int buflen = (int)memory_stream.Length;
1900 IntPtr buffer = Marshal.AllocHGlobal (buflen);
1901 memory_stream.Position = 0;
1902 for (int i = 0; i < buflen; i++)
1903 Marshal.WriteByte (buffer, i, (byte)memory_stream.ReadByte ());
1904 memory_stream.Close ();
1906 XChangeProperty (DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target,
1907 8, PropertyMode.Replace, buffer, buflen);
1908 sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
1909 Marshal.FreeHGlobal (buffer);
1912 } else if (Clipboard.IsSourceImage) {
1913 if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
1914 // FIXME - convert image and store as property
1915 } else if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
1916 // FIXME - convert image and store as property
1920 XSendEvent(DisplayHandle, xevent.SelectionRequestEvent.requestor, false, new IntPtr ((int)EventMask.NoEventMask), ref sel_event);
1924 case XEventName.SelectionNotify: {
1925 if (Clipboard.Enumerating) {
1926 Clipboard.Enumerating = false;
1927 if (xevent.SelectionEvent.property != IntPtr.Zero) {
1928 XDeleteProperty(DisplayHandle, FosterParent, (IntPtr)xevent.SelectionEvent.property);
1929 if (!Clipboard.Formats.Contains(xevent.SelectionEvent.property)) {
1930 Clipboard.Formats.Add(xevent.SelectionEvent.property);
1931 DriverDebug("Got supported clipboard atom format: {0}", xevent.SelectionEvent.property);
1934 } else if (Clipboard.Retrieving) {
1935 Clipboard.Retrieving = false;
1936 if (xevent.SelectionEvent.property != IntPtr.Zero) {
1937 TranslatePropertyToClipboard(xevent.SelectionEvent.property);
1939 Clipboard.ClearSources ();
1940 Clipboard.Item = null;
1943 Dnd.HandleSelectionNotifyEvent (ref xevent);
1948 case XEventName.KeyRelease:
1949 if (!detectable_key_auto_repeat && XPending (DisplayHandle) != 0) {
1950 XEvent nextevent = new XEvent ();
1952 XPeekEvent (DisplayHandle, ref nextevent);
1954 if (nextevent.type == XEventName.KeyPress &&
1955 nextevent.KeyEvent.keycode == xevent.KeyEvent.keycode &&
1956 nextevent.KeyEvent.time == xevent.KeyEvent.time) {
1960 goto case XEventName.KeyPress;
1962 case XEventName.MotionNotify: {
1965 /* we can't do motion compression across threads, so just punt if we don't match up */
1966 if (Thread.CurrentThread == hwnd.Queue.Thread && hwnd.Queue.Count > 0) {
1967 peek = hwnd.Queue.Peek();
1968 if (peek.AnyEvent.type == XEventName.MotionNotify) {
1972 goto case XEventName.KeyPress;
1975 case XEventName.KeyPress:
1976 hwnd.Queue.EnqueueLocked (xevent);
1977 /* Process KeyPresses immediately. Otherwise multiple Compose messages as a result of a
1978 * single physical keypress are not processed correctly */
1980 case XEventName.ButtonPress:
1981 case XEventName.ButtonRelease:
1982 case XEventName.EnterNotify:
1983 case XEventName.LeaveNotify:
1984 case XEventName.CreateNotify:
1985 case XEventName.DestroyNotify:
1986 case XEventName.FocusIn:
1987 case XEventName.FocusOut:
1988 case XEventName.ClientMessage:
1989 case XEventName.ReparentNotify:
1990 case XEventName.MapNotify:
1991 case XEventName.UnmapNotify:
1992 hwnd.Queue.EnqueueLocked (xevent);
1995 case XEventName.ConfigureNotify:
1996 AddConfigureNotify(xevent);
1999 case XEventName.PropertyNotify:
2000 DriverDebug ("UpdateMessageQueue (), got Event: {0}", xevent.ToString ());
2001 if (xevent.PropertyEvent.atom == _NET_ACTIVE_WINDOW) {
2006 IntPtr prop = IntPtr.Zero;
2009 prev_active = ActiveWindow;
2010 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);
2011 if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
2012 ActiveWindow = Hwnd.GetHandleFromWindow((IntPtr)Marshal.ReadInt32(prop));
2015 DebugHelper.WriteLine ("PropertyNotify: _NET_ACTIVE_WINDOW: previous = 0x{0:x}, new = 0x{1:x}", prev_active.ToInt32 (), ActiveWindow.ToInt32 ());
2017 if (prev_active != ActiveWindow) {
2018 if (prev_active != IntPtr.Zero) {
2019 PostMessage(prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
2021 if (ActiveWindow != IntPtr.Zero) {
2022 PostMessage(ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
2025 if (ModalWindows.Count == 0) {
2028 // Modality Handling
2030 // If there is a modal window on the stack and the new active
2031 // window is MWF window, but not the modal one and not a non-modal
2032 // child of the modal one, switch back to the modal window.
2034 // To identify if a non-modal form is child of a modal form
2035 // we match their ApplicationContexts, which will be the same.
2036 // This is because each modal form runs the loop with a
2037 // new ApplicationContext, which is inherited by the non-modal
2040 Form activeForm = Control.FromHandle (ActiveWindow) as Form;
2041 if (activeForm != null) {
2042 Form modalForm = Control.FromHandle ((IntPtr)ModalWindows.Peek()) as Form;
2043 if (ActiveWindow != (IntPtr)ModalWindows.Peek() &&
2044 (modalForm == null || activeForm.context == modalForm.context)) {
2045 Activate((IntPtr)ModalWindows.Peek());
2052 else if (xevent.PropertyEvent.atom == _NET_WM_STATE) {
2053 // invalidate our cache - we'll query again the next time someone does GetWindowState.
2054 hwnd.cached_window_state = (FormWindowState)(-1);
2055 PostMessage (hwnd.Handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
2063 IntPtr GetMousewParam(int Delta) {
2066 if ((MouseState & MouseButtons.Left) != 0) {
2067 result |= (int)MsgButtons.MK_LBUTTON;
2070 if ((MouseState & MouseButtons.Middle) != 0) {
2071 result |= (int)MsgButtons.MK_MBUTTON;
2074 if ((MouseState & MouseButtons.Right) != 0) {
2075 result |= (int)MsgButtons.MK_RBUTTON;
2078 Keys mods = ModifierKeys;
2079 if ((mods & Keys.Control) != 0) {
2080 result |= (int)MsgButtons.MK_CONTROL;
2083 if ((mods & Keys.Shift) != 0) {
2084 result |= (int)MsgButtons.MK_SHIFT;
2087 result |= Delta << 16;
2089 return (IntPtr)result;
2091 IntPtr XGetParent(IntPtr handle) {
2098 XQueryTree(DisplayHandle, handle, out Root, out Parent, out Children, out ChildCount);
2101 if (Children!=IntPtr.Zero) {
2109 int HandleError (IntPtr display, ref XErrorEvent error_event)
2111 // we need to workaround a problem with the
2112 // ordering of destruction of Drawables and
2113 // Pictures that exists between cairo and
2114 // RENDER on the server.
2115 if (error_event.request_code == (XRequest)render_major_opcode
2116 && error_event.minor_code == 7 /* X_RenderFreePicture from render.h */
2117 && error_event.error_code == render_first_error + 1 /* BadPicture from render.h */) {
2121 if (ErrorExceptions) {
2122 XUngrabPointer (display, IntPtr.Zero);
2123 throw new XException (error_event.display, error_event.resourceid,
2124 error_event.serial, error_event.error_code,
2125 error_event.request_code, error_event.minor_code);
2127 Console.WriteLine("X11 Error encountered: {0}{1}\n",
2128 XException.GetMessage (error_event.display, error_event.resourceid,
2129 error_event.serial, error_event.error_code,
2130 error_event.request_code, error_event.minor_code),
2131 Environment.StackTrace);
2136 void AccumulateDestroyedHandles (Control c, ArrayList list)
2138 DebugHelper.Enter ();
2141 Control[] controls = c.Controls.GetAllControls ();
2143 DebugHelper.WriteLine ("Checking control:0x{0:x}", c.IsHandleCreated ? c.Handle.ToInt32() : 0);
2145 if (c.IsHandleCreated && !c.IsDisposed) {
2146 Hwnd hwnd = Hwnd.ObjectFromHandle(c.Handle);
2148 DriverDebug (" + adding {0} to the list of zombie windows", XplatUI.Window (hwnd.Handle));
2149 DriverDebug (" + parent X window is {0:X}", XGetParent (hwnd.whole_window).ToInt32());
2152 CleanupCachedWindows (hwnd);
2155 for (int i = 0; i < controls.Length; i ++) {
2156 AccumulateDestroyedHandles (controls[i], list);
2159 DebugHelper.Leave ();
2162 void CleanupCachedWindows (Hwnd hwnd)
2164 if (ActiveWindow == hwnd.Handle) {
2165 SendMessage(hwnd.client_window, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
2166 ActiveWindow = IntPtr.Zero;
2169 if (FocusWindow == hwnd.Handle) {
2170 SendMessage(hwnd.client_window, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
2171 FocusWindow = IntPtr.Zero;
2174 if (Grab.Hwnd == hwnd.Handle) {
2175 Grab.Hwnd = IntPtr.Zero;
2176 Grab.Confined = false;
2179 DestroyCaret (hwnd.Handle);
2182 void PerformNCCalc(Hwnd hwnd) {
2183 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
2187 rect = new Rectangle (0, 0, hwnd.Width, hwnd.Height);
2189 ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
2190 ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));
2192 ncp.rgrc1.left = rect.Left;
2193 ncp.rgrc1.top = rect.Top;
2194 ncp.rgrc1.right = rect.Right;
2195 ncp.rgrc1.bottom = rect.Bottom;
2197 Marshal.StructureToPtr(ncp, ptr, true);
2198 NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
2199 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
2200 Marshal.FreeHGlobal(ptr);
2203 rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
2204 hwnd.ClientRect = rect;
2206 rect = TranslateClientRectangleToXClientRectangle (hwnd);
2209 MoveResizeWindow (DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
2212 AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
2214 #endregion // Methods
2217 void MouseHover(object sender, EventArgs e) {
2221 HoverState.Timer.Enabled = false;
2223 if (HoverState.Window != IntPtr.Zero) {
2224 hwnd = Hwnd.GetObjectFromWindow(HoverState.Window);
2226 xevent = new XEvent ();
2228 xevent.type = XEventName.ClientMessage;
2229 xevent.ClientMessageEvent.display = DisplayHandle;
2230 xevent.ClientMessageEvent.window = HoverState.Window;
2231 xevent.ClientMessageEvent.message_type = HoverState.Atom;
2232 xevent.ClientMessageEvent.format = 32;
2233 xevent.ClientMessageEvent.ptr1 = (IntPtr) (HoverState.Y << 16 | HoverState.X);
2235 hwnd.Queue.EnqueueLocked (xevent);
2242 void CaretCallback(object sender, EventArgs e) {
2246 Caret.On = !Caret.On;
2248 XDrawLine(DisplayHandle, Caret.Hwnd, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
2250 #endregion // Callbacks
2252 #region Public Properties
2254 internal override int CaptionHeight {
2260 internal override Size CursorSize {
2265 if (XQueryBestCursor(DisplayHandle, RootWindow, 32, 32, out x, out y) != 0) {
2266 return new Size(x, y);
2268 return new Size(16, 16);
2273 internal override bool DragFullWindows {
2279 internal override Size DragSize {
2281 return new Size(4, 4);
2285 internal override Size FrameBorderSize {
2287 return new Size (4, 4);
2291 internal override Size IconSize {
2297 if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
2301 current = (long)list;
2304 size = new XIconSize();
2306 for (int i = 0; i < count; i++) {
2307 size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
2308 current += Marshal.SizeOf(size);
2310 // Look for our preferred size
2311 if (size.min_width == 32) {
2313 return new Size(32, 32);
2316 if (size.max_width == 32) {
2318 return new Size(32, 32);
2321 if (size.min_width < 32 && size.max_width > 32) {
2324 // check if we can fit one
2326 while (x < size.max_width) {
2327 x += size.width_inc;
2330 return new Size(32, 32);
2335 if (largest < size.max_width) {
2336 largest = size.max_width;
2340 // We didn't find a match or we wouldn't be here
2341 return new Size(largest, largest);
2344 return new Size(32, 32);
2349 internal override int KeyboardSpeed {
2352 // A lot harder: need to do:
2353 // XkbQueryExtension(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 1
2354 // XkbAllocKeyboard(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 0x080517a8
2355 // XkbGetControls(0x08051008, 1, 0x080517a8, 0xbfffdf54, 0xbfffdf58) = 0
2357 // And from that we can tell the repetition rate
2359 // Notice, the values must map to:
2360 // [0, 31] which maps to 2.5 to 30 repetitions per second.
2366 internal override int KeyboardDelay {
2369 // Return values must range from 0 to 4, 0 meaning 250ms,
2370 // and 4 meaning 1000 ms.
2372 return 1; // ie, 500 ms
2376 internal override Size MaxWindowTrackSize {
2378 return new Size (WorkingArea.Width, WorkingArea.Height);
2382 internal override bool MenuAccessKeysUnderlined {
2388 internal override Size MinimizedWindowSpacingSize {
2390 return new Size(1, 1);
2394 internal override Size MinimumWindowSize {
2396 return new Size(110, 22);
2400 internal override Size MinimumFixedToolWindowSize {
2401 get { return new Size (27, 22); }
2404 internal override Size MinimumSizeableToolWindowSize {
2405 get { return new Size (37, 22); }
2408 internal override Size MinimumNoBorderWindowSize {
2409 get { return new Size (2, 2); }
2412 internal override Keys ModifierKeys {
2414 return Keyboard.ModifierKeys;
2418 internal override Size SmallIconSize {
2424 if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
2428 current = (long)list;
2431 size = new XIconSize();
2433 for (int i = 0; i < count; i++) {
2434 size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
2435 current += Marshal.SizeOf(size);
2437 // Look for our preferred size
2438 if (size.min_width == 16) {
2440 return new Size(16, 16);
2443 if (size.max_width == 16) {
2445 return new Size(16, 16);
2448 if (size.min_width < 16 && size.max_width > 16) {
2451 // check if we can fit one
2453 while (x < size.max_width) {
2454 x += size.width_inc;
2457 return new Size(16, 16);
2462 if (smallest == 0 || smallest > size.min_width) {
2463 smallest = size.min_width;
2467 // We didn't find a match or we wouldn't be here
2468 return new Size(smallest, smallest);
2471 return new Size(16, 16);
2476 internal override int MouseButtonCount {
2482 internal override bool MouseButtonsSwapped {
2484 return false; // FIXME - how to detect?
2488 internal override Point MousePosition {
2490 return mouse_position;
2494 internal override Size MouseHoverSize {
2496 return new Size (1, 1);
2500 internal override int MouseHoverTime {
2502 return HoverState.Interval;
2508 internal override bool MouseWheelPresent {
2510 return true; // FIXME - how to detect?
2514 internal override MouseButtons MouseButtons {
2520 internal override Rectangle VirtualScreen {
2526 IntPtr prop = IntPtr.Zero;
2530 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);
2531 if ((long)nitems < 2)
2534 width = Marshal.ReadIntPtr(prop, 0).ToInt32();
2535 height = Marshal.ReadIntPtr(prop, IntPtr.Size).ToInt32();
2539 return new Rectangle(0, 0, width, height);
2542 XWindowAttributes attributes=new XWindowAttributes();
2545 XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
2548 return new Rectangle(0, 0, attributes.width, attributes.height);
2552 internal override Rectangle WorkingArea {
2558 IntPtr prop = IntPtr.Zero;
2561 int current_desktop;
2565 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);
2566 if ((long)nitems < 1) {
2570 current_desktop = Marshal.ReadIntPtr(prop, 0).ToInt32();
2573 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);
2574 if ((long)nitems < 4 * (current_desktop + 1)) {
2578 x = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop).ToInt32();
2579 y = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size).ToInt32();
2580 width = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size * 2).ToInt32();
2581 height = Marshal.ReadIntPtr(prop, IntPtr.Size * 4 * current_desktop + IntPtr.Size * 3).ToInt32();
2584 return new Rectangle(x, y, width, height);
2587 XWindowAttributes attributes=new XWindowAttributes();
2590 XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
2593 return new Rectangle(0, 0, attributes.width, attributes.height);
2597 internal override Screen[] AllScreens {
2599 if (!XineramaIsActive (DisplayHandle))
2602 IntPtr xineramaScreens = XineramaQueryScreens (DisplayHandle, out nScreens);
2603 var screens = new Screen [nScreens];
2604 IntPtr current = xineramaScreens;
2605 for (int i = 0; i < nScreens; i++) {
2606 var screen = (XineramaScreenInfo)Marshal.PtrToStructure (current,
2607 typeof (XineramaScreenInfo));
2608 var screenRect = new Rectangle (screen.x_org, screen.y_org, screen.width,
2610 var name = string.Format ("Display {0}", screen.screen_number);
2611 screens [i] = new Screen (i == 0, name, screenRect, screenRect);
2612 current = (IntPtr)( (ulong)current + (ulong)Marshal.SizeOf(typeof (XineramaScreenInfo)));
2614 XFree (xineramaScreens);
2619 internal override bool ThemesEnabled {
2621 return XplatUIX11.themes_enabled;
2626 #endregion // Public properties
2628 #region Public Static Methods
2629 internal override void RaiseIdle (EventArgs e)
2635 internal override IntPtr InitializeDriver()
2638 if (DisplayHandle==IntPtr.Zero) {
2639 SetDisplay(XOpenDisplay(IntPtr.Zero));
2645 internal override void ShutdownDriver(IntPtr token)
2648 if (DisplayHandle!=IntPtr.Zero) {
2649 XCloseDisplay(DisplayHandle);
2650 DisplayHandle=IntPtr.Zero;
2655 internal override void EnableThemes()
2657 themes_enabled = true;
2661 internal override void Activate(IntPtr handle)
2665 hwnd = Hwnd.ObjectFromHandle(handle);
2669 if (true /* the window manager supports NET_ACTIVE_WINDOW */) {
2670 SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
2671 XEventQueue q = null;
2672 lock (unattached_timer_list) {
2673 foreach (Timer t in unattached_timer_list) {
2675 q= (XEventQueue) MessageQueues [Thread.CurrentThread];
2676 t.thread = q.Thread;
2677 q.timer_list.Add (t);
2679 unattached_timer_list.Clear ();
2683 // XRaiseWindow(DisplayHandle, handle);
2689 internal override void AudibleAlert(AlertType alert)
2691 XBell(DisplayHandle, 0);
2696 internal override void CaretVisible(IntPtr handle, bool visible)
2698 if (Caret.Hwnd == handle) {
2700 if (!Caret.Visible) {
2701 Caret.Visible = true;
2703 Caret.Timer.Start();
2706 Caret.Visible = false;
2713 internal override bool CalculateWindowRect(ref Rectangle ClientRect, CreateParams cp, Menu menu, out Rectangle WindowRect)
2715 WindowRect = Hwnd.GetWindowRectangle (cp, menu, ClientRect);
2719 internal override void ClientToScreen(IntPtr handle, ref int x, ref int y)
2726 hwnd = Hwnd.ObjectFromHandle(handle);
2729 XTranslateCoordinates(DisplayHandle, hwnd.client_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
2736 internal override int[] ClipboardAvailableFormats(IntPtr handle)
2738 DataFormats.Format f;
2741 f = DataFormats.Format.List;
2743 if (XGetSelectionOwner(DisplayHandle, CLIPBOARD) == IntPtr.Zero) {
2747 Clipboard.Formats = new ArrayList();
2750 XConvertSelection(DisplayHandle, CLIPBOARD, (IntPtr)f.Id, (IntPtr)f.Id, FosterParent, IntPtr.Zero);
2752 var timeToWaitForSelectionFormats = TimeSpan.FromSeconds(4);
2753 var startTime = DateTime.Now;
2754 Clipboard.Enumerating = true;
2755 while (Clipboard.Enumerating) {
2756 UpdateMessageQueue(null, false);
2758 if (DateTime.Now - startTime > timeToWaitForSelectionFormats)
2764 result = new int[Clipboard.Formats.Count];
2766 for (int i = 0; i < Clipboard.Formats.Count; i++) {
2767 result[i] = ((IntPtr)Clipboard.Formats[i]).ToInt32 ();
2770 Clipboard.Formats = null;
2774 internal override void ClipboardClose(IntPtr handle)
2776 if (handle != ClipMagic) {
2777 throw new ArgumentException("handle is not a valid clipboard handle");
2782 internal override int ClipboardGetID(IntPtr handle, string format)
2784 if (handle != ClipMagic) {
2785 throw new ArgumentException("handle is not a valid clipboard handle");
2788 if (format == "Text" ) return (int)Atom.XA_STRING;
2789 else if (format == "Bitmap" ) return (int)Atom.XA_BITMAP;
2790 //else if (format == "MetaFilePict" ) return 3;
2791 //else if (format == "SymbolicLink" ) return 4;
2792 //else if (format == "DataInterchangeFormat" ) return 5;
2793 //else if (format == "Tiff" ) return 6;
2794 else if (format == "OEMText" ) return OEMTEXT.ToInt32();
2795 else if (format == "DeviceIndependentBitmap" ) return (int)Atom.XA_PIXMAP;
2796 else if (format == "Palette" ) return (int)Atom.XA_COLORMAP; // Useless
2797 //else if (format == "PenData" ) return 10;
2798 //else if (format == "RiffAudio" ) return 11;
2799 //else if (format == "WaveAudio" ) return 12;
2800 else if (format == "UnicodeText" ) return UTF16_STRING.ToInt32();
2801 //else if (format == "EnhancedMetafile" ) return 14;
2802 //else if (format == "FileDrop" ) return 15;
2803 //else if (format == "Locale" ) return 16;
2804 else if (format == "Rich Text Format") return RICHTEXTFORMAT.ToInt32 ();
2806 return XInternAtom(DisplayHandle, format, false).ToInt32();
2809 internal override IntPtr ClipboardOpen(bool primary_selection)
2811 if (!primary_selection)
2812 ClipMagic = CLIPBOARD;
2814 ClipMagic = PRIMARY;
2818 internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter)
2820 XConvertSelection(DisplayHandle, handle, (IntPtr)type, (IntPtr)type, FosterParent, IntPtr.Zero);
2822 Clipboard.Retrieving = true;
2823 while (Clipboard.Retrieving) {
2824 UpdateMessageQueue(null, false);
2827 return Clipboard.Item;
2830 internal override void ClipboardStore (IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter, bool copy)
2832 Clipboard.Converter = converter;
2835 Clipboard.AddSource (type, obj);
2836 XSetSelectionOwner (DisplayHandle, CLIPBOARD, FosterParent, IntPtr.Zero);
2840 var clipboardAtom = gdk_atom_intern ("CLIPBOARD", true);
2841 var clipboard = gtk_clipboard_get (clipboardAtom);
2842 if (clipboard != null) {
2843 // for now we only store text
2844 var text = Clipboard.GetRtfText ();
2845 if (string.IsNullOrEmpty (text))
2846 text = Clipboard.GetPlainText ();
2847 if (!string.IsNullOrEmpty (text)) {
2848 gtk_clipboard_set_text (clipboard, text, text.Length);
2849 gtk_clipboard_store (clipboard);
2853 // ignore any errors - most likely because gtk isn't installed?
2857 // Clearing the selection
2858 Clipboard.ClearSources ();
2859 XSetSelectionOwner (DisplayHandle, CLIPBOARD, IntPtr.Zero, IntPtr.Zero);
2863 internal override void CreateCaret (IntPtr handle, int width, int height)
2865 XGCValues gc_values;
2868 hwnd = Hwnd.ObjectFromHandle(handle);
2870 if (Caret.Hwnd != IntPtr.Zero) {
2871 DestroyCaret(Caret.Hwnd);
2874 Caret.Hwnd = handle;
2875 Caret.Window = hwnd.client_window;
2876 Caret.Width = width;
2877 Caret.Height = height;
2878 Caret.Visible = false;
2881 gc_values = new XGCValues();
2882 gc_values.line_width = width;
2884 Caret.gc = XCreateGC(DisplayHandle, Caret.Window, new IntPtr ((int)GCFunction.GCLineWidth), ref gc_values);
2885 if (Caret.gc == IntPtr.Zero) {
2886 Caret.Hwnd = IntPtr.Zero;
2890 XSetFunction(DisplayHandle, Caret.gc, GXFunction.GXinvert);
2893 internal override IntPtr CreateWindow (CreateParams cp)
2895 XSetWindowAttributes Attributes;
2897 Hwnd parent_hwnd = null;
2902 IntPtr ParentHandle;
2904 IntPtr ClientWindow;
2905 SetWindowValuemask ValueMask;
2910 Attributes = new XSetWindowAttributes();
2916 if (Width<1) Width=1;
2917 if (Height<1) Height=1;
2919 if (cp.Parent != IntPtr.Zero) {
2920 parent_hwnd = Hwnd.ObjectFromHandle(cp.Parent);
2921 ParentHandle = parent_hwnd.client_window;
2923 if (StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
2924 // We need to use our foster parent window until this poor child gets it's parent assigned
2925 ParentHandle=FosterParent;
2927 ParentHandle=RootWindow;
2931 // Set the default location location for forms.
2933 if (cp.control is Form) {
2934 next = Hwnd.GetNextStackedFormLocation (cp, parent_hwnd);
2938 ValueMask = SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity;
2940 Attributes.bit_gravity = Gravity.NorthWestGravity;
2941 Attributes.win_gravity = Gravity.NorthWestGravity;
2943 // Save what's under the toolwindow
2944 if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
2945 Attributes.save_under = true;
2946 ValueMask |= SetWindowValuemask.SaveUnder;
2950 // If we're a popup without caption we override the WM
2951 if (StyleSet (cp.Style, WindowStyles.WS_POPUP) && !StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
2952 Attributes.override_redirect = true;
2953 ValueMask |= SetWindowValuemask.OverrideRedirect;
2959 hwnd.height = Height;
2960 hwnd.parent = Hwnd.ObjectFromHandle(cp.Parent);
2961 hwnd.initial_style = cp.WindowStyle;
2962 hwnd.initial_ex_style = cp.WindowExStyle;
2964 if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
2965 hwnd.enabled = false;
2968 ClientWindow = IntPtr.Zero;
2970 Size XWindowSize = TranslateWindowSizeToXWindowSize (cp);
2971 Rectangle XClientRect = TranslateClientRectangleToXClientRectangle (hwnd, cp.control);
2974 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);
2975 if (WholeWindow != IntPtr.Zero) {
2976 ValueMask &= ~(SetWindowValuemask.OverrideRedirect | SetWindowValuemask.SaveUnder);
2978 if (CustomVisual != IntPtr.Zero && CustomColormap != IntPtr.Zero) {
2979 ValueMask = SetWindowValuemask.ColorMap;
2980 Attributes.colormap = CustomColormap;
2982 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);
2986 if ((WholeWindow == IntPtr.Zero) || (ClientWindow == IntPtr.Zero)) {
2987 throw new Exception("Could not create X11 windows");
2990 hwnd.Queue = ThreadQueue(Thread.CurrentThread);
2991 hwnd.WholeWindow = WholeWindow;
2992 hwnd.ClientWindow = ClientWindow;
2994 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);
2996 if (!StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
2997 if ((X != unchecked((int)0x80000000)) && (Y != unchecked((int)0x80000000))) {
3000 hints = new XSizeHints();
3003 hints.flags = (IntPtr)(XSizeHintsFlags.USPosition | XSizeHintsFlags.PPosition);
3004 XSetWMNormalHints(DisplayHandle, WholeWindow, ref hints);
3009 XSelectInput(DisplayHandle, hwnd.whole_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | EventMask.PropertyChangeMask | Keyboard.KeyEventMask)));
3010 if (hwnd.whole_window != hwnd.client_window)
3011 XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | Keyboard.KeyEventMask)));
3014 if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST))
3015 SetTopmost(hwnd.whole_window, true);
3017 SetWMStyles(hwnd, cp);
3019 // set the group leader
3020 XWMHints wm_hints = new XWMHints ();
3022 wm_hints.flags = (IntPtr)(XWMHintsFlags.InputHint | XWMHintsFlags.StateHint | XWMHintsFlags.WindowGroupHint);
3023 wm_hints.input = !StyleSet (cp.Style, WindowStyles.WS_DISABLED);
3024 wm_hints.initial_state = StyleSet (cp.Style, WindowStyles.WS_MINIMIZE) ? XInitialState.IconicState : XInitialState.NormalState;
3026 if (ParentHandle != RootWindow) {
3027 wm_hints.window_group = hwnd.whole_window;
3029 wm_hints.window_group = ParentHandle;
3033 XSetWMHints(DisplayHandle, hwnd.whole_window, ref wm_hints );
3036 if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZE)) {
3037 SetWindowState(hwnd.Handle, FormWindowState.Minimized);
3038 } else if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZE)) {
3039 SetWindowState(hwnd.Handle, FormWindowState.Maximized);
3042 // for now make all windows dnd enabled
3043 Dnd.SetAllowDrop (hwnd, true);
3045 // Set caption/window title
3046 Text(hwnd.Handle, cp.Caption);
3048 SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1, IntPtr.Zero /* XXX unused */);
3049 SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);
3051 if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
3052 hwnd.visible = true;
3053 MapWindow(hwnd, WindowType.Both);
3054 if (!(Control.FromHandle(hwnd.Handle) is Form))
3055 SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
3061 internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height)
3063 CreateParams create_params = new CreateParams();
3065 create_params.Caption = "";
3066 create_params.X = X;
3067 create_params.Y = Y;
3068 create_params.Width = Width;
3069 create_params.Height = Height;
3071 create_params.ClassName=XplatUI.GetDefaultClassName (GetType ());
3072 create_params.ClassStyle = 0;
3073 create_params.ExStyle=0;
3074 create_params.Parent=IntPtr.Zero;
3075 create_params.Param=0;
3077 return CreateWindow(create_params);
3080 internal override IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot)
3083 Bitmap cursor_bitmap;
3091 IntPtr cursor_pixmap;
3098 if (XQueryBestCursor(DisplayHandle, RootWindow, bitmap.Width, bitmap.Height, out width, out height) == 0) {
3102 // Win32 only allows creation cursors of a certain size
3103 if ((bitmap.Width != width) || (bitmap.Width != height)) {
3104 cursor_bitmap = new Bitmap(bitmap, new Size(width, height));
3105 cursor_mask = new Bitmap(mask, new Size(width, height));
3107 cursor_bitmap = bitmap;
3111 width = cursor_bitmap.Width;
3112 height = cursor_bitmap.Height;
3114 cursor_bits = new Byte[(width / 8) * height];
3115 mask_bits = new Byte[(width / 8) * height];
3117 for (int y = 0; y < height; y++) {
3118 for (int x = 0; x < width; x++) {
3119 c_pixel = cursor_bitmap.GetPixel(x, y);
3120 m_pixel = cursor_mask.GetPixel(x, y);
3122 and = c_pixel == cursor_pixel;
3123 xor = m_pixel == mask_pixel;
3127 // cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8))); // The bit already is 0
3128 mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
3129 } else if (and && !xor) {
3131 cursor_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
3132 mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
3134 } else if (and && !xor) {
3136 } else if (and && xor) {
3139 // X11 doesn't know the 'reverse screen' concept, so we'll treat them the same
3140 // we want both to be 0 so nothing to be done
3141 //cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));
3142 //mask_bits[y * width / 8 + x / 8] |= (byte)(01 << (x % 8));
3148 cursor_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, cursor_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
3149 mask_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, mask_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
3153 fg.pixel = XWhitePixel(DisplayHandle, ScreenNo);
3154 fg.red = (ushort)65535;
3155 fg.green = (ushort)65535;
3156 fg.blue = (ushort)65535;
3158 bg.pixel = XBlackPixel(DisplayHandle, ScreenNo);
3160 cursor = XCreatePixmapCursor(DisplayHandle, cursor_pixmap, mask_pixmap, ref fg, ref bg, xHotSpot, yHotSpot);
3162 XFreePixmap(DisplayHandle, cursor_pixmap);
3163 XFreePixmap(DisplayHandle, mask_pixmap);
3168 internal override Bitmap DefineStdCursorBitmap (StdCursor id)
3170 CursorFontShape shape;
3177 shape = StdCursorToFontShape (id);
3178 name = shape.ToString ().Replace ("XC_", string.Empty);
3179 size = XcursorGetDefaultSize (DisplayHandle);
3180 theme = XcursorGetTheme (DisplayHandle);
3181 IntPtr images_ptr = XcursorLibraryLoadImages (name, theme, size);
3182 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);
3184 if (images_ptr == IntPtr.Zero) {
3188 XcursorImages images = (XcursorImages) Marshal.PtrToStructure (images_ptr, typeof (XcursorImages));
3189 DriverDebug ("DefineStdCursorBitmap, cursor has {0} images", images.nimage);
3191 if (images.nimage > 0) {
3192 // We only care about the first image.
3193 XcursorImage image = (XcursorImage)Marshal.PtrToStructure (Marshal.ReadIntPtr (images.images), typeof (XcursorImage));
3195 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);
3197 if (image.width <= short.MaxValue && image.height <= short.MaxValue) {
3198 int [] pixels = new int [image.width * image.height];
3199 Marshal.Copy (image.pixels, pixels, 0, pixels.Length);
3200 bmp = new Bitmap (image.width, image.height);
3201 for (int w = 0; w < image.width; w++) {
3202 for (int h = 0; h < image.height; h++) {
3203 bmp.SetPixel (w, h, Color.FromArgb (pixels [h * image.width + w]));
3209 XcursorImagesDestroy (images_ptr);
3211 } catch (DllNotFoundException ex) {
3212 Console.WriteLine ("Could not load libXcursor: " + ex.Message + " (" + ex.GetType ().Name + ")");
3220 internal override IntPtr DefineStdCursor(StdCursor id)
3222 CursorFontShape shape;
3225 shape = StdCursorToFontShape (id);
3228 cursor = XCreateFontCursor(DisplayHandle, shape);
3233 internal static CursorFontShape StdCursorToFontShape (StdCursor id)
3235 CursorFontShape shape;
3236 // FIXME - define missing shapes
3239 case StdCursor.AppStarting: {
3240 shape = CursorFontShape.XC_watch;
3244 case StdCursor.Arrow: {
3245 shape = CursorFontShape.XC_top_left_arrow;
3249 case StdCursor.Cross: {
3250 shape = CursorFontShape.XC_crosshair;
3254 case StdCursor.Default: {
3255 shape = CursorFontShape.XC_top_left_arrow;
3259 case StdCursor.Hand: {
3260 shape = CursorFontShape.XC_hand1;
3264 case StdCursor.Help: {
3265 shape = CursorFontShape.XC_question_arrow;
3269 case StdCursor.HSplit: {
3270 shape = CursorFontShape.XC_sb_v_double_arrow;
3274 case StdCursor.IBeam: {
3275 shape = CursorFontShape.XC_xterm;
3279 case StdCursor.No: {
3280 shape = CursorFontShape.XC_circle;
3284 case StdCursor.NoMove2D: {
3285 shape = CursorFontShape.XC_fleur;
3289 case StdCursor.NoMoveHoriz: {
3290 shape = CursorFontShape.XC_fleur;
3294 case StdCursor.NoMoveVert: {
3295 shape = CursorFontShape.XC_fleur;
3299 case StdCursor.PanEast: {
3300 shape = CursorFontShape.XC_fleur;
3304 case StdCursor.PanNE: {
3305 shape = CursorFontShape.XC_fleur;
3309 case StdCursor.PanNorth: {
3310 shape = CursorFontShape.XC_fleur;
3314 case StdCursor.PanNW: {
3315 shape = CursorFontShape.XC_fleur;
3319 case StdCursor.PanSE: {
3320 shape = CursorFontShape.XC_fleur;
3324 case StdCursor.PanSouth: {
3325 shape = CursorFontShape.XC_fleur;
3329 case StdCursor.PanSW: {
3330 shape = CursorFontShape.XC_fleur;
3334 case StdCursor.PanWest: {
3335 shape = CursorFontShape.XC_sizing;
3339 case StdCursor.SizeAll: {
3340 shape = CursorFontShape.XC_fleur;
3344 case StdCursor.SizeNESW: {
3345 shape = CursorFontShape.XC_top_right_corner;
3349 case StdCursor.SizeNS: {
3350 shape = CursorFontShape.XC_sb_v_double_arrow;
3354 case StdCursor.SizeNWSE: {
3355 shape = CursorFontShape.XC_top_left_corner;
3359 case StdCursor.SizeWE: {
3360 shape = CursorFontShape.XC_sb_h_double_arrow;
3364 case StdCursor.UpArrow: {
3365 shape = CursorFontShape.XC_center_ptr;
3369 case StdCursor.VSplit: {
3370 shape = CursorFontShape.XC_sb_h_double_arrow;
3374 case StdCursor.WaitCursor: {
3375 shape = CursorFontShape.XC_watch;
3380 shape = (CursorFontShape) 0;
3388 internal override IntPtr DefWndProc(ref Message msg)
3390 switch ((Msg)msg.Msg) {
3392 case Msg.WM_IME_COMPOSITION:
3393 string s = Keyboard.GetCompositionString ();
3394 foreach (char c in s)
3395 SendMessage (msg.HWnd, Msg.WM_IME_CHAR, (IntPtr) c, msg.LParam);
3398 case Msg.WM_IME_CHAR:
3399 // On Windows API it sends two WM_CHAR messages for each byte, but
3400 // I wonder if it is worthy to emulate it (also no idea how to
3401 // reconstruct those bytes into chars).
3402 SendMessage (msg.HWnd, Msg.WM_CHAR, msg.WParam, msg.LParam);
3405 case Msg.WM_PAINT: {
3408 hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3410 hwnd.expose_pending = false;
3416 case Msg.WM_NCPAINT: {
3419 hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3421 hwnd.nc_expose_pending = false;
3427 case Msg.WM_NCCALCSIZE: {
3430 if (msg.WParam == (IntPtr)1) {
3431 hwnd = Hwnd.GetObjectFromWindow (msg.HWnd);
3433 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
3434 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (msg.LParam, typeof (XplatUIWin32.NCCALCSIZE_PARAMS));
3436 // Add all the stuff X is supposed to draw.
3437 Control ctrl = Control.FromHandle (hwnd.Handle);
3440 Hwnd.Borders rect = Hwnd.GetBorders (ctrl.GetCreateParams (), null);
3442 ncp.rgrc1.top += rect.top;
3443 ncp.rgrc1.bottom -= rect.bottom;
3444 ncp.rgrc1.left += rect.left;
3445 ncp.rgrc1.right -= rect.right;
3447 Marshal.StructureToPtr (ncp, msg.LParam, true);
3454 case Msg.WM_CONTEXTMENU: {
3457 hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3459 if ((hwnd != null) && (hwnd.parent != null)) {
3460 SendMessage(hwnd.parent.client_window, Msg.WM_CONTEXTMENU, msg.WParam, msg.LParam);
3465 case Msg.WM_MOUSEWHEEL: {
3468 hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3470 if ((hwnd != null) && (hwnd.parent != null)) {
3471 SendMessage(hwnd.parent.client_window, Msg.WM_MOUSEWHEEL, msg.WParam, msg.LParam);
3472 if (msg.Result == IntPtr.Zero) {
3479 case Msg.WM_SETCURSOR: {
3482 hwnd = Hwnd.GetObjectFromWindow(msg.HWnd);
3484 break; // not sure how this happens, but it does
3486 // Pass to parent window first
3487 while ((hwnd.parent != null) && (msg.Result == IntPtr.Zero)) {
3489 msg.Result = NativeWindow.WndProc(hwnd.Handle, Msg.WM_SETCURSOR, msg.HWnd, msg.LParam);
3492 if (msg.Result == IntPtr.Zero) {
3495 switch((HitTest)(msg.LParam.ToInt32() & 0xffff)) {
3496 case HitTest.HTBOTTOM: handle = Cursors.SizeNS.handle; break;
3497 case HitTest.HTBORDER: handle = Cursors.SizeNS.handle; break;
3498 case HitTest.HTBOTTOMLEFT: handle = Cursors.SizeNESW.handle; break;
3499 case HitTest.HTBOTTOMRIGHT: handle = Cursors.SizeNWSE.handle; break;
3500 case HitTest.HTERROR: if ((msg.LParam.ToInt32() >> 16) == (int)Msg.WM_LBUTTONDOWN) {
3501 AudibleAlert(AlertType.Default);
3503 handle = Cursors.Default.handle;
3506 case HitTest.HTHELP: handle = Cursors.Help.handle; break;
3507 case HitTest.HTLEFT: handle = Cursors.SizeWE.handle; break;
3508 case HitTest.HTRIGHT: handle = Cursors.SizeWE.handle; break;
3509 case HitTest.HTTOP: handle = Cursors.SizeNS.handle; break;
3510 case HitTest.HTTOPLEFT: handle = Cursors.SizeNWSE.handle; break;
3511 case HitTest.HTTOPRIGHT: handle = Cursors.SizeNESW.handle; break;
3514 case HitTest.HTGROWBOX:
3515 case HitTest.HTSIZE:
3516 case HitTest.HTZOOM:
3517 case HitTest.HTVSCROLL:
3518 case HitTest.HTSYSMENU:
3519 case HitTest.HTREDUCE:
3520 case HitTest.HTNOWHERE:
3521 case HitTest.HTMAXBUTTON:
3522 case HitTest.HTMINBUTTON:
3523 case HitTest.HTMENU:
3524 case HitTest.HSCROLL:
3525 case HitTest.HTBOTTOM:
3526 case HitTest.HTCAPTION:
3527 case HitTest.HTCLIENT:
3528 case HitTest.HTCLOSE:
3530 default: handle = Cursors.Default.handle; break;
3532 SetCursor(msg.HWnd, handle);
3540 internal override void DestroyCaret(IntPtr handle)
3542 if (Caret.Hwnd == handle) {
3543 if (Caret.Visible) {
3547 if (Caret.gc != IntPtr.Zero) {
3548 XFreeGC(DisplayHandle, Caret.gc);
3549 Caret.gc = IntPtr.Zero;
3551 Caret.Hwnd = IntPtr.Zero;
3552 Caret.Visible = false;
3557 internal override void DestroyCursor(IntPtr cursor)
3560 XFreeCursor(DisplayHandle, cursor);
3564 internal override void DestroyWindow(IntPtr handle)
3567 hwnd = Hwnd.ObjectFromHandle(handle);
3569 // The window should never ever be a zombie here, since we should
3570 // wait until it's completely dead before returning from
3571 // "destroying" calls, but just in case....
3572 if (hwnd == null || hwnd.zombie) {
3573 DriverDebug ("window {0:X} already destroyed", handle.ToInt32());
3577 DriverDebug ("Destroying window {0}", XplatUI.Window(hwnd.client_window));
3579 SendParentNotify (hwnd.Handle, Msg.WM_DESTROY, int.MaxValue, int.MaxValue);
3581 CleanupCachedWindows (hwnd);
3583 ArrayList windows = new ArrayList ();
3585 AccumulateDestroyedHandles (Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle), windows);
3588 foreach (Hwnd h in windows) {
3589 SendMessage (h.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
3594 if (hwnd.whole_window != IntPtr.Zero) {
3595 DriverDebug ("XDestroyWindow (whole_window = {0:X})", hwnd.whole_window.ToInt32());
3596 Keyboard.DestroyICForWindow (hwnd.whole_window);
3597 XDestroyWindow(DisplayHandle, hwnd.whole_window);
3599 else if (hwnd.client_window != IntPtr.Zero) {
3600 DriverDebug ("XDestroyWindow (client_window = {0:X})", hwnd.client_window.ToInt32());
3601 Keyboard.DestroyICForWindow (hwnd.client_window);
3602 XDestroyWindow(DisplayHandle, hwnd.client_window);
3608 internal override IntPtr DispatchMessage(ref MSG msg)
3610 return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
3613 IntPtr GetReversibleScreenGC (Color backColor)
3615 XGCValues gc_values;
3619 XColor xcolor = new XColor();
3620 xcolor.red = (ushort)(backColor.R * 257);
3621 xcolor.green = (ushort)(backColor.G * 257);
3622 xcolor.blue = (ushort)(backColor.B * 257);
3623 XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3624 pixel = (uint)xcolor.pixel.ToInt32();
3627 gc_values = new XGCValues();
3629 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
3630 gc_values.foreground = (IntPtr)pixel;
3632 gc = XCreateGC(DisplayHandle, RootWindow, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCForeground)), ref gc_values);
3633 XSetForeground(DisplayHandle, gc, (UIntPtr)pixel);
3634 XSetFunction(DisplayHandle, gc, GXFunction.GXxor);
3639 IntPtr GetReversibleControlGC (Control control, int line_width)
3641 XGCValues gc_values;
3644 gc_values = new XGCValues();
3646 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
3647 gc_values.line_width = line_width;
3648 gc_values.foreground = XBlackPixel(DisplayHandle, ScreenNo);
3650 // This logic will give us true rubber bands: (libsx, SANE_XOR)
3651 //mask = foreground ^ background;
3652 //XSetForeground(DisplayHandle, gc, 0xffffffff);
3653 //XSetBackground(DisplayHandle, gc, background);
3654 //XSetFunction(DisplayHandle, gc, GXxor);
3655 //XSetPlaneMask(DisplayHandle, gc, mask);
3658 gc = XCreateGC(DisplayHandle, control.Handle, new IntPtr ((int) (GCFunction.GCSubwindowMode | GCFunction.GCLineWidth | GCFunction.GCForeground)), ref gc_values);
3662 XColor xcolor = new XColor();
3664 xcolor.red = (ushort)(control.ForeColor.R * 257);
3665 xcolor.green = (ushort)(control.ForeColor.G * 257);
3666 xcolor.blue = (ushort)(control.ForeColor.B * 257);
3667 XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3668 foreground = (uint)xcolor.pixel.ToInt32();
3670 xcolor.red = (ushort)(control.BackColor.R * 257);
3671 xcolor.green = (ushort)(control.BackColor.G * 257);
3672 xcolor.blue = (ushort)(control.BackColor.B * 257);
3673 XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
3674 background = (uint)xcolor.pixel.ToInt32();
3676 uint mask = foreground ^ background;
3678 XSetForeground(DisplayHandle, gc, (UIntPtr)0xffffffff);
3679 XSetBackground(DisplayHandle, gc, (UIntPtr)background);
3680 XSetFunction(DisplayHandle, gc, GXFunction.GXxor);
3681 XSetPlaneMask(DisplayHandle, gc, (IntPtr)mask);
3686 internal override void DrawReversibleLine(Point start, Point end, Color backColor)
3688 if (backColor.GetBrightness() < 0.5)
3689 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3691 IntPtr gc = GetReversibleScreenGC (backColor);
3693 XDrawLine (DisplayHandle, RootWindow, gc, start.X, start.Y, end.X, end.Y);
3695 XFreeGC(DisplayHandle, gc);
3698 internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style)
3700 if (backColor.GetBrightness() < 0.5)
3701 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3703 IntPtr gc = GetReversibleScreenGC (backColor);
3705 if (rectangle.Width < 0) {
3706 rectangle.X += rectangle.Width;
3707 rectangle.Width = -rectangle.Width;
3709 if (rectangle.Height < 0) {
3710 rectangle.Y += rectangle.Height;
3711 rectangle.Height = -rectangle.Height;
3715 GCLineStyle line_style = GCLineStyle.LineSolid;
3716 GCCapStyle cap_style = GCCapStyle.CapButt;
3717 GCJoinStyle join_style = GCJoinStyle.JoinMiter;
3720 case FrameStyle.Dashed:
3721 line_style = GCLineStyle.LineOnOffDash;
3723 case FrameStyle.Thick:
3728 XSetLineAttributes (DisplayHandle, gc, line_width, line_style, cap_style, join_style);
3730 XDrawRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
3732 XFreeGC(DisplayHandle, gc);
3735 internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor)
3737 if (backColor.GetBrightness() < 0.5)
3738 backColor = Color.FromArgb(255 - backColor.R, 255 - backColor.G, 255 - backColor.B);
3740 IntPtr gc = GetReversibleScreenGC (backColor);
3742 if (rectangle.Width < 0) {
3743 rectangle.X += rectangle.Width;
3744 rectangle.Width = -rectangle.Width;
3746 if (rectangle.Height < 0) {
3747 rectangle.Y += rectangle.Height;
3748 rectangle.Height = -rectangle.Height;
3750 XFillRectangle(DisplayHandle, RootWindow, gc, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
3752 XFreeGC(DisplayHandle, gc);
3755 internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width)
3758 Control control = Control.FromHandle(handle);
3760 gc = GetReversibleControlGC (control, line_width);
3762 if ((rect.Width > 0) && (rect.Height > 0)) {
3763 XDrawRectangle(DisplayHandle, control.Handle, gc, rect.Left, rect.Top, rect.Width, rect.Height);
3765 if (rect.Width > 0) {
3766 XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.Right, rect.Y);
3768 XDrawLine(DisplayHandle, control.Handle, gc, rect.X, rect.Y, rect.X, rect.Bottom);
3771 XFreeGC(DisplayHandle, gc);
3774 internal override void DoEvents()
3776 DebugHelper.Enter ();
3778 MSG msg = new MSG ();
3781 if (OverrideCursorHandle != IntPtr.Zero) {
3782 OverrideCursorHandle = IntPtr.Zero;
3785 queue = ThreadQueue(Thread.CurrentThread);
3787 queue.DispatchIdle = false;
3790 while (PeekMessage(queue, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
3791 Message m = Message.Create (msg.hwnd, (int)msg.message, msg.wParam, msg.lParam);
3793 if (Application.FilterMessage (ref m))
3796 TranslateMessage (ref msg);
3797 DispatchMessage (ref msg);
3799 string key = msg.hwnd + ":" + msg.message;
3800 if (messageHold[key] != null) {
3801 messageHold[key] = ((int)messageHold[key]) - 1;
3802 DebugHelper.WriteLine ("Got " + msg + " for " + key);
3806 in_doevents = false;
3807 queue.DispatchIdle = true;
3809 DebugHelper.Leave ();
3812 internal override void EnableWindow(IntPtr handle, bool Enable)
3816 hwnd = Hwnd.ObjectFromHandle(handle);
3818 hwnd.Enabled = Enable;
3822 internal override void EndLoop(Thread thread)
3824 // This is where we one day will shut down the loop for the thread
3827 internal override IntPtr GetActive()
3833 IntPtr prop = IntPtr.Zero;
3834 IntPtr active = IntPtr.Zero;
3836 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);
3837 if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
3838 active = (IntPtr)Marshal.ReadInt32(prop);
3841 // The window manager does not support _NET_ACTIVE_WINDOW. Fall back to XGetInputFocus.
3842 IntPtr revert_to = IntPtr.Zero;
3843 XGetInputFocus(DisplayHandle, out active, out revert_to);
3846 if (active != IntPtr.Zero) {
3849 hwnd = Hwnd.GetObjectFromWindow(active);
3851 active = hwnd.Handle;
3853 active = IntPtr.Zero;
3859 internal override Region GetClipRegion(IntPtr handle)
3863 hwnd = Hwnd.ObjectFromHandle(handle);
3865 return hwnd.UserClip;
3871 internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y)
3879 internal override void GetDisplaySize(out Size size)
3881 XWindowAttributes attributes=new XWindowAttributes();
3884 // FIXME - use _NET_WM messages instead?
3885 XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
3888 size = new Size(attributes.width, attributes.height);
3891 internal override SizeF GetAutoScaleSize(Font font)
3895 string magic_string = "The quick brown fox jumped over the lazy dog.";
3896 double magic_number = 44.549996948242189;
3898 g = Graphics.FromHwnd(FosterParent);
3900 width = (float) (g.MeasureString (magic_string, font).Width / magic_number);
3901 return new SizeF(width, font.Height);
3904 internal override IntPtr GetParent(IntPtr handle)
3908 hwnd = Hwnd.ObjectFromHandle(handle);
3909 if (hwnd != null && hwnd.parent != null) {
3910 return hwnd.parent.Handle;
3915 // This is a nop on win32 and x11
3916 internal override IntPtr GetPreviousWindow(IntPtr handle)
3921 internal override void GetCursorPos(IntPtr handle, out int x, out int y)
3932 if (handle != IntPtr.Zero) {
3933 use_handle = Hwnd.ObjectFromHandle(handle).client_window;
3935 use_handle = RootWindow;
3939 QueryPointer (DisplayHandle, use_handle, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
3942 if (handle != IntPtr.Zero) {
3951 internal override IntPtr GetFocus()
3957 internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent)
3959 FontFamily ff = font.FontFamily;
3960 ascent = ff.GetCellAscent (font.Style);
3961 descent = ff.GetCellDescent (font.Style);
3965 internal override Point GetMenuOrigin(IntPtr handle)
3969 hwnd = Hwnd.ObjectFromHandle(handle);
3972 return hwnd.MenuOrigin;
3977 [MonoTODO("Implement filtering")]
3978 internal override bool GetMessage(Object queue_id, ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax)
3986 if (((XEventQueue)queue_id).Count > 0) {
3987 xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
3989 UpdateMessageQueue ((XEventQueue)queue_id);
3991 if (((XEventQueue)queue_id).Count > 0) {
3992 xevent = (XEvent) ((XEventQueue)queue_id).Dequeue ();
3993 } else if (((XEventQueue)queue_id).Paint.Count > 0) {
3994 xevent = ((XEventQueue)queue_id).Paint.Dequeue();
3996 msg.hwnd= IntPtr.Zero;
3997 msg.message = Msg.WM_ENTERIDLE;
4002 hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
4004 #if DriverDebugDestroy
4007 Console.WriteLine ( "GetMessage zombie, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
4009 Console.WriteLine ( "GetMessage, got Event: " + xevent.ToString () + " for 0x{0:x}", hwnd.Handle.ToInt32());
4011 // Handle messages for windows that are already or are about to be destroyed.
4013 // we need a special block for this because unless we remove the hwnd from the paint
4014 // queue it will always stay there (since we don't handle the expose), and we'll
4015 // effectively loop infinitely trying to repaint a non-existant window.
4016 if (hwnd != null && hwnd.zombie && xevent.type == XEventName.Expose) {
4017 hwnd.expose_pending = hwnd.nc_expose_pending = false;
4018 hwnd.Queue.Paint.Remove (hwnd);
4019 goto ProcessNextMessage;
4022 // We need to make sure we only allow DestroyNotify events through for zombie
4023 // hwnds, since much of the event handling code makes requests using the hwnd's
4024 // client_window, and that'll result in BadWindow errors if there's some lag
4025 // between the XDestroyWindow call and the DestroyNotify event.
4026 if (hwnd == null || hwnd.zombie && xevent.AnyEvent.type != XEventName.ClientMessage) {
4027 DriverDebug("GetMessage(): Got message {0} for non-existent or already destroyed window {1:X}", xevent.type, xevent.AnyEvent.window.ToInt32());
4028 goto ProcessNextMessage;
4032 // If we get here, that means the window is no more but there are Client Messages
4033 // to be processed, probably a Posted message (for instance, an WM_ACTIVATE message)
4034 // We don't want anything else to run but the ClientMessage block, so reset all hwnd
4035 // properties that might cause other processing to occur.
4037 hwnd.resizing_or_moving = false;
4040 if (hwnd.client_window == xevent.AnyEvent.window) {
4042 //Console.WriteLine("Client message {1}, sending to window {0:X}", msg.hwnd.ToInt32(), xevent.type);
4045 //Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
4048 msg.hwnd = hwnd.Handle;
4050 // Windows sends WM_ENTERSIZEMOVE when a form resize/move operation starts and WM_EXITSIZEMOVE
4051 // when it is done. The problem in X11 is that there is no concept of start-end of a moving/sizing.
4052 // Configure events ("this window has resized/moved") are sent for each step of the resize. We send a
4053 // WM_ENTERSIZEMOVE when we get the first Configure event. The problem is the WM_EXITSIZEMOVE.
4055 // - There is no way for us to know which is the last Configure event. We can't traverse the events
4056 // queue, because the next configure event might not be pending yet.
4057 // - We can't get ButtonPress/Release events for the window decorations, because they are not part
4058 // of the window(s) we manage.
4059 // - We can't rely on the mouse state to change to "up" before the last Configure event. It doesn't.
4061 // We are almost 100% guaranteed to get another event (e.g Expose or other), but we can't know for sure
4062 // which, so we have here to check if the mouse buttons state is "up" and send the WM_EXITSIZEMOVE
4064 if (hwnd.resizing_or_moving) {
4065 int root_x, root_y, win_x, win_y, keys_buttons;
4067 XQueryPointer (DisplayHandle, hwnd.Handle, out root, out child, out root_x, out root_y,
4068 out win_x, out win_y, out keys_buttons);
4069 if ((keys_buttons & (int)MouseKeyMasks.Button1Mask) == 0 &&
4070 (keys_buttons & (int)MouseKeyMasks.Button2Mask) == 0 &&
4071 (keys_buttons & (int)MouseKeyMasks.Button3Mask) == 0) {
4072 hwnd.resizing_or_moving = false;
4073 SendMessage (hwnd.Handle, Msg.WM_EXITSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
4078 // If you add a new event to this switch make sure to add it in
4079 // UpdateMessage also unless it is not coming through the X event system.
4081 switch(xevent.type) {
4082 case XEventName.KeyPress: {
4083 Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
4085 // F1 key special case - WM_HELP sending
4086 if (msg.wParam == (IntPtr)VirtualKeys.VK_F1 || msg.wParam == (IntPtr)VirtualKeys.VK_HELP) {
4087 // Send wM_HELP and then return it as a keypress message in
4088 // case it needs to be preproccessed.
4089 HELPINFO helpInfo = new HELPINFO ();
4090 GetCursorPos (IntPtr.Zero, out helpInfo.MousePos.x, out helpInfo.MousePos.y);
4091 IntPtr helpInfoPtr = Marshal.AllocHGlobal (Marshal.SizeOf (helpInfo));
4092 Marshal.StructureToPtr (helpInfo, helpInfoPtr, true);
4093 NativeWindow.WndProc (FocusWindow, Msg.WM_HELP, IntPtr.Zero, helpInfoPtr);
4094 Marshal.FreeHGlobal (helpInfoPtr);
4099 case XEventName.KeyRelease: {
4100 Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
4104 case XEventName.ButtonPress: {
4105 switch(xevent.ButtonEvent.button) {
4107 MouseState |= MouseButtons.Left;
4109 msg.message = Msg.WM_LBUTTONDOWN;
4110 msg.wParam = GetMousewParam (0);
4112 msg.message = Msg.WM_NCLBUTTONDOWN;
4113 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4114 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4120 MouseState |= MouseButtons.Middle;
4122 msg.message = Msg.WM_MBUTTONDOWN;
4123 msg.wParam = GetMousewParam (0);
4125 msg.message = Msg.WM_NCMBUTTONDOWN;
4126 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4127 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4133 MouseState |= MouseButtons.Right;
4135 msg.message = Msg.WM_RBUTTONDOWN;
4136 msg.wParam = GetMousewParam (0);
4138 msg.message = Msg.WM_NCRBUTTONDOWN;
4139 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4140 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4146 msg.hwnd = FocusWindow;
4147 msg.message=Msg.WM_MOUSEWHEEL;
4148 msg.wParam=GetMousewParam(120);
4153 msg.hwnd = FocusWindow;
4154 msg.message=Msg.WM_MOUSEWHEEL;
4155 msg.wParam=GetMousewParam(-120);
4161 msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
4162 mouse_position.X = xevent.ButtonEvent.x;
4163 mouse_position.Y = xevent.ButtonEvent.y;
4165 if (!hwnd.Enabled) {
4168 msg.hwnd = hwnd.EnabledHwnd;
4169 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);
4170 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4173 if (Grab.Hwnd != IntPtr.Zero) {
4174 msg.hwnd = Grab.Hwnd;
4177 if (ClickPending.Pending && ((((long)xevent.ButtonEvent.time - ClickPending.Time) < DoubleClickInterval) && (msg.wParam == ClickPending.wParam) && (msg.lParam == ClickPending.lParam) && (msg.message == ClickPending.Message))) {
4178 // Looks like a genuine double click, clicked twice on the same spot with the same keys
4179 switch(xevent.ButtonEvent.button) {
4181 msg.message = client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK;
4186 msg.message = client ? Msg.WM_MBUTTONDBLCLK : Msg.WM_NCMBUTTONDBLCLK;
4191 msg.message = client ? Msg.WM_RBUTTONDBLCLK : Msg.WM_NCRBUTTONDBLCLK;
4195 ClickPending.Pending = false;
4197 ClickPending.Pending = true;
4198 ClickPending.Hwnd = msg.hwnd;
4199 ClickPending.Message = msg.message;
4200 ClickPending.wParam = msg.wParam;
4201 ClickPending.lParam = msg.lParam;
4202 ClickPending.Time = (long)xevent.ButtonEvent.time;
4205 if (msg.message == Msg.WM_LBUTTONDOWN || msg.message == Msg.WM_MBUTTONDOWN || msg.message == Msg.WM_RBUTTONDOWN) {
4206 SendParentNotify(msg.hwnd, msg.message, mouse_position.X, mouse_position.Y);
4212 case XEventName.ButtonRelease: {
4213 switch(xevent.ButtonEvent.button) {
4216 msg.message = Msg.WM_LBUTTONUP;
4218 msg.message = Msg.WM_NCLBUTTONUP;
4219 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4220 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4222 MouseState &= ~MouseButtons.Left;
4223 msg.wParam = GetMousewParam (0);
4229 msg.message = Msg.WM_MBUTTONUP;
4231 msg.message = Msg.WM_NCMBUTTONUP;
4232 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4233 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4235 MouseState &= ~MouseButtons.Middle;
4236 msg.wParam = GetMousewParam (0);
4242 msg.message = Msg.WM_RBUTTONUP;
4244 msg.message = Msg.WM_NCRBUTTONUP;
4245 msg.wParam = (IntPtr) NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4246 MenuToScreen (xevent.AnyEvent.window, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
4248 MouseState &= ~MouseButtons.Right;
4249 msg.wParam = GetMousewParam (0);
4254 goto ProcessNextMessage;
4258 goto ProcessNextMessage;
4262 if (!hwnd.Enabled) {
4265 msg.hwnd = hwnd.EnabledHwnd;
4266 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);
4267 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4270 if (Grab.Hwnd != IntPtr.Zero) {
4271 msg.hwnd = Grab.Hwnd;
4274 msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
4275 mouse_position.X = xevent.ButtonEvent.x;
4276 mouse_position.Y = xevent.ButtonEvent.y;
4278 // Win32 splurts MouseMove events all over the place, regardless of whether the mouse is actually moving or
4279 // not, especially after mousedown and mouseup. To support apps relying on mousemove events between and after
4280 // mouse clicks to repaint or whatever, we generate a mousemove event here. *sigh*
4281 if (msg.message == Msg.WM_LBUTTONUP || msg.message == Msg.WM_MBUTTONUP || msg.message == Msg.WM_RBUTTONUP) {
4282 XEvent motionEvent = new XEvent ();
4283 motionEvent.type = XEventName.MotionNotify;
4284 motionEvent.MotionEvent.display = DisplayHandle;
4285 motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
4286 motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
4287 motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
4288 hwnd.Queue.EnqueueLocked (motionEvent);
4293 case XEventName.MotionNotify: {
4295 DriverDebug("GetMessage(): Window {0:X} MotionNotify x={1} y={2}",
4296 client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
4297 xevent.MotionEvent.x, xevent.MotionEvent.y);
4299 if (Grab.Hwnd != IntPtr.Zero) {
4300 msg.hwnd = Grab.Hwnd;
4303 NativeWindow.WndProc(msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
4307 if (xevent.MotionEvent.is_hint != 0)
4311 XQueryPointer (DisplayHandle, xevent.AnyEvent.window,
4312 out root, out child,
4313 out xevent.MotionEvent.x_root,
4314 out xevent.MotionEvent.y_root,
4315 out xevent.MotionEvent.x,
4316 out xevent.MotionEvent.y, out mask);
4319 msg.message = Msg.WM_MOUSEMOVE;
4320 msg.wParam = GetMousewParam(0);
4321 msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x & 0xFFFF);
4323 if (!hwnd.Enabled) {
4326 msg.hwnd = hwnd.EnabledHwnd;
4327 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);
4328 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4331 mouse_position.X = xevent.MotionEvent.x;
4332 mouse_position.Y = xevent.MotionEvent.y;
4334 if ((HoverState.Timer.Enabled) &&
4335 (((mouse_position.X + HoverState.Size.Width) < HoverState.X) ||
4336 ((mouse_position.X - HoverState.Size.Width) > HoverState.X) ||
4337 ((mouse_position.Y + HoverState.Size.Height) < HoverState.Y) ||
4338 ((mouse_position.Y - HoverState.Size.Height) > HoverState.Y))) {
4339 HoverState.Timer.Stop();
4340 HoverState.Timer.Start();
4341 HoverState.X = mouse_position.X;
4342 HoverState.Y = mouse_position.Y;
4350 DriverDebug("GetMessage(): non-client area {0:X} MotionNotify x={1} y={2}",
4351 client ? hwnd.client_window.ToInt32() : hwnd.whole_window.ToInt32(),
4352 xevent.MotionEvent.x, xevent.MotionEvent.y);
4353 msg.message = Msg.WM_NCMOUSEMOVE;
4355 if (!hwnd.Enabled) {
4356 msg.hwnd = hwnd.EnabledHwnd;
4357 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);
4358 msg.lParam = (IntPtr)(mouse_position.Y << 16 | mouse_position.X);
4361 ht = NCHitTest (hwnd, xevent.MotionEvent.x, xevent.MotionEvent.y);
4362 NativeWindow.WndProc(hwnd.client_window, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)ht);
4364 mouse_position.X = xevent.MotionEvent.x;
4365 mouse_position.Y = xevent.MotionEvent.y;
4371 case XEventName.EnterNotify: {
4372 if (!hwnd.Enabled) {
4373 goto ProcessNextMessage;
4375 if (xevent.CrossingEvent.mode == NotifyMode.NotifyGrab || xevent.AnyEvent.window != hwnd.client_window) {
4376 goto ProcessNextMessage;
4378 if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) { // Pseudo motion caused by grabbing
4379 if (LastPointerWindow == xevent.AnyEvent.window)
4380 goto ProcessNextMessage;
4382 if (LastPointerWindow != IntPtr.Zero) {
4383 Point enter_loc = new Point (xevent.ButtonEvent.x, xevent.ButtonEvent.y);
4385 // We need this due to EnterNotify being fired on all the parent controls
4386 // of the Control being grabbed, and obviously in that scenario we are not
4387 // actuallty entering them
4388 Control ctrl = Control.FromHandle (hwnd.client_window);
4389 foreach (Control child_control in ctrl.Controls.GetAllControls ())
4390 if (child_control.Bounds.Contains (enter_loc))
4391 goto ProcessNextMessage;
4393 // A MouseLeave/LeaveNotify event is sent to the previous window
4394 // until the mouse is ungrabbed, not when actually leaving its bounds
4395 int x = xevent.CrossingEvent.x_root;
4396 int y = xevent.CrossingEvent.y_root;
4397 ScreenToClient (LastPointerWindow, ref x, ref y);
4399 XEvent leaveEvent = new XEvent ();
4400 leaveEvent.type = XEventName.LeaveNotify;
4401 leaveEvent.CrossingEvent.display = DisplayHandle;
4402 leaveEvent.CrossingEvent.window = LastPointerWindow;
4403 leaveEvent.CrossingEvent.x = x;
4404 leaveEvent.CrossingEvent.y = y;
4405 leaveEvent.CrossingEvent.mode = NotifyMode.NotifyNormal;
4406 Hwnd last_pointer_hwnd = Hwnd.ObjectFromHandle (LastPointerWindow);
4407 last_pointer_hwnd.Queue.EnqueueLocked (leaveEvent);
4411 LastPointerWindow = xevent.AnyEvent.window;
4413 msg.message = Msg.WM_MOUSE_ENTER;
4414 HoverState.X = xevent.CrossingEvent.x;
4415 HoverState.Y = xevent.CrossingEvent.y;
4416 HoverState.Timer.Enabled = true;
4417 HoverState.Window = xevent.CrossingEvent.window;
4419 // Win32 sends a WM_MOUSEMOVE after mouse enter
4420 XEvent motionEvent = new XEvent ();
4421 motionEvent.type = XEventName.MotionNotify;
4422 motionEvent.MotionEvent.display = DisplayHandle;
4423 motionEvent.MotionEvent.window = xevent.ButtonEvent.window;
4424 motionEvent.MotionEvent.x = xevent.ButtonEvent.x;
4425 motionEvent.MotionEvent.y = xevent.ButtonEvent.y;
4426 hwnd.Queue.EnqueueLocked (motionEvent);
4430 case XEventName.LeaveNotify: {
4431 if (xevent.CrossingEvent.mode == NotifyMode.NotifyUngrab) {
4432 WindowUngrabbed (hwnd.Handle);
4433 goto ProcessNextMessage;
4435 if (!hwnd.Enabled) {
4436 goto ProcessNextMessage;
4438 if ((xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) || (xevent.CrossingEvent.window != hwnd.client_window)) {
4439 goto ProcessNextMessage;
4441 // If a grab is taking place, ignore it - we handle it in EnterNotify
4442 if (Grab.Hwnd != IntPtr.Zero)
4443 goto ProcessNextMessage;
4445 // Reset the cursor explicitly on X11.
4446 // X11 remembers the last set cursor for the window and in cases where
4447 // the control won't get a WM_SETCURSOR X11 will restore the last
4448 // known cursor, which we don't want.
4450 SetCursor (hwnd.client_window, IntPtr.Zero);
4452 msg.message=Msg.WM_MOUSELEAVE;
4453 HoverState.Timer.Enabled = false;
4454 HoverState.Window = IntPtr.Zero;
4459 case XEventName.CreateNotify: {
4460 if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {
4461 msg.message = WM_CREATE;
4462 // Set up CreateStruct
4464 goto ProcessNextMessage;
4471 case XEventName.ReparentNotify: {
4472 if (hwnd.parent == null) { // Toplevel
4473 if ((xevent.ReparentEvent.parent != IntPtr.Zero) && (xevent.ReparentEvent.window == hwnd.whole_window)) {
4474 hwnd.Reparented = true;
4476 // The location given by the event is not reliable between different wm's,
4477 // so use an alternative way of getting it.
4478 Point location = GetTopLevelWindowLocation (hwnd);
4479 hwnd.X = location.X;
4480 hwnd.Y = location.Y;
4482 if (hwnd.opacity != 0xffffffff) {
4485 opacity = (IntPtr)(Int32)hwnd.opacity;
4486 XChangeProperty(DisplayHandle, XGetParent(hwnd.whole_window), _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
4488 SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, msg.wParam, msg.lParam);
4489 goto ProcessNextMessage;
4491 hwnd.Reparented = false;
4492 goto ProcessNextMessage;
4495 goto ProcessNextMessage;
4498 case XEventName.ConfigureNotify: {
4499 if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
4500 DriverDebug("GetMessage(): Window {0:X} ConfigureNotify x={1} y={2} width={3} height={4}",
4501 hwnd.client_window.ToInt32(), xevent.ConfigureEvent.x,
4502 xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
4504 lock (hwnd.configure_lock) {
4505 Form form = Control.FromHandle (hwnd.client_window) as Form;
4506 if (form != null && !hwnd.resizing_or_moving) {
4507 if (hwnd.x != form.Bounds.X || hwnd.y != form.Bounds.Y) {
4508 SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_MOVE, IntPtr.Zero);
4509 hwnd.resizing_or_moving = true;
4510 } else if (hwnd.width != form.Bounds.Width || hwnd.height != form.Bounds.Height) {
4511 SendMessage (form.Handle, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_SIZE, IntPtr.Zero);
4512 hwnd.resizing_or_moving = true;
4514 if (hwnd.resizing_or_moving)
4515 SendMessage (form.Handle, Msg.WM_ENTERSIZEMOVE, IntPtr.Zero, IntPtr.Zero);
4518 SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
4519 hwnd.configure_pending = false;
4521 // We need to adjust our client window to track the resize of whole_window
4522 if (hwnd.whole_window != hwnd.client_window)
4523 PerformNCCalc(hwnd);
4526 goto ProcessNextMessage;
4529 case XEventName.FocusIn: {
4530 // We received focus. We use X11 focus only to know if the app window does or does not have focus
4531 // We do not track the actual focussed window via it. Instead, this is done via FocusWindow internally
4532 // Receiving focus means we've gotten activated and therefore we need to let the actual FocusWindow know
4533 // about it having focus again
4534 if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
4535 goto ProcessNextMessage;
4539 if (FocusWindow == IntPtr.Zero) {
4540 Control c = Control.FromHandle (hwnd.client_window);
4543 goto ProcessNextMessage;
4544 Form form = c.FindForm ();
4546 goto ProcessNextMessage;
4548 if (ActiveWindow != form.Handle) {
4549 ActiveWindow = form.Handle;
4550 SendMessage (ActiveWindow, Msg.WM_ACTIVATE, (IntPtr) WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
4552 goto ProcessNextMessage;
4554 Keyboard.FocusIn (FocusWindow);
4555 SendMessage(FocusWindow, Msg.WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero);
4556 goto ProcessNextMessage;
4559 case XEventName.FocusOut: {
4560 // Se the comment for our FocusIn handler
4561 if (xevent.FocusChangeEvent.detail != NotifyDetail.NotifyNonlinear) {
4562 goto ProcessNextMessage;
4565 while (Keyboard.ResetKeyState(FocusWindow, ref msg)) {
4566 SendMessage(FocusWindow, msg.message, msg.wParam, msg.lParam);
4569 Keyboard.FocusOut(hwnd.client_window);
4570 SendMessage(FocusWindow, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
4571 goto ProcessNextMessage;
4574 // We are already firing WM_SHOWWINDOW messages in the proper places, but I'm leaving this code
4575 // in case we break a scenario not taken into account in the tests
4576 case XEventName.MapNotify: {
4577 /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
4579 msg.message = Msg.WM_SHOWWINDOW;
4580 msg.wParam = (IntPtr) 1;
4581 // XXX we're missing the lParam..
4584 goto ProcessNextMessage;
4587 case XEventName.UnmapNotify: {
4588 /*if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
4589 hwnd.mapped = false;
4590 msg.message = Msg.WM_SHOWWINDOW;
4591 msg.wParam = (IntPtr) 0;
4592 // XXX we're missing the lParam..
4595 goto ProcessNextMessage;
4598 case XEventName.Expose: {
4601 hwnd.expose_pending = false;
4603 hwnd.nc_expose_pending = false;
4605 goto ProcessNextMessage;
4609 if (!hwnd.expose_pending) {
4610 goto ProcessNextMessage;
4613 if (!hwnd.nc_expose_pending) {
4614 goto ProcessNextMessage;
4617 switch (hwnd.border_style) {
4618 case FormBorderStyle.Fixed3D: {
4621 g = Graphics.FromHwnd(hwnd.whole_window);
4622 if (hwnd.border_static)
4623 ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.SunkenOuter);
4625 ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Border3DStyle.Sunken);
4630 case FormBorderStyle.FixedSingle: {
4633 g = Graphics.FromHwnd(hwnd.whole_window);
4634 ControlPaint.DrawBorder(g, new Rectangle(0, 0, hwnd.Width, hwnd.Height), Color.Black, ButtonBorderStyle.Solid);
4639 DriverDebug("GetMessage(): Window {0:X} Exposed non-client area {1},{2} {3}x{4}",
4640 hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y,
4641 xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4643 Rectangle rect = new Rectangle (xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4644 Region region = new Region (rect);
4645 IntPtr hrgn = region.GetHrgn (null); // Graphics object isn't needed
4646 msg.message = Msg.WM_NCPAINT;
4647 msg.wParam = hrgn == IntPtr.Zero ? (IntPtr)1 : hrgn;
4648 msg.refobject = region;
4651 DriverDebug("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}",
4652 hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y,
4653 xevent.ExposeEvent.width, xevent.ExposeEvent.height);
4654 if (Caret.Visible == true) {
4655 Caret.Paused = true;
4659 if (Caret.Visible == true) {
4661 Caret.Paused = false;
4663 msg.message = Msg.WM_PAINT;
4667 case XEventName.DestroyNotify: {
4669 // This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
4670 hwnd = Hwnd.ObjectFromHandle(xevent.DestroyWindowEvent.window);
4672 // We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
4673 if ((hwnd != null) && (hwnd.client_window == xevent.DestroyWindowEvent.window)) {
4674 CleanupCachedWindows (hwnd);
4676 DriverDebug("Received X11 Destroy Notification for {0}", XplatUI.Window(hwnd.client_window));
4678 msg.hwnd = hwnd.client_window;
4679 msg.message=Msg.WM_DESTROY;
4682 goto ProcessNextMessage;
4688 case XEventName.ClientMessage: {
4689 if (Dnd.HandleClientMessage (ref xevent)) {
4690 goto ProcessNextMessage;
4693 if (xevent.ClientMessageEvent.message_type == AsyncAtom) {
4694 XplatUIDriverSupport.ExecuteClientMessage((GCHandle)xevent.ClientMessageEvent.ptr1);
4695 goto ProcessNextMessage;
4698 if (xevent.ClientMessageEvent.message_type == HoverState.Atom) {
4699 msg.message = Msg.WM_MOUSEHOVER;
4700 msg.wParam = GetMousewParam(0);
4701 msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
4705 if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {
4706 DebugHelper.Indent ();
4707 DebugHelper.WriteLine (String.Format ("Posted message:" + (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 () + " for 0x{0:x}", xevent.ClientMessageEvent.ptr1.ToInt32 ()));
4708 DebugHelper.Unindent ();
4709 msg.hwnd = xevent.ClientMessageEvent.ptr1;
4710 msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
4711 msg.wParam = xevent.ClientMessageEvent.ptr3;
4712 msg.lParam = xevent.ClientMessageEvent.ptr4;
4713 if (msg.message == (Msg)Msg.WM_QUIT)
4719 if (xevent.ClientMessageEvent.message_type == _XEMBED) {
4720 #if DriverDebugXEmbed
4721 Console.WriteLine("GOT EMBED MESSAGE {0:X}, detail {1:X}", xevent.ClientMessageEvent.ptr2.ToInt32(), xevent.ClientMessageEvent.ptr3.ToInt32());
4724 if (xevent.ClientMessageEvent.ptr2.ToInt32() == (int)XEmbedMessage.EmbeddedNotify) {
4725 XSizeHints hints = new XSizeHints();
4728 XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
4730 hwnd.width = hints.max_width;
4731 hwnd.height = hints.max_height;
4732 hwnd.ClientRect = Rectangle.Empty;
4733 SendMessage(msg.hwnd, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
4737 if (xevent.ClientMessageEvent.message_type == WM_PROTOCOLS) {
4738 if (xevent.ClientMessageEvent.ptr1 == WM_DELETE_WINDOW) {
4739 SendMessage (msg.hwnd, Msg.WM_SYSCOMMAND, (IntPtr)SystemCommands.SC_CLOSE, IntPtr.Zero);
4740 msg.message = Msg.WM_CLOSE;
4744 // We should not get this, but I'll leave the code in case we need it in the future
4745 if (xevent.ClientMessageEvent.ptr1 == WM_TAKE_FOCUS) {
4746 goto ProcessNextMessage;
4749 goto ProcessNextMessage;
4753 goto ProcessNextMessage;
4760 HitTest NCHitTest (Hwnd hwnd, int x, int y)
4762 // The hit test is sent in screen coordinates
4764 int screen_x, screen_y;
4765 XTranslateCoordinates (DisplayHandle, hwnd.WholeWindow, RootWindow, x, y, out screen_x, out screen_y, out dummy);
4766 return (HitTest) NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero,
4767 (IntPtr) (screen_y << 16 | screen_x & 0xFFFF));
4770 // Our very basic implementation of MoveResize - we can extend it later
4772 internal override void BeginMoveResize (IntPtr handle)
4774 // We *need* to ungrab the pointer in the current display
4775 XplatUI.UngrabWindow (Grab.Hwnd);
4778 GetCursorPos (IntPtr.Zero, out x_root, out y_root);
4780 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
4781 SendNetWMMessage (hwnd.whole_window, _NET_WM_MOVERESIZE, (IntPtr) x_root, (IntPtr) y_root,
4782 (IntPtr) NetWmMoveResize._NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT,
4783 (IntPtr) 1); // left button
4786 internal override bool GetText(IntPtr handle, out string text)
4794 IntPtr prop = IntPtr.Zero;
4796 XGetWindowProperty(DisplayHandle, handle,
4797 _NET_WM_NAME, IntPtr.Zero, new IntPtr (1), false,
4798 UTF8_STRING, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
4800 if ((long)nitems > 0 && prop != IntPtr.Zero) {
4801 text = Marshal.PtrToStringUni (prop, (int)nitems);
4806 // fallback on the non-_NET property
4809 textptr = IntPtr.Zero;
4811 XFetchName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, ref textptr);
4812 if (textptr != IntPtr.Zero) {
4813 text = Marshal.PtrToStringAnsi(textptr);
4824 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)
4828 hwnd = Hwnd.ObjectFromHandle(handle);
4834 height = hwnd.height;
4836 PerformNCCalc(hwnd);
4838 client_width = hwnd.ClientRect.Width;
4839 client_height = hwnd.ClientRect.Height;
4844 // Should we throw an exception or fail silently?
4845 // throw new ArgumentException("Called with an invalid window handle", "handle");
4855 internal override FormWindowState GetWindowState(IntPtr handle)
4859 hwnd = Hwnd.ObjectFromHandle(handle);
4861 if (hwnd.cached_window_state == (FormWindowState)(-1))
4862 hwnd.cached_window_state = UpdateWindowState (handle);
4864 return hwnd.cached_window_state;
4867 FormWindowState UpdateWindowState (IntPtr handle) {
4872 IntPtr prop = IntPtr.Zero;
4876 XWindowAttributes attributes;
4879 hwnd = Hwnd.ObjectFromHandle(handle);
4883 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);
4884 if (((long)nitems > 0) && (prop != IntPtr.Zero)) {
4885 for (int i = 0; i < (long)nitems; i++) {
4886 atom = (IntPtr)Marshal.ReadInt32(prop, i * 4);
4887 if ((atom == _NET_WM_STATE_MAXIMIZED_HORZ) || (atom == _NET_WM_STATE_MAXIMIZED_VERT)) {
4889 } else if (atom == _NET_WM_STATE_HIDDEN) {
4897 return FormWindowState.Minimized;
4898 } else if (maximized == 2) {
4899 return FormWindowState.Maximized;
4902 attributes = new XWindowAttributes();
4903 XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
4904 if (attributes.map_state == MapState.IsUnmapped) {
4905 return (FormWindowState)(-1);
4909 return FormWindowState.Normal;
4912 internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea)
4915 GrabConfined = Grab.Confined;
4916 GrabArea = Grab.Area;
4919 internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle)
4922 IntPtr confine_to_window;
4924 confine_to_window = IntPtr.Zero;
4926 if (confine_to_handle != IntPtr.Zero) {
4927 XWindowAttributes attributes = new XWindowAttributes();
4929 hwnd = Hwnd.ObjectFromHandle(confine_to_handle);
4932 XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
4934 Grab.Area.X = attributes.x;
4935 Grab.Area.Y = attributes.y;
4936 Grab.Area.Width = attributes.width;
4937 Grab.Area.Height = attributes.height;
4938 Grab.Confined = true;
4939 confine_to_window = hwnd.client_window;
4944 hwnd = Hwnd.ObjectFromHandle(handle);
4947 XGrabPointer(DisplayHandle, hwnd.client_window, false,
4948 EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
4949 EventMask.ButtonReleaseMask | EventMask.PointerMotionMask |
4950 EventMask.PointerMotionHintMask | EventMask.LeaveWindowMask,
4951 GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, IntPtr.Zero, IntPtr.Zero);
4955 internal override void UngrabWindow(IntPtr hwnd)
4958 XUngrabPointer(DisplayHandle, IntPtr.Zero);
4959 XFlush(DisplayHandle);
4961 WindowUngrabbed (hwnd);
4964 void WindowUngrabbed (IntPtr hwnd) {
4965 bool was_grabbed = Grab.Hwnd != IntPtr.Zero;
4967 Grab.Hwnd = IntPtr.Zero;
4968 Grab.Confined = false;
4971 // lparam should be the handle to the window gaining the mouse capture,
4972 // but X doesn't seem to give us that information.
4973 // Also only generate WM_CAPTURECHANGED if the window actually was grabbed.
4974 // X will send a NotifyUngrab, but since it comes late sometimes we're
4975 // calling WindowUngrabbed directly from UngrabWindow in order to send
4976 // this WM right away.
4977 SendMessage (hwnd, Msg.WM_CAPTURECHANGED, IntPtr.Zero, IntPtr.Zero);
4981 internal override void HandleException(Exception e)
4983 StackTrace st = new StackTrace(e, true);
4984 Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
4985 Console.WriteLine("{0}{1}", e.Message, st.ToString());
4988 internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear)
4992 hwnd = Hwnd.ObjectFromHandle(handle);
4995 AddExpose (hwnd, true, hwnd.X, hwnd.Y, hwnd.Width, hwnd.Height);
4997 AddExpose (hwnd, true, rc.X, rc.Y, rc.Width, rc.Height);
5001 internal override void InvalidateNC (IntPtr handle)
5005 hwnd = Hwnd.ObjectFromHandle(handle);
5007 AddExpose (hwnd, hwnd.WholeWindow == hwnd.ClientWindow, 0, 0, hwnd.Width, hwnd.Height);
5010 internal override bool IsEnabled(IntPtr handle)
5012 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5013 return (hwnd != null && hwnd.Enabled);
5016 internal override bool IsVisible(IntPtr handle)
5018 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5019 return (hwnd != null && hwnd.visible);
5022 internal override void KillTimer(Timer timer)
5024 XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
5026 if (queue == null) {
5027 // This isn't really an error, MS doesn't start the timer if
5028 // it has no assosciated queue. In this case, remove the timer
5029 // from the list of unattached timers (if it was enabled).
5030 lock (unattached_timer_list) {
5031 if (unattached_timer_list.Contains (timer))
5032 unattached_timer_list.Remove (timer);
5036 queue.timer_list.Remove (timer);
5039 internal override void MenuToScreen(IntPtr handle, ref int x, ref int y)
5046 hwnd = Hwnd.ObjectFromHandle(handle);
5049 XTranslateCoordinates(DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
5056 internal override void OverrideCursor(IntPtr cursor)
5058 if (Grab.Hwnd != IntPtr.Zero) {
5059 XChangeActivePointerGrab (DisplayHandle,
5060 EventMask.ButtonMotionMask |
5061 EventMask.PointerMotionMask |
5062 EventMask.PointerMotionHintMask |
5063 EventMask.ButtonPressMask |
5064 EventMask.ButtonReleaseMask,
5065 cursor, IntPtr.Zero);
5069 OverrideCursorHandle = cursor;
5072 internal override PaintEventArgs PaintEventStart(ref Message msg, IntPtr handle, bool client)
5074 PaintEventArgs paint_event;
5079 // handle (and paint_hwnd) refers to the window that is should be painted.
5080 // msg.HWnd (and hwnd) refers to the window that got the paint message.
5083 hwnd = Hwnd.ObjectFromHandle(msg.HWnd);
5084 if (msg.HWnd == handle) {
5087 paint_hwnd = Hwnd.ObjectFromHandle (handle);
5090 if (Caret.Visible == true) {
5091 Caret.Paused = true;
5098 dc = Graphics.FromHwnd (paint_hwnd.client_window);
5100 Region clip_region = new Region ();
5101 clip_region.MakeEmpty();
5103 foreach (Rectangle r in hwnd.ClipRectangles) {
5104 /* Expand the region slightly.
5107 Rectangle r2 = Rectangle.FromLTRB (r.Left, r.Top, r.Right, r.Bottom + 1);
5108 clip_region.Union (r2);
5111 if (hwnd.UserClip != null) {
5112 clip_region.Intersect(hwnd.UserClip);
5115 dc.Clip = clip_region;
5116 paint_event = new PaintEventArgs(dc, hwnd.Invalid);
5117 hwnd.expose_pending = false;
5119 hwnd.ClearInvalidArea();
5121 hwnd.drawing_stack.Push (paint_event);
5122 hwnd.drawing_stack.Push (dc);
5126 dc = Graphics.FromHwnd (paint_hwnd.whole_window);
5128 if (!hwnd.nc_invalid.IsEmpty) {
5129 dc.SetClip (hwnd.nc_invalid);
5130 paint_event = new PaintEventArgs(dc, hwnd.nc_invalid);
5132 paint_event = new PaintEventArgs(dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
5134 hwnd.nc_expose_pending = false;
5136 hwnd.ClearNcInvalidArea ();
5138 hwnd.drawing_stack.Push (paint_event);
5139 hwnd.drawing_stack.Push (dc);
5145 internal override void PaintEventEnd(ref Message msg, IntPtr handle, bool client)
5149 hwnd = Hwnd.ObjectFromHandle (msg.HWnd);
5151 Graphics dc = (Graphics)hwnd.drawing_stack.Pop ();
5155 PaintEventArgs pe = (PaintEventArgs)hwnd.drawing_stack.Pop();
5156 pe.SetGraphics (null);
5159 if (Caret.Visible == true) {
5161 Caret.Paused = false;
5165 [MonoTODO("Implement filtering and PM_NOREMOVE")]
5166 internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags)
5168 XEventQueue queue = (XEventQueue) queue_id;
5171 if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
5172 throw new NotImplementedException("PeekMessage PM_NOREMOVE is not implemented yet"); // FIXME - Implement PM_NOREMOVE flag
5176 if (queue.Count > 0) {
5179 // Only call UpdateMessageQueue if real events are pending
5180 // otherwise we go to sleep on the socket
5181 if (XPending(DisplayHandle) != 0) {
5182 UpdateMessageQueue((XEventQueue)queue_id);
5184 } else if (((XEventQueue)queue_id).Paint.Count > 0) {
5189 CheckTimers(queue.timer_list, DateTime.UtcNow);
5194 return GetMessage(queue_id, ref msg, hWnd, wFilterMin, wFilterMax);
5197 internal override bool PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam)
5199 XEvent xevent = new XEvent ();
5200 Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5202 xevent.type = XEventName.ClientMessage;
5203 xevent.ClientMessageEvent.display = DisplayHandle;
5206 xevent.ClientMessageEvent.window = hwnd.whole_window;
5208 xevent.ClientMessageEvent.window = IntPtr.Zero;
5211 xevent.ClientMessageEvent.message_type = (IntPtr) PostAtom;
5212 xevent.ClientMessageEvent.format = 32;
5213 xevent.ClientMessageEvent.ptr1 = handle;
5214 xevent.ClientMessageEvent.ptr2 = (IntPtr) message;
5215 xevent.ClientMessageEvent.ptr3 = wparam;
5216 xevent.ClientMessageEvent.ptr4 = lparam;
5219 hwnd.Queue.EnqueueLocked (xevent);
5221 ThreadQueue(Thread.CurrentThread).EnqueueLocked (xevent);
5226 internal override void PostQuitMessage(int exitCode)
5228 ApplicationContext ctx = Application.MWFThread.Current.Context;
5229 Form f = ctx != null ? ctx.MainForm : null;
5231 PostMessage (Application.MWFThread.Current.Context.MainForm.window.Handle, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
5233 PostMessage (FosterParent, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
5234 XFlush(DisplayHandle);
5237 internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave)
5242 internal override void RequestNCRecalc(IntPtr handle)
5246 hwnd = Hwnd.ObjectFromHandle(handle);
5252 PerformNCCalc(hwnd);
5253 SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5254 InvalidateNC(handle);
5257 internal override void ResetMouseHover(IntPtr handle)
5261 hwnd = Hwnd.ObjectFromHandle(handle);
5266 HoverState.Timer.Enabled = true;
5267 HoverState.X = mouse_position.X;
5268 HoverState.Y = mouse_position.Y;
5269 HoverState.Window = handle;
5273 internal override void ScreenToClient(IntPtr handle, ref int x, ref int y)
5280 hwnd = Hwnd.ObjectFromHandle(handle);
5283 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.client_window, x, y, out dest_x_return, out dest_y_return, out child);
5290 internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y)
5297 hwnd = Hwnd.ObjectFromHandle(handle);
5300 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.whole_window, x, y, out dest_x_return, out dest_y_return, out child);
5303 Form form = Control.FromHandle (handle) as Form;
5304 if (form != null && form.window_manager != null) {
5305 dest_y_return -= form.window_manager.TitleBarHeight;
5312 bool GraphicsExposePredicate (IntPtr display, ref XEvent xevent, IntPtr arg)
5314 return (xevent.type == XEventName.GraphicsExpose || xevent.type == XEventName.NoExpose) &&
5315 arg == xevent.GraphicsExposeEvent.drawable;
5318 delegate bool EventPredicate (IntPtr display, ref XEvent xevent, IntPtr arg);
5320 void ProcessGraphicsExpose (Hwnd hwnd)
5322 XEvent xevent = new XEvent ();
5323 IntPtr handle = Hwnd.HandleFromObject (hwnd);
5324 EventPredicate predicate = GraphicsExposePredicate;
5327 XIfEvent (Display, ref xevent, predicate, handle);
5328 if (xevent.type != XEventName.GraphicsExpose)
5331 AddExpose (hwnd, xevent.ExposeEvent.window == hwnd.ClientWindow, xevent.GraphicsExposeEvent.x, xevent.GraphicsExposeEvent.y,
5332 xevent.GraphicsExposeEvent.width, xevent.GraphicsExposeEvent.height);
5334 if (xevent.GraphicsExposeEvent.count == 0)
5339 internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children)
5343 XGCValues gc_values;
5345 hwnd = Hwnd.ObjectFromHandle(handle);
5347 Rectangle r = Rectangle.Intersect (hwnd.Invalid, area);
5349 /* We have an invalid area in the window we're scrolling.
5350 Adjust our stored invalid rectangle to to match the scrolled amount */
5365 if (area.Contains (hwnd.Invalid))
5366 hwnd.ClearInvalidArea ();
5367 hwnd.AddInvalidArea(r);
5370 gc_values = new XGCValues();
5372 if (with_children) {
5373 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
5376 gc = XCreateGC(DisplayHandle, hwnd.client_window, IntPtr.Zero, ref gc_values);
5378 Rectangle visible_rect = GetTotalVisibleArea (hwnd.client_window);
5379 visible_rect.Intersect (area);
5381 Rectangle dest_rect = visible_rect;
5382 dest_rect.Y += YAmount;
5383 dest_rect.X += XAmount;
5384 dest_rect.Intersect (area);
5386 Point src = new Point (dest_rect.X - XAmount, dest_rect.Y - YAmount);
5387 XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src.X, src.Y,
5388 dest_rect.Width, dest_rect.Height, dest_rect.X, dest_rect.Y);
5390 Rectangle dirty_area = GetDirtyArea (area, dest_rect, XAmount, YAmount);
5391 AddExpose (hwnd, true, dirty_area.X, dirty_area.Y, dirty_area.Width, dirty_area.Height);
5393 ProcessGraphicsExpose (hwnd);
5395 XFreeGC(DisplayHandle, gc);
5398 internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children)
5403 hwnd = Hwnd.GetObjectFromWindow(handle);
5405 rect = hwnd.ClientRect;
5408 ScrollWindow(handle, rect, XAmount, YAmount, with_children);
5411 Rectangle GetDirtyArea (Rectangle total_area, Rectangle valid_area, int XAmount, int YAmount)
5413 Rectangle dirty_area = total_area;
5416 dirty_area.Height -= valid_area.Height;
5417 else if (YAmount < 0) {
5418 dirty_area.Height -= valid_area.Height;
5419 dirty_area.Y += valid_area.Height;
5423 dirty_area.Width -= valid_area.Width;
5424 else if (XAmount < 0) {
5425 dirty_area.Width -= valid_area.Width;
5426 dirty_area.X += valid_area.Width;
5432 Rectangle GetTotalVisibleArea (IntPtr handle)
5434 Control c = Control.FromHandle (handle);
5436 Rectangle visible_area = c.ClientRectangle;
5437 visible_area.Location = c.PointToScreen (Point.Empty);
5439 for (Control parent = c.Parent; parent != null; parent = parent.Parent) {
5440 if (!parent.IsHandleCreated || !parent.Visible)
5441 return visible_area; // Non visible, not need to finish computations
5443 Rectangle r = parent.ClientRectangle;
5444 r.Location = parent.PointToScreen (Point.Empty);
5446 visible_area.Intersect (r);
5449 visible_area.Location = c.PointToClient (visible_area.Location);
5450 return visible_area;
5453 internal override void SendAsyncMethod (AsyncMethodData method)
5456 XEvent xevent = new XEvent ();
5458 hwnd = Hwnd.ObjectFromHandle(method.Handle);
5460 xevent.type = XEventName.ClientMessage;
5461 xevent.ClientMessageEvent.display = DisplayHandle;
5462 xevent.ClientMessageEvent.window = method.Handle;
5463 xevent.ClientMessageEvent.message_type = (IntPtr)AsyncAtom;
5464 xevent.ClientMessageEvent.format = 32;
5465 xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
5467 hwnd.Queue.EnqueueLocked (xevent);
5472 delegate IntPtr WndProcDelegate (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam);
5474 internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam)
5477 h = Hwnd.ObjectFromHandle(hwnd);
5479 if (h != null && h.queue != ThreadQueue (Thread.CurrentThread)) {
5480 AsyncMethodResult result;
5481 AsyncMethodData data;
5483 result = new AsyncMethodResult ();
5484 data = new AsyncMethodData ();
5487 data.Method = new WndProcDelegate (NativeWindow.WndProc);
5488 data.Args = new object[] { hwnd, message, wParam, lParam };
5489 data.Result = result;
5491 SendAsyncMethod (data);
5492 DriverDebug("Sending {0} message across.", message);
5496 string key = hwnd + ":" + message;
5497 if (messageHold[key] != null)
5498 messageHold[key] = ((int)messageHold[key]) - 1;
5499 return NativeWindow.WndProc(hwnd, message, wParam, lParam);
5502 internal override int SendInput(IntPtr handle, Queue keys)
5504 if (handle == IntPtr.Zero)
5507 int count = keys.Count;
5508 Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5510 while (keys.Count > 0) {
5512 MSG msg = (MSG)keys.Dequeue();
5514 XEvent xevent = new XEvent ();
5516 xevent.type = (msg.message == Msg.WM_KEYUP ? XEventName.KeyRelease : XEventName.KeyPress);
5517 xevent.KeyEvent.display = DisplayHandle;
5520 xevent.KeyEvent.window = hwnd.whole_window;
5522 xevent.KeyEvent.window = IntPtr.Zero;
5525 xevent.KeyEvent.keycode = Keyboard.ToKeycode((int)msg.wParam);
5527 hwnd.Queue.EnqueueLocked (xevent);
5532 internal override void SetAllowDrop (IntPtr handle, bool value)
5534 // We allow drop on all windows
5537 internal override DragDropEffects StartDrag (IntPtr handle, object data,
5538 DragDropEffects allowed_effects)
5540 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5543 throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");
5545 return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
5548 internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style)
5550 Form form = Control.FromHandle (handle) as Form;
5551 if (form != null && form.window_manager == null) {
5552 CreateParams cp = form.GetCreateParams ();
5553 if (border_style == FormBorderStyle.FixedToolWindow ||
5554 border_style == FormBorderStyle.SizableToolWindow ||
5555 cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
5556 form.window_manager = new ToolWindowManager (form);
5560 RequestNCRecalc(handle);
5563 internal override void SetCaretPos(IntPtr handle, int x, int y)
5565 if (Caret.Hwnd == handle) {
5572 Keyboard.SetCaretPos (Caret, handle, x, y);
5574 if (Caret.Visible == true) {
5576 Caret.Timer.Start();
5581 internal override void SetClipRegion(IntPtr handle, Region region)
5585 hwnd = Hwnd.ObjectFromHandle(handle);
5590 hwnd.UserClip = region;
5593 internal override void SetCursor(IntPtr handle, IntPtr cursor)
5597 if (OverrideCursorHandle == IntPtr.Zero) {
5598 if ((LastCursorWindow == handle) && (LastCursorHandle == cursor)) {
5602 LastCursorHandle = cursor;
5603 LastCursorWindow = handle;
5605 hwnd = Hwnd.ObjectFromHandle(handle);
5607 if (cursor != IntPtr.Zero) {
5608 XDefineCursor(DisplayHandle, hwnd.whole_window, cursor);
5610 XUndefineCursor(DisplayHandle, hwnd.whole_window);
5612 XFlush(DisplayHandle);
5617 hwnd = Hwnd.ObjectFromHandle(handle);
5619 XDefineCursor(DisplayHandle, hwnd.whole_window, OverrideCursorHandle);
5623 void QueryPointer (IntPtr display, IntPtr w, out IntPtr root, out IntPtr child,
5624 out int root_x, out int root_y, out int child_x, out int child_y,
5627 /* this code was written with the help of
5628 glance at gdk. I never would have realized we
5629 needed a loop in order to traverse down in the
5630 hierarchy. I would have assumed you'd get the
5631 most deeply nested child and have to do
5632 XQueryTree to move back up the hierarchy..
5633 stupid me, of course. */
5636 XGrabServer (display);
5638 XQueryPointer(display, w, out root, out c,
5639 out root_x, out root_y, out child_x, out child_y,
5645 IntPtr child_last = IntPtr.Zero;
5646 while (c != IntPtr.Zero) {
5648 XQueryPointer(display, c, out root, out c,
5649 out root_x, out root_y, out child_x, out child_y,
5652 XUngrabServer (display);
5658 internal override void SetCursorPos(IntPtr handle, int x, int y)
5660 if (handle == IntPtr.Zero) {
5663 int root_x, root_y, child_x, child_y, mask;
5666 * QueryPointer before warping
5667 * because if the warp is on
5668 * the RootWindow, the x/y are
5669 * relative to the current
5672 QueryPointer (DisplayHandle, RootWindow,
5675 out root_x, out root_y,
5676 out child_x, out child_y,
5679 XWarpPointer(DisplayHandle, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x - root_x, y - root_y);
5681 XFlush (DisplayHandle);
5683 /* then we need to a
5684 * QueryPointer after warping
5685 * to manually generate a
5686 * motion event for the window
5689 QueryPointer (DisplayHandle, RootWindow,
5692 out root_x, out root_y,
5693 out child_x, out child_y,
5696 Hwnd child_hwnd = Hwnd.ObjectFromHandle(child);
5697 if (child_hwnd == null) {
5701 XEvent xevent = new XEvent ();
5703 xevent.type = XEventName.MotionNotify;
5704 xevent.MotionEvent.display = DisplayHandle;
5705 xevent.MotionEvent.window = child_hwnd.client_window;
5706 xevent.MotionEvent.root = RootWindow;
5707 xevent.MotionEvent.x = child_x;
5708 xevent.MotionEvent.y = child_y;
5709 xevent.MotionEvent.x_root = root_x;
5710 xevent.MotionEvent.y_root = root_y;
5711 xevent.MotionEvent.state = mask;
5713 child_hwnd.Queue.EnqueueLocked (xevent);
5718 hwnd = Hwnd.ObjectFromHandle(handle);
5720 XWarpPointer(DisplayHandle, IntPtr.Zero, hwnd.client_window, 0, 0, 0, 0, x, y);
5725 internal override void SetFocus(IntPtr handle)
5728 IntPtr prev_focus_window;
5730 hwnd = Hwnd.ObjectFromHandle(handle);
5732 if (hwnd.client_window == FocusWindow) {
5736 // Win32 doesn't do anything if disabled
5740 prev_focus_window = FocusWindow;
5741 FocusWindow = hwnd.client_window;
5743 if (prev_focus_window != IntPtr.Zero) {
5744 SendMessage(prev_focus_window, Msg.WM_KILLFOCUS, FocusWindow, IntPtr.Zero);
5746 Keyboard.FocusIn (FocusWindow);
5747 SendMessage(FocusWindow, Msg.WM_SETFOCUS, prev_focus_window, IntPtr.Zero);
5749 //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
5752 internal override void SetIcon(IntPtr handle, Icon icon)
5756 hwnd = Hwnd.ObjectFromHandle(handle);
5758 SetIcon(hwnd, icon);
5762 internal override void SetMenu(IntPtr handle, Menu menu)
5766 hwnd = Hwnd.ObjectFromHandle(handle);
5769 RequestNCRecalc(handle);
5772 internal override void SetModal(IntPtr handle, bool Modal)
5775 ModalWindows.Push(handle);
5777 if (ModalWindows.Contains(handle)) {
5780 if (ModalWindows.Count > 0) {
5781 Activate((IntPtr)ModalWindows.Peek());
5785 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
5786 Control ctrl = Control.FromHandle (handle);
5787 SetWMStyles (hwnd, ctrl.GetCreateParams ());
5790 internal override IntPtr SetParent(IntPtr handle, IntPtr parent)
5794 hwnd = Hwnd.ObjectFromHandle(handle);
5795 hwnd.parent = Hwnd.ObjectFromHandle(parent);
5798 DriverDebug("Parent for window {0} = {1}", XplatUI.Window(hwnd.Handle), XplatUI.Window(hwnd.parent != null ? hwnd.parent.Handle : IntPtr.Zero));
5799 XReparentWindow(DisplayHandle, hwnd.whole_window, hwnd.parent == null ? FosterParent : hwnd.parent.client_window, hwnd.x, hwnd.y);
5805 internal override void SetTimer (Timer timer)
5807 XEventQueue queue = (XEventQueue) MessageQueues [timer.thread];
5809 if (queue == null) {
5810 // This isn't really an error, MS doesn't start the timer if
5811 // it has no assosciated queue at this stage (it will be
5812 // enabled when a window is activated).
5813 unattached_timer_list.Add (timer);
5816 queue.timer_list.Add (timer);
5820 internal override bool SetTopmost(IntPtr handle, bool enabled)
5823 Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
5824 hwnd.topmost = enabled;
5829 SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_ADD, _NET_WM_STATE_ABOVE, IntPtr.Zero);
5831 int[] atoms = new int[8];
5832 atoms[0] = _NET_WM_STATE_ABOVE.ToInt32();
5833 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
5839 SendNetWMMessage(hwnd.WholeWindow, _NET_WM_STATE, (IntPtr) NetWmStateRequest._NET_WM_STATE_REMOVE, _NET_WM_STATE_ABOVE, IntPtr.Zero);
5841 XDeleteProperty(DisplayHandle, hwnd.whole_window, _NET_WM_STATE);
5847 internal override bool SetOwner(IntPtr handle, IntPtr handle_owner)
5852 hwnd = Hwnd.ObjectFromHandle(handle);
5854 if (handle_owner != IntPtr.Zero) {
5855 hwnd_owner = Hwnd.ObjectFromHandle(handle_owner);
5861 atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
5862 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
5864 if (hwnd_owner != null) {
5865 XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd_owner.whole_window);
5867 XSetTransientForHint(DisplayHandle, hwnd.whole_window, RootWindow);
5872 XDeleteProperty(DisplayHandle, hwnd.whole_window, (IntPtr)Atom.XA_WM_TRANSIENT_FOR);
5878 internal override bool SetVisible (IntPtr handle, bool visible, bool activate)
5882 hwnd = Hwnd.ObjectFromHandle(handle);
5883 hwnd.visible = visible;
5887 MapWindow(hwnd, WindowType.Both);
5889 if (Control.FromHandle(handle) is Form) {
5892 s = ((Form)Control.FromHandle(handle)).WindowState;
5895 case FormWindowState.Minimized: SetWindowState(handle, FormWindowState.Minimized); break;
5896 case FormWindowState.Maximized: SetWindowState(handle, FormWindowState.Maximized); break;
5900 SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
5903 UnmapWindow(hwnd, WindowType.Both);
5909 internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max)
5911 Control ctrl = Control.FromHandle (handle);
5912 SetWindowMinMax (handle, maximized, min, max, ctrl != null ? ctrl.GetCreateParams () : null);
5915 internal void SetWindowMinMax (IntPtr handle, Rectangle maximized, Size min, Size max, CreateParams cp)
5921 hwnd = Hwnd.ObjectFromHandle(handle);
5926 min.Width = Math.Max (min.Width, SystemInformation.MinimumWindowSize.Width);
5927 min.Height = Math.Max (min.Height, SystemInformation.MinimumWindowSize.Height);
5929 hints = new XSizeHints();
5931 XGetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints, out dummy);
5932 if ((min != Size.Empty) && (min.Width > 0) && (min.Height > 0)) {
5934 min = TranslateWindowSizeToXWindowSize (cp, min);
5935 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMinSize);
5936 hints.min_width = min.Width;
5937 hints.min_height = min.Height;
5940 if ((max != Size.Empty) && (max.Width > 0) && (max.Height > 0)) {
5942 max = TranslateWindowSizeToXWindowSize (cp, max);
5943 hints.flags = (IntPtr)((int)hints.flags | (int)XSizeHintsFlags.PMaxSize);
5944 hints.max_width = max.Width;
5945 hints.max_height = max.Height;
5948 if (hints.flags != IntPtr.Zero) {
5949 // The Metacity team has decided that they won't care about this when clicking the maximize icon,
5950 // they will maximize the window to fill the screen/parent no matter what.
5951 // http://bugzilla.ximian.com/show_bug.cgi?id=80021
5952 XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref hints);
5955 if ((maximized != Rectangle.Empty) && (maximized.Width > 0) && (maximized.Height > 0)) {
5957 maximized.Size = TranslateWindowSizeToXWindowSize (cp);
5958 hints.flags = (IntPtr)XSizeHintsFlags.PPosition;
5959 hints.x = maximized.X;
5960 hints.y = maximized.Y;
5961 hints.width = maximized.Width;
5962 hints.height = maximized.Height;
5964 // Metacity does not seem to follow this constraint for maximized (zoomed) windows
5965 XSetZoomHints(DisplayHandle, hwnd.whole_window, ref hints);
5970 internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height)
5974 hwnd = Hwnd.ObjectFromHandle(handle);
5980 // Win32 automatically changes negative width/height to 0.
5986 // X requires a sanity check for width & height; otherwise it dies
5987 if (hwnd.zero_sized && width > 0 && height > 0) {
5989 MapWindow(hwnd, WindowType.Whole);
5991 hwnd.zero_sized = false;
5994 if ((width < 1) || (height < 1)) {
5995 hwnd.zero_sized = true;
5996 UnmapWindow(hwnd, WindowType.Whole);
5999 // Save a server roundtrip (and prevent a feedback loop)
6000 if ((hwnd.x == x) && (hwnd.y == y) &&
6001 (hwnd.width == width) && (hwnd.height == height)) {
6005 if (!hwnd.zero_sized) {
6010 hwnd.height = height;
6011 SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
6013 if (hwnd.fixed_size) {
6014 SetWindowMinMax(handle, Rectangle.Empty, new Size(width, height), new Size(width, height));
6018 Control ctrl = Control.FromHandle (handle);
6019 Size TranslatedSize = TranslateWindowSizeToXWindowSize (ctrl.GetCreateParams (), new Size (width, height));
6020 MoveResizeWindow (DisplayHandle, hwnd.whole_window, x, y, TranslatedSize.Width, TranslatedSize.Height);
6021 PerformNCCalc(hwnd);
6025 // Update our position/size immediately, so
6026 // that future calls to SetWindowPos aren't
6027 // kept from calling XMoveResizeWindow (by the
6028 // "Save a server roundtrip" block above).
6032 hwnd.height = height;
6033 hwnd.ClientRect = Rectangle.Empty;
6036 internal override void SetWindowState(IntPtr handle, FormWindowState state)
6038 FormWindowState current_state;
6041 hwnd = Hwnd.ObjectFromHandle(handle);
6043 current_state = GetWindowState(handle);
6045 if (current_state == state) {
6050 case FormWindowState.Normal: {
6052 if (current_state == FormWindowState.Minimized) {
6053 MapWindow(hwnd, WindowType.Both);
6054 } else if (current_state == FormWindowState.Maximized) {
6055 SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
6062 case FormWindowState.Minimized: {
6064 if (current_state == FormWindowState.Maximized) {
6065 SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)2 /* toggle */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
6067 XIconifyWindow(DisplayHandle, hwnd.whole_window, ScreenNo);
6072 case FormWindowState.Maximized: {
6074 if (current_state == FormWindowState.Minimized) {
6075 MapWindow(hwnd, WindowType.Both);
6078 SendNetWMMessage(hwnd.whole_window, _NET_WM_STATE, (IntPtr)1 /* Add */, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT);
6086 internal override void SetWindowStyle(IntPtr handle, CreateParams cp)
6090 hwnd = Hwnd.ObjectFromHandle(handle);
6091 SetHwndStyles(hwnd, cp);
6092 SetWMStyles(hwnd, cp);
6095 internal override double GetWindowTransparency(IntPtr handle)
6100 internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key)
6105 hwnd = Hwnd.ObjectFromHandle(handle);
6111 hwnd.opacity = (uint)(0xffffffff * transparency);
6112 opacity = (IntPtr)((int)hwnd.opacity);
6114 IntPtr w = hwnd.whole_window;
6115 if (hwnd.reparented)
6116 w = XGetParent (hwnd.whole_window);
6117 XChangeProperty(DisplayHandle, w, _NET_WM_WINDOW_OPACITY, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, ref opacity, 1);
6120 internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool top, bool bottom)
6122 Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
6130 XRaiseWindow(DisplayHandle, hwnd.whole_window);
6133 } else if (!bottom) {
6134 Hwnd after_hwnd = null;
6136 if (after_handle != IntPtr.Zero) {
6137 after_hwnd = Hwnd.ObjectFromHandle(after_handle);
6140 XWindowChanges values = new XWindowChanges();
6142 if (after_hwnd == null) {
6143 // Work around metacity 'issues'
6147 atoms[0] = unixtime();
6148 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_USER_TIME, (IntPtr)Atom.XA_CARDINAL, 32, PropertyMode.Replace, atoms, 1);
6150 XRaiseWindow(DisplayHandle, hwnd.whole_window);
6151 SendNetWMMessage(hwnd.whole_window, _NET_ACTIVE_WINDOW, (IntPtr)1, IntPtr.Zero, IntPtr.Zero);
6153 //throw new ArgumentNullException("after_handle", "Need sibling to adjust z-order");
6156 values.sibling = after_hwnd.whole_window;
6157 values.stack_mode = StackMode.Below;
6160 XConfigureWindow(DisplayHandle, hwnd.whole_window, ChangeWindowFlags.CWStackMode | ChangeWindowFlags.CWSibling, ref values);
6165 XLowerWindow(DisplayHandle, hwnd.whole_window);
6172 internal override void ShowCursor(bool show)
6174 ; // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
6177 internal override object StartLoop(Thread thread)
6179 XEventQueue q = ThreadQueue(thread);
6183 internal override TransparencySupport SupportsTransparency()
6185 // We need to check if the x compositing manager is running
6186 return TransparencySupport.Set;
6189 internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt)
6191 GetSystrayManagerWindow();
6193 if (SystrayMgrWindow != IntPtr.Zero) {
6194 XSizeHints size_hints;
6197 hwnd = Hwnd.ObjectFromHandle(handle);
6198 DriverDebug("Adding Systray Whole:{0:X}, Client:{1:X}", hwnd.whole_window.ToInt32(), hwnd.client_window.ToInt32());
6201 if (hwnd.client_window != hwnd.whole_window) {
6202 Keyboard.DestroyICForWindow (hwnd.client_window);
6203 XDestroyWindow(DisplayHandle, hwnd.client_window);
6204 hwnd.client_window = hwnd.whole_window;
6207 /* by virtue of the way the tests are ordered when determining if it's PAINT
6208 or NCPAINT, client_window == whole_window will always be PAINT. So, if we're
6209 waiting on an nc_expose, drop it and remove the hwnd from the list (unless
6210 there's a pending expose). */
6211 if (hwnd.nc_expose_pending) {
6212 hwnd.nc_expose_pending = false;
6213 if (!hwnd.expose_pending)
6214 hwnd.Queue.Paint.Remove (hwnd);
6217 // We are going to be directly mapped by the system tray, so mark as mapped
6218 // so we can later properly unmap it.
6221 size_hints = new XSizeHints();
6223 size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
6225 size_hints.min_width = 24;
6226 size_hints.min_height = 24;
6227 size_hints.max_width = 24;
6228 size_hints.max_height = 24;
6229 size_hints.base_width = 24;
6230 size_hints.base_height = 24;
6232 XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints);
6234 int[] atoms = new int[2];
6235 atoms [0] = 1; // Version 1
6236 atoms [1] = 1; // we want to be mapped
6238 // This line cost me 3 days...
6239 XChangeProperty(DisplayHandle, hwnd.whole_window, _XEMBED_INFO, _XEMBED_INFO, 32, PropertyMode.Replace, atoms, 2);
6241 // Need to pick some reasonable defaults
6243 tt.AutomaticDelay = 350;
6244 tt.InitialDelay = 250;
6245 tt.ReshowDelay = 250;
6246 tt.ShowAlways = true;
6248 if ((tip != null) && (tip != string.Empty)) {
6249 tt.SetToolTip(Control.FromHandle(handle), tip);
6255 SendNetClientMessage(SystrayMgrWindow, _NET_SYSTEM_TRAY_OPCODE, IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
6263 internal override bool SystrayChange(IntPtr handle, string tip, Icon icon, ref ToolTip tt)
6267 control = Control.FromHandle(handle);
6268 if (control != null && tt != null) {
6269 tt.SetToolTip(control, tip);
6271 SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
6278 internal override void SystrayRemove(IntPtr handle, ref ToolTip tt)
6281 SetVisible (handle, false, false);
6283 // The caller can now re-dock it later...
6288 // Close any balloon window *we* fired.
6289 ThemeEngine.Current.HideBalloonWindow (handle);
6292 internal override void SystrayBalloon(IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
6294 ThemeEngine.Current.ShowBalloonWindow (handle, timeout, title, text, icon);
6295 SendMessage(handle, Msg.WM_USER, IntPtr.Zero, (IntPtr) Msg.NIN_BALLOONSHOW);
6298 internal override bool Text(IntPtr handle, string text)
6302 hwnd = Hwnd.ObjectFromHandle(handle);
6305 XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_NAME, UTF8_STRING, 8,
6306 PropertyMode.Replace, text, Encoding.UTF8.GetByteCount (text));
6308 // XXX this has problems with UTF8.
6309 // we need to either use the actual
6310 // text if it's latin-1, or convert it
6311 // to compound text if it's in a
6312 // different charset.
6313 XStoreName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, text);
6318 internal override bool TranslateMessage(ref MSG msg)
6320 return Keyboard.TranslateMessage (ref msg);
6323 internal override void UpdateWindow(IntPtr handle)
6327 hwnd = Hwnd.ObjectFromHandle(handle);
6329 if (!hwnd.visible || !hwnd.expose_pending || !hwnd.Mapped) {
6333 SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
6334 hwnd.Queue.Paint.Remove(hwnd);
6337 internal override void CreateOffscreenDrawable (IntPtr handle,
6338 int width, int height,
6339 out object offscreen_drawable)
6342 int x_out, y_out, width_out, height_out, border_width_out, depth_out;
6344 XGetGeometry (DisplayHandle, handle,
6346 out x_out, out y_out,
6347 out width_out, out height_out,
6348 out border_width_out, out depth_out);
6350 IntPtr pixmap = XCreatePixmap (DisplayHandle, handle, width, height, depth_out);
6352 offscreen_drawable = pixmap;
6356 internal override void DestroyOffscreenDrawable (object offscreen_drawable)
6358 XFreePixmap (DisplayHandle, (IntPtr)offscreen_drawable);
6361 internal override Graphics GetOffscreenGraphics (object offscreen_drawable)
6363 return Graphics.FromHwnd ((IntPtr) offscreen_drawable);
6366 internal override void BlitFromOffscreen (IntPtr dest_handle,
6368 object offscreen_drawable,
6369 Graphics offscreen_dc,
6372 XGCValues gc_values;
6375 gc_values = new XGCValues();
6377 gc = XCreateGC (DisplayHandle, dest_handle, IntPtr.Zero, ref gc_values);
6379 XCopyArea (DisplayHandle, (IntPtr)offscreen_drawable, dest_handle,
6380 gc, r.X, r.Y, r.Width, r.Height, r.X, r.Y);
6382 XFreeGC (DisplayHandle, gc);
6385 #endregion // Public Static Methods
6388 internal override event EventHandler Idle;
6389 #endregion // Events
6394 #region Xcursor imports
6395 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
6396 internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
6398 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
6399 internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
6401 [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
6402 internal extern static void XcursorImagesDestroy (IntPtr images);
6404 [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
6405 internal extern static int XcursorGetDefaultSize (IntPtr display);
6407 [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
6408 internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
6410 [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
6411 internal extern static IntPtr XcursorGetTheme (IntPtr display);
6414 [DllImport ("libX11", EntryPoint="XOpenDisplay")]
6415 internal extern static IntPtr XOpenDisplay(IntPtr display);
6416 [DllImport ("libX11", EntryPoint="XCloseDisplay")]
6417 internal extern static int XCloseDisplay(IntPtr display);
6418 [DllImport ("libX11", EntryPoint="XSynchronize")]
6419 internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
6421 [DllImport ("libX11", EntryPoint="XCreateWindow")]
6422 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);
6423 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)
6425 DebugHelper.TraceWriteLine ("XCreateWindow");
6426 return _XCreateWindow(display, parent, x, y, width, height,
6427 border_width, depth, xclass, visual, valuemask, ref attributes);
6429 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
6430 internal extern static IntPtr _XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
6431 internal static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background)
6433 DebugHelper.TraceWriteLine ("XCreateSimpleWindow");
6434 return _XCreateSimpleWindow(display, parent, x, y, width, height, border_width, border, background);
6436 [DllImport ("libX11", EntryPoint="XMapWindow")]
6437 internal extern static int _XMapWindow(IntPtr display, IntPtr window);
6438 internal static int XMapWindow(IntPtr display, IntPtr window)
6440 DebugHelper.TraceWriteLine ("XMapWindow");
6441 return _XMapWindow(display, window);
6443 [DllImport ("libX11", EntryPoint="XMapRaised")]
6444 internal extern static int _XMapRaised(IntPtr display, IntPtr window);
6445 internal static int XMapRaised(IntPtr display, IntPtr window)
6447 DebugHelper.TraceWriteLine ("XMapRaised");
6448 return _XMapRaised(display, window);
6450 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
6451 internal extern static int _XUnmapWindow(IntPtr display, IntPtr window);
6452 internal static int XUnmapWindow(IntPtr display, IntPtr window)
6454 DebugHelper.TraceWriteLine ("XUnmapWindow");
6455 return _XUnmapWindow(display, window);
6457 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
6458 internal extern static int _XMapSubindows(IntPtr display, IntPtr window);
6459 internal static int XMapSubindows(IntPtr display, IntPtr window)
6461 DebugHelper.TraceWriteLine ("XMapSubindows");
6462 return _XMapSubindows(display, window);
6464 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
6465 internal extern static int _XUnmapSubwindows(IntPtr display, IntPtr window);
6466 internal static int XUnmapSubwindows(IntPtr display, IntPtr window)
6468 DebugHelper.TraceWriteLine ("XUnmapSubwindows");
6469 return _XUnmapSubwindows(display, window);
6471 [DllImport ("libX11", EntryPoint="XRootWindow")]
6472 internal extern static IntPtr _XRootWindow(IntPtr display, int screen_number);
6473 internal static IntPtr XRootWindow(IntPtr display, int screen_number)
6475 DebugHelper.TraceWriteLine ("XRootWindow");
6476 return _XRootWindow(display, screen_number);
6478 [DllImport ("libX11", EntryPoint="XNextEvent")]
6479 internal extern static IntPtr _XNextEvent(IntPtr display, ref XEvent xevent);
6480 internal static IntPtr XNextEvent(IntPtr display, ref XEvent xevent)
6482 DebugHelper.TraceWriteLine ("XNextEvent");
6483 return _XNextEvent(display, ref xevent);
6485 [DllImport ("libX11", EntryPoint="XConnectionNumber")]
6486 internal extern static int _XConnectionNumber (IntPtr display);
6487 internal static int XConnectionNumber (IntPtr display)
6489 DebugHelper.TraceWriteLine ("XConnectionNumber");
6490 return _XConnectionNumber (display);
6492 [DllImport ("libX11", EntryPoint="XPending")]
6493 internal extern static int _XPending (IntPtr display);
6494 internal static int XPending (IntPtr display)
6496 DebugHelper.TraceWriteLine ("XPending");
6497 DebugHelper.DumpCallers (3);
6498 return _XPending (display);
6500 [DllImport ("libX11", EntryPoint="XSelectInput")]
6501 internal extern static IntPtr _XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
6502 internal static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask)
6504 DebugHelper.TraceWriteLine ("XSelectInput");
6505 return _XSelectInput(display, window, mask);
6508 [DllImport ("libX11", EntryPoint="XDestroyWindow")]
6509 internal extern static int _XDestroyWindow(IntPtr display, IntPtr window);
6510 internal static int XDestroyWindow(IntPtr display, IntPtr window)
6512 DebugHelper.TraceWriteLine ("XDestroyWindow 0x{0:x}", window.ToInt32());
6513 return _XDestroyWindow(display, window);
6516 [DllImport ("libX11", EntryPoint="XReparentWindow")]
6517 internal extern static int _XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
6518 internal static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y)
6520 DebugHelper.TraceWriteLine ("XReparentWindow");
6521 return _XReparentWindow(display, window, parent, x, y);
6524 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
6525 extern static int _XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
6526 static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height) {
6527 DebugHelper.TraceWriteLine ("XMoveResizeWindow");
6528 return _XMoveResizeWindow(display, window, x, y, width, height);
6531 internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
6533 int ret = XMoveResizeWindow (display, window, x, y, width, height);
6534 Keyboard.MoveCurrentCaretPos ();
6538 [DllImport ("libX11", EntryPoint="XResizeWindow")]
6539 internal extern static int _XResizeWindow(IntPtr display, IntPtr window, int width, int height);
6540 internal static int XResizeWindow(IntPtr display, IntPtr window, int width, int height)
6542 DebugHelper.TraceWriteLine ("XResizeWindow");
6543 return _XResizeWindow(display, window, width, height);
6546 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
6547 internal extern static int _XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
6548 internal static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes)
6550 DebugHelper.TraceWriteLine ("XGetWindowAttributes");
6551 return _XGetWindowAttributes(display, window, ref attributes);
6554 [DllImport ("libX11", EntryPoint="XFlush")]
6555 internal extern static int _XFlush(IntPtr display);
6556 internal static int XFlush(IntPtr display)
6558 DebugHelper.TraceWriteLine ("XFlush");
6559 return _XFlush(display);
6562 [DllImport ("libX11", EntryPoint="XSetWMName")]
6563 internal extern static int _XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
6564 internal static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop)
6566 DebugHelper.TraceWriteLine ("XSetWMName");
6567 return _XSetWMName(display, window, ref text_prop);
6570 [DllImport ("libX11", EntryPoint="XStoreName")]
6571 internal extern static int _XStoreName(IntPtr display, IntPtr window, string window_name);
6572 internal static int XStoreName(IntPtr display, IntPtr window, string window_name)
6574 DebugHelper.TraceWriteLine ("XStoreName");
6575 return _XStoreName(display, window, window_name);
6578 [DllImport ("libX11", EntryPoint="XFetchName")]
6579 internal extern static int _XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
6580 internal static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name)
6582 DebugHelper.TraceWriteLine ("XFetchName");
6583 return _XFetchName(display, window, ref window_name);
6586 [DllImport ("libX11", EntryPoint="XSendEvent")]
6587 internal extern static int _XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
6588 internal static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event)
6590 DebugHelper.TraceWriteLine ("XSendEvent");
6591 return _XSendEvent(display, window, propagate, event_mask, ref send_event);
6594 [DllImport ("libX11", EntryPoint="XQueryTree")]
6595 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);
6596 internal static int XQueryTree(IntPtr display, IntPtr window, out IntPtr root_return, out IntPtr parent_return, out IntPtr children_return, out int nchildren_return)
6598 DebugHelper.TraceWriteLine ("XQueryTree");
6599 return _XQueryTree(display, window, out root_return, out parent_return, out children_return, out nchildren_return);
6602 [DllImport ("libX11", EntryPoint="XFree")]
6603 internal extern static int _XFree(IntPtr data);
6604 internal static int XFree(IntPtr data)
6606 DebugHelper.TraceWriteLine ("XFree");
6607 return _XFree(data);
6610 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
6611 internal extern static int _XRaiseWindow(IntPtr display, IntPtr window);
6612 internal static int XRaiseWindow(IntPtr display, IntPtr window)
6614 DebugHelper.TraceWriteLine ("XRaiseWindow");
6615 return _XRaiseWindow(display, window);
6618 [DllImport ("libX11", EntryPoint="XLowerWindow")]
6619 internal extern static uint _XLowerWindow(IntPtr display, IntPtr window);
6620 internal static uint XLowerWindow(IntPtr display, IntPtr window)
6622 DebugHelper.TraceWriteLine ("XLowerWindow");
6623 return _XLowerWindow(display, window);
6626 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
6627 internal extern static uint _XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
6628 internal static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values)
6630 DebugHelper.TraceWriteLine ("XConfigureWindow");
6631 return _XConfigureWindow(display, window, value_mask, ref values);
6634 [DllImport ("libX11", EntryPoint="XInternAtom")]
6635 internal extern static IntPtr _XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
6636 internal static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists)
6638 DebugHelper.TraceWriteLine ("XInternAtom");
6639 return _XInternAtom(display, atom_name, only_if_exists);
6642 [DllImport ("libX11", EntryPoint="XInternAtoms")]
6643 internal extern static int _XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
6644 internal static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms)
6646 DebugHelper.TraceWriteLine ("XInternAtoms");
6647 return _XInternAtoms(display, atom_names, atom_count, only_if_exists, atoms);
6650 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
6651 internal extern static int _XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
6652 internal static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count)
6654 DebugHelper.TraceWriteLine ("XSetWMProtocols");
6655 return _XSetWMProtocols(display, window, protocols, count);
6658 [DllImport ("libX11", EntryPoint="XGrabPointer")]
6659 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);
6660 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)
6662 DebugHelper.TraceWriteLine ("XGrabPointer");
6663 return _XGrabPointer(display, window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, timestamp);
6666 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
6667 internal extern static int _XUngrabPointer(IntPtr display, IntPtr timestamp);
6668 internal static int XUngrabPointer(IntPtr display, IntPtr timestamp)
6670 DebugHelper.TraceWriteLine ("XUngrabPointer");
6671 return _XUngrabPointer(display, timestamp);
6674 [DllImport ("libX11", EntryPoint="XQueryPointer")]
6675 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);
6676 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)
6678 DebugHelper.TraceWriteLine ("XQueryPointer");
6679 return _XQueryPointer(display, window, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
6682 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
6683 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);
6684 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)
6686 DebugHelper.TraceWriteLine ("XTranslateCoordinates");
6687 return _XTranslateCoordinates (display, src_w, dest_w, src_x, src_y, out intdest_x_return, out dest_y_return, out child_return);
6690 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6691 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);
6692 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)
6694 DebugHelper.TraceWriteLine ("XGetGeometry");
6695 return _XGetGeometry(display, window, out root, out x, out y, out width, out height, out border_width, out depth);
6698 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6699 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);
6700 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)
6702 DebugHelper.TraceWriteLine ("XGetGeometry");
6703 return _XGetGeometry(display, window, root, out x, out y, out width, out height, border_width, depth);
6706 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6707 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);
6708 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)
6710 DebugHelper.TraceWriteLine ("XGetGeometry");
6711 return _XGetGeometry(display, window, root, out x, out y, width, height, border_width, depth);
6714 [DllImport ("libX11", EntryPoint="XGetGeometry")]
6715 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);
6716 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)
6718 DebugHelper.TraceWriteLine ("XGetGeometry");
6719 return _XGetGeometry(display, window, root, x, y, out width, out height, border_width, depth);
6722 [DllImport ("libX11", EntryPoint="XWarpPointer")]
6723 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);
6724 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)
6726 DebugHelper.TraceWriteLine ("XWarpPointer");
6727 return _XWarpPointer(display, src_w, dest_w, src_x, src_y, src_width, src_height, dest_x, dest_y);
6730 [DllImport ("libX11", EntryPoint="XClearWindow")]
6731 internal extern static int _XClearWindow(IntPtr display, IntPtr window);
6732 internal static int XClearWindow(IntPtr display, IntPtr window)
6734 DebugHelper.TraceWriteLine ("XClearWindow");
6735 return _XClearWindow(display, window);
6738 [DllImport ("libX11", EntryPoint="XClearArea")]
6739 internal extern static int _XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
6740 internal static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures)
6742 DebugHelper.TraceWriteLine ("XClearArea");
6743 return _XClearArea(display, window, x, y, width, height, exposures);
6747 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
6748 internal extern static IntPtr _XDefaultScreenOfDisplay(IntPtr display);
6749 internal static IntPtr XDefaultScreenOfDisplay(IntPtr display)
6751 DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6752 return _XDefaultScreenOfDisplay(display);
6755 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
6756 internal extern static int _XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
6757 internal static int XDefaultScreenOfDisplay(IntPtr display, IntPtr Screen)
6759 DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6760 return _XScreenNumberOfScreen(display, Screen);
6763 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
6764 internal extern static IntPtr _XDefaultVisual(IntPtr display, int screen_number);
6765 internal static IntPtr XDefaultScreenOfDisplay(IntPtr display, int screen_number)
6767 DebugHelper.TraceWriteLine ("XDefaultScreenOfDisplay");
6768 return _XDefaultVisual(display, screen_number);
6771 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
6772 internal extern static uint _XDefaultDepth(IntPtr display, int screen_number);
6773 internal static uint XDefaultDepth(IntPtr display, int screen_number)
6775 DebugHelper.TraceWriteLine ("XDefaultDepth");
6776 return _XDefaultDepth(display, screen_number);
6779 [DllImport ("libX11", EntryPoint="XDefaultScreen")]
6780 internal extern static int _XDefaultScreen(IntPtr display);
6781 internal static int XDefaultScreen(IntPtr display)
6783 DebugHelper.TraceWriteLine ("XDefaultScreen");
6784 return _XDefaultScreen(display);
6787 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
6788 internal extern static IntPtr _XDefaultColormap(IntPtr display, int screen_number);
6789 internal static IntPtr XDefaultColormap(IntPtr display, int screen_number)
6791 DebugHelper.TraceWriteLine ("XDefaultColormap");
6792 return _XDefaultColormap(display, screen_number);
6795 [DllImport ("libX11", EntryPoint="XLookupColor")]
6796 internal extern static int _XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
6797 internal static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color)
6799 DebugHelper.TraceWriteLine ("XLookupColor");
6800 return _XLookupColor(display, Colormap, Coloranem, ref exact_def_color, ref screen_def_color);
6803 [DllImport ("libX11", EntryPoint="XAllocColor")]
6804 internal extern static int _XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
6805 internal static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def)
6807 DebugHelper.TraceWriteLine ("XAllocColor");
6808 return _XAllocColor(display, Colormap, ref colorcell_def);
6811 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
6812 internal extern static int _XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
6813 internal static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window)
6815 DebugHelper.TraceWriteLine ("XSetTransientForHint");
6816 return _XSetTransientForHint(display, window, prop_window);
6819 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6820 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
6821 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements)
6823 DebugHelper.TraceWriteLine ("XChangeProperty");
6824 return _XChangeProperty(display, window, property, type, format, mode, ref data, nelements);
6827 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6828 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
6829 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements)
6831 DebugHelper.TraceWriteLine ("XChangeProperty");
6832 return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
6835 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6836 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
6837 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements)
6839 DebugHelper.TraceWriteLine ("XChangeProperty");
6840 return _XChangeProperty(display, window, property, type, format, mode, ref value, nelements);
6843 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6844 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
6845 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements)
6847 DebugHelper.TraceWriteLine ("XChangeProperty");
6848 return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6851 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6852 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
6853 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements)
6855 DebugHelper.TraceWriteLine ("XChangeProperty");
6856 return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6859 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6860 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
6861 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements)
6863 DebugHelper.TraceWriteLine ("XChangeProperty");
6864 return _XChangeProperty(display, window, property, type, format, mode, data, nelements);
6867 [DllImport ("libX11", EntryPoint="XChangeProperty")]
6868 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
6869 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements)
6871 DebugHelper.TraceWriteLine ("XChangeProperty");
6872 return _XChangeProperty(display, window, property, type, format, mode, atoms, nelements);
6875 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
6876 internal extern static int _XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
6877 internal static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length)
6879 DebugHelper.TraceWriteLine ("XChangeProperty");
6880 return _XChangeProperty(display, window, property, type, format, mode, text, text_length);
6883 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
6884 internal extern static int _XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
6885 internal static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property)
6887 DebugHelper.TraceWriteLine ("XDeleteProperty");
6888 return _XDeleteProperty(display, window, property);
6892 [DllImport ("libX11", EntryPoint="XCreateGC")]
6893 internal extern static IntPtr _XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
6894 internal static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values)
6896 DebugHelper.TraceWriteLine ("XCreateGC");
6897 return _XCreateGC(display, window, valuemask, ref values);
6900 [DllImport ("libX11", EntryPoint="XFreeGC")]
6901 internal extern static int _XFreeGC(IntPtr display, IntPtr gc);
6902 internal static int XFreeGC(IntPtr display, IntPtr gc)
6904 DebugHelper.TraceWriteLine ("XFreeGC");
6905 return _XFreeGC(display, gc);
6908 [DllImport ("libX11", EntryPoint="XSetFunction")]
6909 internal extern static int _XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
6910 internal static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function)
6912 DebugHelper.TraceWriteLine ("XSetFunction");
6913 return _XSetFunction(display, gc, function);
6916 [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
6917 internal extern static int _XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
6918 internal static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style)
6920 DebugHelper.TraceWriteLine ("XSetLineAttributes");
6921 return _XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style);
6924 [DllImport ("libX11", EntryPoint="XDrawLine")]
6925 internal extern static int _XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
6926 internal static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2)
6928 DebugHelper.TraceWriteLine ("XDrawLine");
6929 return _XDrawLine(display, drawable, gc, x1, y1, x2, y2);
6932 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
6933 internal extern static int _XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
6934 internal static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height)
6936 DebugHelper.TraceWriteLine ("XDrawRectangle");
6937 return _XDrawRectangle(display, drawable, gc, x1, y1, width, height);
6940 [DllImport ("libX11", EntryPoint="XFillRectangle")]
6941 internal extern static int _XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
6942 internal static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height)
6944 DebugHelper.TraceWriteLine ("XFillRectangle");
6945 return _XFillRectangle(display, drawable, gc, x1, y1, width, height);
6948 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
6949 internal extern static int _XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
6950 internal static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background)
6952 DebugHelper.TraceWriteLine ("XSetWindowBackground");
6953 return _XSetWindowBackground(display, window, background);
6956 [DllImport ("libX11", EntryPoint="XCopyArea")]
6957 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);
6958 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)
6960 DebugHelper.TraceWriteLine ("XCopyArea");
6961 return _XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y);
6964 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
6965 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);
6966 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)
6968 DebugHelper.TraceWriteLine ("XGetWindowProperty");
6969 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);
6972 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
6973 internal extern static int _XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
6974 internal static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time)
6976 DebugHelper.TraceWriteLine ("XSetInputFocus");
6977 return _XSetInputFocus(display, window, revert_to, time);
6980 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
6981 internal extern static int _XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
6982 internal static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number)
6984 DebugHelper.TraceWriteLine ("XIconifyWindow");
6985 return _XIconifyWindow(display, window, screen_number);
6988 [DllImport ("libX11", EntryPoint="XDefineCursor")]
6989 internal extern static int _XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
6990 internal static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor)
6992 DebugHelper.TraceWriteLine ("XDefineCursor");
6993 return _XDefineCursor(display, window, cursor);
6996 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
6997 internal extern static int _XUndefineCursor(IntPtr display, IntPtr window);
6998 internal static int XUndefineCursor(IntPtr display, IntPtr window)
7000 DebugHelper.TraceWriteLine ("XUndefineCursor");
7001 return _XUndefineCursor(display, window);
7004 [DllImport ("libX11", EntryPoint="XFreeCursor")]
7005 internal extern static int _XFreeCursor(IntPtr display, IntPtr cursor);
7006 internal static int XFreeCursor(IntPtr display, IntPtr cursor)
7008 DebugHelper.TraceWriteLine ("XFreeCursor");
7009 return _XFreeCursor(display, cursor);
7012 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
7013 internal extern static IntPtr _XCreateFontCursor(IntPtr display, CursorFontShape shape);
7014 internal static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape)
7016 DebugHelper.TraceWriteLine ("XCreateFontCursor");
7017 return _XCreateFontCursor(display, shape);
7020 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
7021 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);
7022 internal static IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask, ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot)
7024 DebugHelper.TraceWriteLine ("XCreatePixmapCursor");
7025 return _XCreatePixmapCursor(display, source, mask, ref foreground_color, ref background_color, x_hot, y_hot);
7028 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
7029 internal extern static IntPtr _XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
7030 internal static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth)
7032 DebugHelper.TraceWriteLine ("XCreatePixmapFromBitmapData");
7033 return _XCreatePixmapFromBitmapData(display, drawable, data, width, height, fg, bg, depth);
7036 [DllImport ("libX11", EntryPoint="XCreatePixmap")]
7037 internal extern static IntPtr _XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
7038 internal static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth)
7040 DebugHelper.TraceWriteLine ("XCreatePixmap");
7041 return _XCreatePixmap(display, d, width, height, depth);
7044 [DllImport ("libX11", EntryPoint="XFreePixmap")]
7045 internal extern static IntPtr _XFreePixmap(IntPtr display, IntPtr pixmap);
7046 internal static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap)
7048 DebugHelper.TraceWriteLine ("XFreePixmap");
7049 return _XFreePixmap(display, pixmap);
7052 [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
7053 internal extern static int _XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
7054 internal static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height)
7056 DebugHelper.TraceWriteLine ("XQueryBestCursor");
7057 return _XQueryBestCursor(display, drawable, width, height, out best_width, out best_height);
7060 [DllImport ("libX11", EntryPoint="XQueryExtension")]
7061 internal extern static int _XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
7062 internal static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error)
7064 DebugHelper.TraceWriteLine ("XQueryExtension");
7065 return _XQueryExtension(display, extension_name, ref major, ref first_event, ref first_error);
7068 [DllImport ("libX11", EntryPoint="XWhitePixel")]
7069 internal extern static IntPtr _XWhitePixel(IntPtr display, int screen_no);
7070 internal static IntPtr XWhitePixel(IntPtr display, int screen_no)
7072 DebugHelper.TraceWriteLine ("XWhitePixel");
7073 return _XWhitePixel(display, screen_no);
7076 [DllImport ("libX11", EntryPoint="XBlackPixel")]
7077 internal extern static IntPtr _XBlackPixel(IntPtr display, int screen_no);
7078 internal static IntPtr XBlackPixel(IntPtr display, int screen_no)
7080 DebugHelper.TraceWriteLine ("XBlackPixel");
7081 return _XBlackPixel(display, screen_no);
7084 [DllImport ("libX11", EntryPoint="XGrabServer")]
7085 internal extern static void _XGrabServer(IntPtr display);
7086 internal static void XGrabServer(IntPtr display)
7088 DebugHelper.TraceWriteLine ("XGrabServer");
7089 _XGrabServer(display);
7092 [DllImport ("libX11", EntryPoint="XUngrabServer")]
7093 internal extern static void _XUngrabServer(IntPtr display);
7094 internal static void XUngrabServer(IntPtr display)
7096 DebugHelper.TraceWriteLine ("XUngrabServer");
7097 _XUngrabServer(display);
7100 [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
7101 internal extern static void _XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
7102 internal static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return)
7104 DebugHelper.TraceWriteLine ("XGetWMNormalHints");
7105 _XGetWMNormalHints(display, window, ref hints, out supplied_return);
7108 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
7109 internal extern static void _XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7110 internal static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints)
7112 DebugHelper.TraceWriteLine ("XSetWMNormalHints");
7113 _XSetWMNormalHints(display, window, ref hints);
7116 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
7117 internal extern static void _XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7118 internal static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints)
7120 DebugHelper.TraceWriteLine ("XSetZoomHints");
7121 _XSetZoomHints(display, window, ref hints);
7124 [DllImport ("libX11", EntryPoint="XSetWMHints")]
7125 internal extern static void _XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
7126 internal static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints)
7128 DebugHelper.TraceWriteLine ("XSetWMHints");
7129 _XSetWMHints(display, window, ref wmhints);
7132 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
7133 internal extern static int _XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
7134 internal static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count)
7136 DebugHelper.TraceWriteLine ("XGetIconSizes");
7137 return _XGetIconSizes(display, window, out size_list, out count);
7140 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
7141 internal extern static IntPtr _XSetErrorHandler(XErrorHandler error_handler);
7142 internal static IntPtr XSetErrorHandler(XErrorHandler error_handler)
7144 DebugHelper.TraceWriteLine ("XSetErrorHandler");
7145 return _XSetErrorHandler(error_handler);
7148 [DllImport ("libX11", EntryPoint="XGetErrorText")]
7149 internal extern static IntPtr _XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
7150 internal static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length)
7152 DebugHelper.TraceWriteLine ("XGetErrorText");
7153 return _XGetErrorText(display, code, buffer, length);
7156 [DllImport ("libX11", EntryPoint="XInitThreads")]
7157 internal extern static int _XInitThreads();
7158 internal static int XInitThreads()
7160 DebugHelper.TraceWriteLine ("XInitThreads");
7161 return _XInitThreads();
7164 [DllImport ("libX11", EntryPoint="XConvertSelection")]
7165 internal extern static int _XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
7166 internal static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time)
7168 DebugHelper.TraceWriteLine ("XConvertSelection");
7169 return _XConvertSelection(display, selection, target, property, requestor, time);
7172 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
7173 internal extern static IntPtr _XGetSelectionOwner(IntPtr display, IntPtr selection);
7174 internal static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection)
7176 DebugHelper.TraceWriteLine ("XGetSelectionOwner");
7177 return _XGetSelectionOwner(display, selection);
7180 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
7181 internal extern static int _XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
7182 internal static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time)
7184 DebugHelper.TraceWriteLine ("XSetSelectionOwner");
7185 return _XSetSelectionOwner(display, selection, owner, time);
7188 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
7189 internal extern static int _XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
7190 internal static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask)
7192 DebugHelper.TraceWriteLine ("XSetPlaneMask");
7193 return _XSetPlaneMask(display, gc, mask);
7196 [DllImport ("libX11", EntryPoint="XSetForeground")]
7197 internal extern static int _XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
7198 internal static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground)
7200 DebugHelper.TraceWriteLine ("XSetForeground");
7201 return _XSetForeground(display, gc, foreground);
7204 [DllImport ("libX11", EntryPoint="XSetBackground")]
7205 internal extern static int _XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
7206 internal static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background)
7208 DebugHelper.TraceWriteLine ("XSetBackground");
7209 return _XSetBackground(display, gc, background);
7212 [DllImport ("libX11", EntryPoint="XBell")]
7213 internal extern static int _XBell(IntPtr display, int percent);
7214 internal static int XBell(IntPtr display, int percent)
7216 DebugHelper.TraceWriteLine ("XBell");
7217 return _XBell(display, percent);
7220 [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
7221 internal extern static int _XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
7222 internal static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time)
7224 DebugHelper.TraceWriteLine ("XChangeActivePointerGrab");
7225 return _XChangeActivePointerGrab (display, event_mask, cursor, time);
7228 [DllImport ("libX11", EntryPoint="XFilterEvent")]
7229 internal extern static bool _XFilterEvent(ref XEvent xevent, IntPtr window);
7230 internal static bool XFilterEvent(ref XEvent xevent, IntPtr window)
7232 DebugHelper.TraceWriteLine ("XFilterEvent");
7233 return _XFilterEvent(ref xevent, window);
7236 [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
7237 internal extern static void _XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
7238 internal static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported)
7240 DebugHelper.TraceWriteLine ("XkbSetDetectableAutoRepeat");
7241 _XkbSetDetectableAutoRepeat (display, detectable, supported);
7244 [DllImport ("libX11", EntryPoint="XPeekEvent")]
7245 internal extern static void _XPeekEvent (IntPtr display, ref XEvent xevent);
7246 internal static void XPeekEvent (IntPtr display, ref XEvent xevent)
7248 DebugHelper.TraceWriteLine ("XPeekEvent");
7249 _XPeekEvent (display, ref xevent);
7252 [DllImport ("libX11", EntryPoint="XIfEvent")]
7253 internal extern static void _XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
7254 internal static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg)
7256 DebugHelper.TraceWriteLine ("XIfEvent");
7257 _XIfEvent (display, ref xevent, event_predicate, arg);
7261 #region Xinerama imports
7262 [DllImport ("libXinerama", EntryPoint="XineramaQueryScreens")]
7263 extern static IntPtr _XineramaQueryScreens (IntPtr display, out int number);
7264 internal static IntPtr XineramaQueryScreens (IntPtr display, out int number)
7266 DebugHelper.TraceWriteLine ("XineramaQueryScreens");
7267 return _XineramaQueryScreens (display, out number);
7270 [DllImport ("libXinerama", EntryPoint="XineramaIsActive")]
7271 extern static bool _XineramaIsActive (IntPtr display);
7272 static bool XineramaNotInstalled;
7274 internal static bool XineramaIsActive (IntPtr display)
7276 DebugHelper.TraceWriteLine ("XineramaIsActive");
7278 if (XineramaNotInstalled)
7281 return _XineramaIsActive (display);
7282 } catch (DllNotFoundException) {
7283 // Xinerama isn't installed
7284 XineramaNotInstalled = true;
7290 #else //no TRACE defined
7292 #region Xcursor imports
7293 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadCursor")]
7294 internal extern static IntPtr XcursorLibraryLoadCursor (IntPtr display, [MarshalAs (UnmanagedType.LPStr)] string name);
7296 [DllImport ("libXcursor", EntryPoint = "XcursorLibraryLoadImages")]
7297 internal extern static IntPtr XcursorLibraryLoadImages ([MarshalAs (UnmanagedType.LPStr)] string file, IntPtr theme, int size);
7299 [DllImport ("libXcursor", EntryPoint = "XcursorImagesDestroy")]
7300 internal extern static void XcursorImagesDestroy (IntPtr images);
7302 [DllImport ("libXcursor", EntryPoint = "XcursorGetDefaultSize")]
7303 internal extern static int XcursorGetDefaultSize (IntPtr display);
7305 [DllImport ("libXcursor", EntryPoint = "XcursorImageLoadCursor")]
7306 internal extern static IntPtr XcursorImageLoadCursor (IntPtr display, IntPtr image);
7308 [DllImport ("libXcursor", EntryPoint = "XcursorGetTheme")]
7309 internal extern static IntPtr XcursorGetTheme (IntPtr display);
7312 [DllImport ("libX11", EntryPoint="XOpenDisplay")]
7313 internal extern static IntPtr XOpenDisplay(IntPtr display);
7314 [DllImport ("libX11", EntryPoint="XCloseDisplay")]
7315 internal extern static int XCloseDisplay(IntPtr display);
7316 [DllImport ("libX11", EntryPoint="XSynchronize")]
7317 internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
7319 [DllImport ("libX11", EntryPoint="XCreateWindow")]
7320 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);
7322 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
7323 internal extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, UIntPtr border, UIntPtr background);
7325 [DllImport ("libX11", EntryPoint="XMapWindow")]
7326 internal extern static int XMapWindow(IntPtr display, IntPtr window);
7328 [DllImport ("libX11", EntryPoint="XMapRaised")]
7329 internal extern static int XMapRaised(IntPtr display, IntPtr window);
7331 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
7332 internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
7334 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
7335 internal extern static int XMapSubindows(IntPtr display, IntPtr window);
7337 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
7338 internal extern static int XUnmapSubwindows(IntPtr display, IntPtr window);
7340 [DllImport ("libX11", EntryPoint="XRootWindow")]
7341 internal extern static IntPtr XRootWindow(IntPtr display, int screen_number);
7343 [DllImport ("libX11", EntryPoint="XNextEvent")]
7344 internal extern static IntPtr XNextEvent(IntPtr display, ref XEvent xevent);
7346 [DllImport ("libX11", EntryPoint="XConnectionNumber")]
7347 internal extern static int XConnectionNumber (IntPtr display);
7349 [DllImport ("libX11", EntryPoint="XPending")]
7350 internal extern static int XPending (IntPtr display);
7352 [DllImport ("libX11", EntryPoint="XSelectInput")]
7353 internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
7355 [DllImport ("libX11", EntryPoint="XDestroyWindow")]
7356 internal extern static int XDestroyWindow(IntPtr display, IntPtr window);
7358 [DllImport ("libX11", EntryPoint="XReparentWindow")]
7359 internal extern static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
7361 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
7362 extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
7363 internal static int MoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height)
7365 int ret = XMoveResizeWindow (display, window, x, y, width, height);
7366 Keyboard.MoveCurrentCaretPos ();
7370 [DllImport ("libX11", EntryPoint="XResizeWindow")]
7371 internal extern static int XResizeWindow(IntPtr display, IntPtr window, int width, int height);
7373 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
7374 internal extern static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
7376 [DllImport ("libX11", EntryPoint="XFlush")]
7377 internal extern static int XFlush(IntPtr display);
7379 [DllImport ("libX11", EntryPoint="XSetWMName")]
7380 internal extern static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
7382 [DllImport ("libX11", EntryPoint="XStoreName")]
7383 internal extern static int XStoreName(IntPtr display, IntPtr window, string window_name);
7385 [DllImport ("libX11", EntryPoint="XFetchName")]
7386 internal extern static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
7388 [DllImport ("libX11", EntryPoint="XSendEvent")]
7389 internal extern static int XSendEvent(IntPtr display, IntPtr window, bool propagate, IntPtr event_mask, ref XEvent send_event);
7391 [DllImport ("libX11", EntryPoint="XQueryTree")]
7392 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);
7394 [DllImport ("libX11", EntryPoint="XFree")]
7395 internal extern static int XFree(IntPtr data);
7397 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
7398 internal extern static int XRaiseWindow(IntPtr display, IntPtr window);
7400 [DllImport ("libX11", EntryPoint="XLowerWindow")]
7401 internal extern static uint XLowerWindow(IntPtr display, IntPtr window);
7403 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
7404 internal extern static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
7406 [DllImport ("libX11", EntryPoint="XInternAtom")]
7407 internal extern static IntPtr XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
7409 [DllImport ("libX11", EntryPoint="XInternAtoms")]
7410 internal extern static int XInternAtoms(IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
7412 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
7413 internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, IntPtr[] protocols, int count);
7415 [DllImport ("libX11", EntryPoint="XGrabPointer")]
7416 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);
7418 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
7419 internal extern static int XUngrabPointer(IntPtr display, IntPtr timestamp);
7421 [DllImport ("libX11", EntryPoint="XQueryPointer")]
7422 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);
7424 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
7425 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);
7427 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7428 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);
7430 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7431 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);
7433 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7434 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);
7436 [DllImport ("libX11", EntryPoint="XGetGeometry")]
7437 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);
7439 [DllImport ("libX11", EntryPoint="XWarpPointer")]
7440 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);
7442 [DllImport ("libX11", EntryPoint="XClearWindow")]
7443 internal extern static int XClearWindow(IntPtr display, IntPtr window);
7445 [DllImport ("libX11", EntryPoint="XClearArea")]
7446 internal extern static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
7449 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
7450 internal extern static IntPtr XDefaultScreenOfDisplay(IntPtr display);
7452 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
7453 internal extern static int XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
7455 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
7456 internal extern static IntPtr XDefaultVisual(IntPtr display, int screen_number);
7458 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
7459 internal extern static uint XDefaultDepth(IntPtr display, int screen_number);
7461 [DllImport ("libX11", EntryPoint="XDefaultScreen")]
7462 internal extern static int XDefaultScreen(IntPtr display);
7464 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
7465 internal extern static IntPtr XDefaultColormap(IntPtr display, int screen_number);
7467 [DllImport ("libX11", EntryPoint="XLookupColor")]
7468 internal extern static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
7470 [DllImport ("libX11", EntryPoint="XAllocColor")]
7471 internal extern static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
7473 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
7474 internal extern static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
7476 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7477 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
7479 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7480 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref uint value, int nelements);
7482 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7483 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, ref IntPtr value, int nelements);
7485 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7486 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, uint[] data, int nelements);
7488 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7489 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, int[] data, int nelements);
7491 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7492 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr[] data, int nelements);
7494 [DllImport ("libX11", EntryPoint="XChangeProperty")]
7495 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, IntPtr atoms, int nelements);
7497 [DllImport ("libX11", EntryPoint="XChangeProperty", CharSet=CharSet.Ansi)]
7498 internal extern static int XChangeProperty(IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, PropertyMode mode, string text, int text_length);
7500 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
7501 internal extern static int XDeleteProperty(IntPtr display, IntPtr window, IntPtr property);
7504 [DllImport ("libX11", EntryPoint="XCreateGC")]
7505 internal extern static IntPtr XCreateGC(IntPtr display, IntPtr window, IntPtr valuemask, ref XGCValues values);
7507 [DllImport ("libX11", EntryPoint="XFreeGC")]
7508 internal extern static int XFreeGC(IntPtr display, IntPtr gc);
7510 [DllImport ("libX11", EntryPoint="XSetFunction")]
7511 internal extern static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
7513 [DllImport ("libX11", EntryPoint="XSetLineAttributes")]
7514 internal extern static int XSetLineAttributes(IntPtr display, IntPtr gc, int line_width, GCLineStyle line_style, GCCapStyle cap_style, GCJoinStyle join_style);
7516 [DllImport ("libX11", EntryPoint="XDrawLine")]
7517 internal extern static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
7519 [DllImport ("libX11", EntryPoint="XDrawRectangle")]
7520 internal extern static int XDrawRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
7522 [DllImport ("libX11", EntryPoint="XFillRectangle")]
7523 internal extern static int XFillRectangle(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int width, int height);
7525 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
7526 internal extern static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
7528 [DllImport ("libX11", EntryPoint="XCopyArea")]
7529 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);
7531 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
7532 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);
7534 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
7535 internal extern static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
7537 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
7538 internal extern static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
7540 [DllImport ("libX11", EntryPoint="XDefineCursor")]
7541 internal extern static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
7543 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
7544 internal extern static int XUndefineCursor(IntPtr display, IntPtr window);
7546 [DllImport ("libX11", EntryPoint="XFreeCursor")]
7547 internal extern static int XFreeCursor(IntPtr display, IntPtr cursor);
7549 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
7550 internal extern static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape);
7552 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
7553 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);
7555 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
7556 internal extern static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
7558 [DllImport ("libX11", EntryPoint="XCreatePixmap")]
7559 internal extern static IntPtr XCreatePixmap(IntPtr display, IntPtr d, int width, int height, int depth);
7561 [DllImport ("libX11", EntryPoint="XFreePixmap")]
7562 internal extern static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap);
7564 [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
7565 internal extern static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
7567 [DllImport ("libX11", EntryPoint="XQueryExtension")]
7568 internal extern static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
7570 [DllImport ("libX11", EntryPoint="XWhitePixel")]
7571 internal extern static IntPtr XWhitePixel(IntPtr display, int screen_no);
7573 [DllImport ("libX11", EntryPoint="XBlackPixel")]
7574 internal extern static IntPtr XBlackPixel(IntPtr display, int screen_no);
7576 [DllImport ("libX11", EntryPoint="XGrabServer")]
7577 internal extern static void XGrabServer(IntPtr display);
7579 [DllImport ("libX11", EntryPoint="XUngrabServer")]
7580 internal extern static void XUngrabServer(IntPtr display);
7582 [DllImport ("libX11", EntryPoint="XGetWMNormalHints")]
7583 internal extern static void XGetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints, out IntPtr supplied_return);
7585 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
7586 internal extern static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7588 [DllImport ("libX11", EntryPoint="XSetZoomHints")]
7589 internal extern static void XSetZoomHints(IntPtr display, IntPtr window, ref XSizeHints hints);
7591 [DllImport ("libX11", EntryPoint="XSetWMHints")]
7592 internal extern static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
7594 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
7595 internal extern static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
7597 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
7598 internal extern static IntPtr XSetErrorHandler(XErrorHandler error_handler);
7600 [DllImport ("libX11", EntryPoint="XGetErrorText")]
7601 internal extern static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
7603 [DllImport ("libX11", EntryPoint="XInitThreads")]
7604 internal extern static int XInitThreads();
7606 [DllImport ("libX11", EntryPoint="XConvertSelection")]
7607 internal extern static int XConvertSelection(IntPtr display, IntPtr selection, IntPtr target, IntPtr property, IntPtr requestor, IntPtr time);
7609 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
7610 internal extern static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection);
7612 [DllImport ("libX11", EntryPoint="XSetSelectionOwner")]
7613 internal extern static int XSetSelectionOwner(IntPtr display, IntPtr selection, IntPtr owner, IntPtr time);
7615 [DllImport ("libX11", EntryPoint="XSetPlaneMask")]
7616 internal extern static int XSetPlaneMask(IntPtr display, IntPtr gc, IntPtr mask);
7618 [DllImport ("libX11", EntryPoint="XSetForeground")]
7619 internal extern static int XSetForeground(IntPtr display, IntPtr gc, UIntPtr foreground);
7621 [DllImport ("libX11", EntryPoint="XSetBackground")]
7622 internal extern static int XSetBackground(IntPtr display, IntPtr gc, UIntPtr background);
7624 [DllImport ("libX11", EntryPoint="XBell")]
7625 internal extern static int XBell(IntPtr display, int percent);
7627 [DllImport ("libX11", EntryPoint="XChangeActivePointerGrab")]
7628 internal extern static int XChangeActivePointerGrab (IntPtr display, EventMask event_mask, IntPtr cursor, IntPtr time);
7630 [DllImport ("libX11", EntryPoint="XFilterEvent")]
7631 internal extern static bool XFilterEvent(ref XEvent xevent, IntPtr window);
7633 [DllImport ("libX11", EntryPoint="XkbSetDetectableAutoRepeat")]
7634 internal extern static void XkbSetDetectableAutoRepeat (IntPtr display, bool detectable, IntPtr supported);
7636 [DllImport ("libX11", EntryPoint="XPeekEvent")]
7637 internal extern static void XPeekEvent (IntPtr display, ref XEvent xevent);
7639 [DllImport ("libX11", EntryPoint="XIfEvent")]
7640 internal extern static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event_predicate, IntPtr arg);
7642 [DllImport ("libX11", EntryPoint="XGetInputFocus")]
7643 internal extern static void XGetInputFocus (IntPtr display, out IntPtr focus, out IntPtr revert_to);
7645 #region Gtk/Gdk imports
7646 [DllImport("libgdk-x11-2.0")]
7647 internal extern static IntPtr gdk_atom_intern (string atomName, bool onlyIfExists);
7649 [DllImport("libgtk-x11-2.0")]
7650 internal extern static IntPtr gtk_clipboard_get (IntPtr atom);
7652 [DllImport("libgtk-x11-2.0")]
7653 internal extern static void gtk_clipboard_store (IntPtr clipboard);
7655 [DllImport("libgtk-x11-2.0")]
7656 internal extern static void gtk_clipboard_set_text (IntPtr clipboard, string text, int len);
7660 #region Xinerama imports
7661 [DllImport ("libXinerama")]
7662 internal extern static IntPtr XineramaQueryScreens (IntPtr display, out int number);
7664 [DllImport ("libXinerama", EntryPoint = "XineramaIsActive")]
7665 extern static bool _XineramaIsActive (IntPtr display);
7666 static bool XineramaNotInstalled;
7668 internal static bool XineramaIsActive (IntPtr display)
7670 if (XineramaNotInstalled)
7673 return _XineramaIsActive (display);
7674 } catch (DllNotFoundException) {
7675 // Xinerama isn't installed
7676 XineramaNotInstalled = true;