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-2005 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
46 using System.ComponentModel;
47 using System.Collections;
48 using System.Diagnostics;
50 using System.Drawing.Imaging;
53 using System.Net.Sockets;
54 using System.Reflection;
55 using System.Runtime.InteropServices;
57 using System.Threading;
59 // Only do the poll when building with mono for now
65 namespace System.Windows.Forms {
66 internal class XplatUIX11 : XplatUIDriver {
67 #region Local Variables
69 private static XplatUIX11 Instance;
70 private static int RefCount;
71 private static object XlibLock; // Our locking object
72 private static bool ThemesEnabled;
75 private static IntPtr DisplayHandle; // X11 handle to display
76 private static int ScreenNo; // Screen number used
77 private static IntPtr DefaultColormap; // Colormap for screen
78 private static IntPtr RootWindow; // Handle of the root window for the screen/display
79 private static IntPtr FosterParent; // Container to hold child windows until their parent exists
80 private static XErrorHandler ErrorHandler; // Error handler delegate
81 private static bool ErrorExceptions; // Throw exceptions on X errors
84 private static int PostAtom; // PostMessage atom
85 private static int AsyncAtom; // Support for async messages
88 private static bool GetMessageResult; // Value returned by GetMessage()
89 private static XEventQueue MessageQueue; // Holds our queued up events
91 private static Pollfd[] pollfds; // For watching the X11 socket
93 private static X11Keyboard Keyboard; //
94 private static Socket listen; //
95 private static Socket wake; //
99 private static IntPtr ActiveWindow; // Handle of the active window
100 private static IntPtr FocusWindow; // Handle of the window with keyboard focus (if any)
103 private static Stack ModalWindows; // Stack of our modal windows
106 private static IntPtr SystrayMgrWindow; // Handle of the Systray Manager window
109 private static IntPtr LastCursorWindow; // The last window we set the cursor on
110 private static IntPtr LastCursorHandle; // The handle that was last set on LastCursorWindow
111 private static IntPtr OverrideCursorHandle; // The cursor that is set to override any other cursors
114 private static CaretStruct Caret; //
116 // Support for Window Styles
117 private static int[] NetAtoms; // All atoms we know
119 // mouse hover message generation
120 private static HoverStruct HoverState; //
122 // double click message generation
123 private static ClickStruct ClickPending; //
125 // Support for mouse grab
126 private static GrabStruct Grab; //
129 private static Point MousePosition; // Last position of mouse, in screen coords
130 private static MouseButtons MouseState; // Last state of mouse buttons
133 private static ArrayList TimerList; // Holds SWF.Timers
136 private static int DoubleClickInterval; // msec; max interval between clicks to count as double click
138 private static readonly EventMask SelectInputMask = EventMask.ButtonPressMask |
139 EventMask.ButtonReleaseMask |
140 EventMask.KeyPressMask |
141 EventMask.KeyReleaseMask |
142 EventMask.EnterWindowMask |
143 EventMask.LeaveWindowMask |
144 EventMask.ExposureMask |
145 EventMask.FocusChangeMask |
146 EventMask.PointerMotionMask |
147 EventMask.VisibilityChangeMask |
148 EventMask.SubstructureNotifyMask |
149 EventMask.StructureNotifyMask;
150 #endregion // Local Variables
153 private XplatUIX11() {
154 // Handle singleton stuff first
157 // Now regular initialization
158 XlibLock = new object ();
159 MessageQueue = new XEventQueue ();
160 TimerList = new ArrayList ();
163 ErrorExceptions = false;
165 // X11 Initialization
166 SetDisplay(XOpenDisplay(IntPtr.Zero));
171 if (DisplayHandle!=IntPtr.Zero) {
172 XCloseDisplay(DisplayHandle);
173 DisplayHandle=IntPtr.Zero;
177 #endregion // Constructors
179 #region Singleton Specific Code
180 public static XplatUIX11 GetInstance() {
181 lock (typeof(XplatUIX11)) {
182 if (Instance == null) {
183 Instance=new XplatUIX11();
190 public int Reference {
197 #region XExceptionClass
198 internal class XException : ApplicationException {
202 XRequest RequestCode;
206 public XException(IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode) {
207 this.Display = Display;
208 this.ResourceID = ResourceID;
209 this.Serial = Serial;
210 this.RequestCode = RequestCode;
211 this.ErrorCode = ErrorCode;
212 this.MinorCode = MinorCode;
215 public override string Message {
217 return GetMessage(Display, ResourceID, Serial, ErrorCode, RequestCode, MinorCode);
221 public static string GetMessage(IntPtr Display, IntPtr ResourceID, IntPtr Serial, byte ErrorCode, XRequest RequestCode, byte MinorCode) {
226 sb = new StringBuilder(160);
227 XGetErrorText(Display, ErrorCode, sb, sb.Capacity);
228 x_error_text = sb.ToString();
230 error = String.Format("\n Error: {0}\n Request: {1:D} ({2})\n Resource ID: 0x{3:x}\n Serial: {4}", x_error_text, RequestCode, RequestCode, ResourceID.ToInt32(), Serial);
234 #endregion // XExceptionClass
236 #region Internal Methods
237 internal void SetDisplay(IntPtr display_handle) {
238 if (display_handle != IntPtr.Zero) {
239 if ((DisplayHandle != IntPtr.Zero) && (FosterParent != IntPtr.Zero)) {
240 XDestroyWindow(DisplayHandle, FosterParent);
243 if (DisplayHandle != IntPtr.Zero) {
244 XCloseDisplay(DisplayHandle);
247 DisplayHandle=display_handle;
249 // We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
250 // been hacked to do this for us.
251 Graphics.FromHdcInternal (DisplayHandle);
254 if (Environment.GetEnvironmentVariable ("MONO_XSYNC") != null) {
255 XSynchronize(DisplayHandle, true);
258 if (Environment.GetEnvironmentVariable ("MONO_XEXCEPTIONS") != null) {
259 ErrorExceptions = true;
264 RootWindow = XRootWindow(DisplayHandle, ScreenNo);
265 DefaultColormap = XDefaultColormap(DisplayHandle, ScreenNo);
267 // Create the foster parent
268 FosterParent=XCreateSimpleWindow(DisplayHandle, RootWindow, 0, 0, 1, 1, 4, 0, 0);
269 if (FosterParent==IntPtr.Zero) {
270 Console.WriteLine("XplatUIX11 Constructor failed to create FosterParent");
274 // For sleeping on the X11 socket
275 listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
276 IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 0);
280 // To wake up when a timer is ready
281 wake = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
282 wake.Connect(listen.LocalEndPoint);
285 pollfds = new Pollfd [2];
286 pollfds [0] = new Pollfd ();
287 pollfds [0].fd = XConnectionNumber (DisplayHandle);
288 pollfds [0].events = PollEvents.POLLIN;
290 pollfds [1] = new Pollfd ();
291 pollfds [1].fd = wake.Handle.ToInt32 ();
292 pollfds [1].events = PollEvents.POLLIN;
295 Keyboard = new X11Keyboard(DisplayHandle);
297 GetMessageResult = true;
299 DoubleClickInterval = 500;
301 HoverState.Interval = 500;
302 HoverState.Timer = new Timer();
303 HoverState.Timer.Enabled = false;
304 HoverState.Timer.Interval = HoverState.Interval;
305 HoverState.Timer.Tick +=new EventHandler(MouseHover);
309 ActiveWindow = IntPtr.Zero;
310 FocusWindow = IntPtr.Zero;
311 ModalWindows = new Stack(3);
313 MouseState = MouseButtons.None;
314 MousePosition = new Point(0, 0);
316 Caret.Timer = new Timer();
317 Caret.Timer.Interval = 500; // FIXME - where should this number come from?
318 Caret.Timer.Tick += new EventHandler(CaretCallback);
322 // Grab atom changes off the root window to catch certain WM events
323 XSelectInput(DisplayHandle, RootWindow, EventMask.PropertyChangeMask);
325 // Handle any upcoming errors
326 ErrorHandler = new XErrorHandler(HandleError);
327 XSetErrorHandler(ErrorHandler);
329 throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
333 internal static void Where() {
334 Console.WriteLine("Here: {0}\n", WhereString());
337 internal static string WhereString() {
345 newline = String.Format("{0}\t {1} ", Environment.NewLine, Locale.GetText("at"));
346 unknown = Locale.GetText("<unknown method>");
347 sb = new StringBuilder();
348 stack = new StackTrace(true);
350 for (int i = 0; i < stack.FrameCount; i++) {
351 frame = stack.GetFrame(i);
354 method = frame.GetMethod();
355 if (method != null) {
357 sb.AppendFormat(frame.ToString());
359 if (frame.GetFileLineNumber() != 0) {
360 sb.AppendFormat("{0}.{1} () [{2}:{3}]", method.DeclaringType.FullName, method.Name, Path.GetFileName(frame.GetFileName()), frame.GetFileLineNumber());
362 sb.AppendFormat("{0}.{1} ()", method.DeclaringType.FullName, method.Name);
368 return sb.ToString();
370 #endregion // Internal Methods
372 #region Private Methods
373 private static void SetupAtoms() {
374 NetAtoms = new int[(int)NA.LAST_NET_ATOM];
376 NetAtoms[(int)NA.WM_PROTOCOLS] = XInternAtom(DisplayHandle, "WM_PROTOCOLS", false);
377 NetAtoms[(int)NA.WM_DELETE_WINDOW] = XInternAtom(DisplayHandle, "WM_DELETE_WINDOW", false);
378 NetAtoms[(int)NA.WM_TAKE_FOCUS] = XInternAtom(DisplayHandle, "WM_TAKE_FOCUS", false);
380 NetAtoms[(int)NA._NET_SUPPORTED] = XInternAtom(DisplayHandle, "_NET_SUPPORTED", false);
381 NetAtoms[(int)NA._NET_CLIENT_LIST] = XInternAtom(DisplayHandle, "_NET_CLIENT_LIST", false);
382 NetAtoms[(int)NA._NET_NUMBER_OF_DESKTOPS] = XInternAtom(DisplayHandle, "_NET_NUMBER_OF_DESKTOPS", false);
383 NetAtoms[(int)NA._NET_DESKTOP_GEOMETRY] = XInternAtom(DisplayHandle, "_NET_DESKTOP_GEOMETRY", false);
384 NetAtoms[(int)NA._NET_DESKTOP_VIEWPORT] = XInternAtom(DisplayHandle, "_NET_DESKTOP_VIEWPORT", false);
385 NetAtoms[(int)NA._NET_CURRENT_DESKTOP] = XInternAtom(DisplayHandle, "_NET_CURRENT_DESKTOP", false);
386 NetAtoms[(int)NA._NET_DESKTOP_NAMES] = XInternAtom(DisplayHandle, "_NET_DESKTOP_NAMES", false);
387 NetAtoms[(int)NA._NET_ACTIVE_WINDOW] = XInternAtom(DisplayHandle, "_NET_ACTIVE_WINDOW", false);
388 NetAtoms[(int)NA._NET_WORKAREA] = XInternAtom(DisplayHandle, "_NET_WORKAREA", false);
389 NetAtoms[(int)NA._NET_SUPPORTING_WM_CHECK] = XInternAtom(DisplayHandle, "_NET_SUPPORTING_WM_CHECK", false);
390 NetAtoms[(int)NA._NET_VIRTUAL_ROOTS] = XInternAtom(DisplayHandle, "_NET_VIRTUAL_ROOTS", false);
391 NetAtoms[(int)NA._NET_DESKTOP_LAYOUT] = XInternAtom(DisplayHandle, "_NET_DESKTOP_LAYOUT", false);
392 NetAtoms[(int)NA._NET_SHOWING_DESKTOP] = XInternAtom(DisplayHandle, "_NET_SHOWING_DESKTOP", false);
394 NetAtoms[(int)NA._NET_CLOSE_WINDOW] = XInternAtom(DisplayHandle, "_NET_CLOSE_WINDOW", false);
395 NetAtoms[(int)NA._NET_MOVERESIZE_WINDOW] = XInternAtom(DisplayHandle, "_NET_MOVERESIZE_WINDOW", false);
396 NetAtoms[(int)NA._NET_WM_MOVERESIZE] = XInternAtom(DisplayHandle, "_NET_WM_MOVERESIZE", false);
397 NetAtoms[(int)NA._NET_RESTACK_WINDOW] = XInternAtom(DisplayHandle, "_NET_RESTACK_WINDOW", false);
398 NetAtoms[(int)NA._NET_REQUEST_FRAME_EXTENTS] = XInternAtom(DisplayHandle, "_NET_REQUEST_FRAME_EXTENTS", false);
400 NetAtoms[(int)NA._NET_WM_NAME] = XInternAtom(DisplayHandle, "_NET_WM_NAME", false);
401 NetAtoms[(int)NA._NET_WM_VISIBLE_NAME] = XInternAtom(DisplayHandle, "_NET_WM_VISIBLE_NAME", false);
402 NetAtoms[(int)NA._NET_WM_ICON_NAME] = XInternAtom(DisplayHandle, "_NET_WM_ICON_NAME", false);
403 NetAtoms[(int)NA._NET_WM_VISIBLE_ICON_NAME] = XInternAtom(DisplayHandle, "_NET_WM_VISIBLE_ICON_NAME", false);
404 NetAtoms[(int)NA._NET_WM_DESKTOP] = XInternAtom(DisplayHandle, "_NET_WM_DESKTOP", false);
405 NetAtoms[(int)NA._NET_WM_WINDOW_TYPE] = XInternAtom(DisplayHandle, "_NET_WM_WINDOW_TYPE", false);
406 NetAtoms[(int)NA._NET_WM_STATE] = XInternAtom(DisplayHandle, "_NET_WM_STATE", false);
407 NetAtoms[(int)NA._NET_WM_ALLOWED_ACTIONS] = XInternAtom(DisplayHandle, "_NET_WM_ALLOWED_ACTIONS", false);
408 NetAtoms[(int)NA._NET_WM_STRUT] = XInternAtom(DisplayHandle, "_NET_WM_STRUT", false);
409 NetAtoms[(int)NA._NET_WM_STRUT_PARTIAL] = XInternAtom(DisplayHandle, "_NET_WM_STRUT_PARTIAL", false);
410 NetAtoms[(int)NA._NET_WM_ICON_GEOMETRY] = XInternAtom(DisplayHandle, "_NET_WM_ICON_GEOMETRY", false);
411 NetAtoms[(int)NA._NET_WM_ICON] = XInternAtom(DisplayHandle, "_NET_WM_ICON", false);
412 NetAtoms[(int)NA._NET_WM_PID] = XInternAtom(DisplayHandle, "_NET_WM_PID", false);
413 NetAtoms[(int)NA._NET_WM_HANDLED_ICONS] = XInternAtom(DisplayHandle, "_NET_WM_HANDLED_ICONS", false);
414 NetAtoms[(int)NA._NET_WM_USER_TIME] = XInternAtom(DisplayHandle, "_NET_WM_USER_TIME", false);
415 NetAtoms[(int)NA._NET_FRAME_EXTENTS] = XInternAtom(DisplayHandle, "_NET_FRAME_EXTENTS", false);
417 NetAtoms[(int)NA._NET_WM_PING] = XInternAtom(DisplayHandle, "_NET_WM_PING", false);
418 NetAtoms[(int)NA._NET_WM_SYNC_REQUEST] = XInternAtom(DisplayHandle, "_NET_WM_SYNC_REQUEST", false);
420 NetAtoms[(int)NA._NET_SYSTEM_TRAY_S] = XInternAtom(DisplayHandle, "_NET_SYSTEM_TRAY_S" + ScreenNo.ToString(), false);
421 NetAtoms[(int)NA._NET_SYSTEM_TRAY_OPCODE] = XInternAtom(DisplayHandle, "_NET_SYSTEM_TRAY_OPCODE", false);
422 NetAtoms[(int)NA._NET_SYSTEM_TRAY_ORIENTATION] = XInternAtom(DisplayHandle, "_NET_SYSTEM_TRAY_ORIENTATION", false);
424 NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ] = XInternAtom(DisplayHandle, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
425 NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT] = XInternAtom(DisplayHandle, "_NET_WM_STATE_MAXIMIZED_VERT", false);
427 NetAtoms[(int)NA._XEMBED] = XInternAtom(DisplayHandle, "_XEMBED", false);
428 NetAtoms[(int)NA._XEMBED_INFO] = XInternAtom(DisplayHandle, "_XEMBED_INFO", false);
430 NetAtoms[(int)NA._MOTIF_WM_HINTS] = XInternAtom(DisplayHandle, "_MOTIF_WM_HINTS", false);
432 NetAtoms[(int)NA._NET_WM_STATE_NO_TASKBAR] = XInternAtom(DisplayHandle, "_NET_WM_STATE_NO_TASKBAR", false);
433 NetAtoms[(int)NA._NET_WM_STATE_ABOVE] = XInternAtom(DisplayHandle, "_NET_WM_STATE_ABOVE", false);
434 NetAtoms[(int)NA._NET_WM_STATE_MODAL] = XInternAtom(DisplayHandle, "_NET_WM_STATE_MODAL", false);
435 NetAtoms[(int)NA._NET_WM_CONTEXT_HELP] = XInternAtom(DisplayHandle, "_NET_WM_CONTEXT_HELP", false);
438 AsyncAtom = XInternAtom(DisplayHandle, "_SWF_AsyncAtom", false);
439 PostAtom = XInternAtom (DisplayHandle, "_SWF_PostMessageAtom", false);
440 HoverState.Atom = XInternAtom(DisplayHandle, "_SWF_HoverAtom", false);
443 private void GetSystrayManagerWindow() {
444 XGrabServer(DisplayHandle);
445 SystrayMgrWindow = XGetSelectionOwner(DisplayHandle, (IntPtr)NetAtoms[(int)NA._NET_SYSTEM_TRAY_S]);
446 XUngrabServer(DisplayHandle);
447 XFlush(DisplayHandle);
450 private void SendNetWMMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
454 xev.ClientMessageEvent.type = XEventName.ClientMessage;
455 xev.ClientMessageEvent.send_event = true;
456 xev.ClientMessageEvent.window = window;
457 xev.ClientMessageEvent.message_type = message_type;
458 xev.ClientMessageEvent.format = 32;
459 xev.ClientMessageEvent.ptr1 = l0;
460 xev.ClientMessageEvent.ptr2 = l1;
461 xev.ClientMessageEvent.ptr3 = l2;
462 XSendEvent(DisplayHandle, RootWindow, false, EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask, ref xev);
465 private void SendNetClientMessage(IntPtr window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) {
469 xev.ClientMessageEvent.type = XEventName.ClientMessage;
470 xev.ClientMessageEvent.send_event = true;
471 xev.ClientMessageEvent.window = window;
472 xev.ClientMessageEvent.message_type = message_type;
473 xev.ClientMessageEvent.format = 32;
474 xev.ClientMessageEvent.ptr1 = l0;
475 xev.ClientMessageEvent.ptr2 = l1;
476 xev.ClientMessageEvent.ptr3 = l2;
477 XSendEvent(DisplayHandle, window, false, EventMask.NoEventMask, ref xev);
480 private void SetHwndStyles(Hwnd hwnd, CreateParams cp) {
481 if ((cp.Style & (int)WindowStyles.WS_CHILD) != 0) {
482 if ((cp.Style & (int)WindowStyles.WS_THICKFRAME) != 0) {
483 hwnd.BorderStyle = BorderStyle.Fixed3D;
484 } else if ((cp.Style & (int)WindowStyles.WS_BORDER) != 0) {
485 hwnd.BorderStyle = BorderStyle.FixedSingle;
489 if ((cp.ExStyle & (int)WindowStyles.WS_EX_CLIENTEDGE) != 0) {
490 hwnd.edge_style = Border3DStyle.Sunken;
491 } else if ((cp.ExStyle & (int)WindowStyles.WS_EX_STATICEDGE) != 0) {
492 hwnd.edge_style = Border3DStyle.Flat;
493 } else if ((cp.ExStyle & (int)WindowStyles.WS_EX_WINDOWEDGE) != 0) {
494 hwnd.edge_style = Border3DStyle.Raised;
495 } else if ((cp.ExStyle & (int)WindowStyles.WS_EX_WINDOWEDGE) != 0) {
496 hwnd.edge_style = Border3DStyle.Raised;
499 if ((cp.Style & (int)WindowStyles.WS_CAPTION) != 0) {
500 if ((cp.ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
501 hwnd.title_style = TitleStyle.Tool;
503 hwnd.title_style = TitleStyle.Normal;
508 private void SetWMStyles(Hwnd hwnd, CreateParams cp) {
509 MotifWmHints mwmHints;
510 MotifFunctions functions;
511 MotifDecorations decorations;
514 Rectangle client_rect;
516 mwmHints = new MotifWmHints();
520 mwmHints.flags = (IntPtr)(MotifFlags.Functions | MotifFlags.Decorations);
521 mwmHints.functions = (IntPtr)0;
522 mwmHints.decorations = (IntPtr)0;
524 if ((cp.Style & (int)WindowStyles.WS_CAPTION) != 0) {
525 functions |= MotifFunctions.Move;
526 decorations |= MotifDecorations.Title | MotifDecorations.Menu;
529 if ((cp.Style & ((int)WindowStyles.WS_THICKFRAME)) != 0) {
530 functions |= MotifFunctions.Move | MotifFunctions.Resize;
531 decorations |= MotifDecorations.Border | MotifDecorations.ResizeH;
534 if ((cp.Style & ((int)WindowStyles.WS_MINIMIZEBOX)) != 0) {
535 functions |= MotifFunctions.Minimize;
536 decorations |= MotifDecorations.Minimize;
539 if ((cp.Style & ((int)WindowStyles.WS_MAXIMIZEBOX)) != 0) {
540 functions |= MotifFunctions.Maximize;
541 decorations |= MotifDecorations.Maximize;
544 if ((cp.Style & ((int)WindowStyles.WS_SYSMENU)) != 0) {
545 functions |= MotifFunctions.Close;
548 if ((cp.ExStyle & ((int)WindowStyles.WS_EX_DLGMODALFRAME)) != 0) {
549 decorations |= MotifDecorations.Border;
552 if ((cp.Style & ((int)WindowStyles.WS_DLGFRAME)) != 0) {
553 decorations |= MotifDecorations.Border;
556 if ((cp.Style & ((int)WindowStyles.WS_BORDER)) != 0) {
557 decorations |= MotifDecorations.Border;
560 if ((cp.ExStyle & ((int)WindowStyles.WS_EX_TOOLWINDOW)) != 0) {
565 mwmHints.functions = (IntPtr)functions;
566 mwmHints.decorations = (IntPtr)decorations;
569 client_rect = hwnd.ClientRect;
571 XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._MOTIF_WM_HINTS], NetAtoms[(int)NA._MOTIF_WM_HINTS], 32, PropertyMode.Replace, ref mwmHints, 5);
573 if (((cp.Style & (int)WindowStyles.WS_POPUP) != 0) && (hwnd.parent != null) && (hwnd.parent.whole_window != IntPtr.Zero)) {
574 XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd.parent.whole_window);
576 XMoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
581 if ((cp.ExStyle & ((int)WindowStyles.WS_EX_TOOLWINDOW)) != 0) {
582 atoms[atom_count++] = (uint)NetAtoms[(int)NA._NET_WM_STATE_ABOVE];
583 atoms[atom_count++] = (uint)NetAtoms[(int)NA._NET_WM_STATE_NO_TASKBAR];
586 XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._NET_WM_STATE], Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, atom_count);
589 atoms[atom_count++] = (uint)NetAtoms[(int)NA.WM_DELETE_WINDOW];
590 if ((cp.ExStyle & (int)WindowStyles.WS_EX_CONTEXTHELP) != 0) {
591 atoms[atom_count++] = (uint)NetAtoms[(int)NA._NET_WM_CONTEXT_HELP];
594 XSetWMProtocols(DisplayHandle, hwnd.whole_window, atoms, atom_count);
598 private void SetIcon(Hwnd hwnd, Icon icon) {
604 bitmap = icon.ToBitmap();
606 size = bitmap.Width * bitmap.Height + 2;
607 data = new uint[size];
609 data[index++] = (uint)bitmap.Width;
610 data[index++] = (uint)bitmap.Height;
612 for (int y = 0; y < bitmap.Height; y++) {
613 for (int x = 0; x < bitmap.Width; x++) {
614 data[index++] = (uint)bitmap.GetPixel(x, y).ToArgb();
617 XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._NET_WM_ICON], Atom.XA_CARDINAL, 32, PropertyMode.Replace, data, size);
620 private void WakeupMain () {
621 wake.BeginSend (new byte [] { 0xFF }, 0, 1, SocketFlags.None, null, null);
624 private void AddExpose (XEvent xevent) {
627 hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
630 if (hwnd == null || !hwnd.visible) {
634 if (xevent.AnyEvent.window == hwnd.client_window) {
635 hwnd.AddInvalidArea(xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
637 if (!hwnd.expose_pending) {
638 MessageQueue.Enqueue(xevent);
639 hwnd.expose_pending = true;
642 if (!hwnd.nc_expose_pending) {
643 MessageQueue.Enqueue(xevent);
644 hwnd.nc_expose_pending = true;
649 private void AddConfigureNotify (XEvent xevent) {
652 hwnd = Hwnd.GetObjectFromWindow(xevent.ConfigureEvent.window);
659 if (xevent.ConfigureEvent.window == hwnd.whole_window) {
660 if (hwnd.parent != null) {
661 hwnd.x = xevent.ConfigureEvent.x;
662 hwnd.y = xevent.ConfigureEvent.y;
666 // We need to 'discount' the window the WM has put us in
667 XTranslateCoordinates(DisplayHandle, XGetParent(hwnd.whole_window), RootWindow, xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, out hwnd.x, out hwnd.y, out child);
670 hwnd.width = xevent.ConfigureEvent.width;
671 hwnd.height = xevent.ConfigureEvent.height;
673 if (!hwnd.configure_pending) {
674 MessageQueue.Enqueue(xevent);
675 hwnd.configure_pending = true;
678 // We drop configure events for Client windows
681 private void ShowCaret() {
682 if ((Caret.gc == IntPtr.Zero) || Caret.On) {
688 XDrawLine(DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
692 private void HideCaret() {
693 if ((Caret.gc == IntPtr.Zero) || !Caret.On) {
699 XDrawLine(DisplayHandle, Caret.Window, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
703 private int NextTimeout (DateTime now) {
704 int timeout = Int32.MaxValue;
706 foreach (Timer timer in TimerList) {
707 int next = (int) (timer.Expires - now).TotalMilliseconds;
709 return 0; // Have a timer that has already expired
712 if (next < timeout) {
717 if (timeout < Timer.Minimum) {
718 timeout = Timer.Minimum;
724 private void CheckTimers (DateTime now) {
728 count = TimerList.Count;
734 for (int i = 0; i < TimerList.Count; i++) {
737 timer = (Timer) TimerList[i];
739 if (timer.Enabled && timer.Expires <= now) {
747 private void UpdateMessageQueue () {
754 pending = XPending (DisplayHandle);
759 Idle (this, EventArgs.Empty);
763 pending = XPending (DisplayHandle);
770 timeout = NextTimeout (now);
773 Syscall.poll (pollfds, (uint) pollfds.Length, timeout);
776 pending = XPending (DisplayHandle);
785 pending = XPending (DisplayHandle);
789 while (pending > 0) {
790 XEvent xevent = new XEvent ();
793 XNextEvent (DisplayHandle, ref xevent);
796 switch (xevent.type) {
797 case XEventName.Expose:
801 case XEventName.KeyPress:
802 case XEventName.KeyRelease:
803 case XEventName.ButtonPress:
804 case XEventName.ButtonRelease:
805 case XEventName.MotionNotify:
806 case XEventName.EnterNotify:
807 case XEventName.LeaveNotify:
808 case XEventName.CreateNotify:
809 case XEventName.DestroyNotify:
810 case XEventName.FocusIn:
811 case XEventName.FocusOut:
812 case XEventName.ClientMessage:
813 MessageQueue.Enqueue (xevent);
816 case XEventName.ConfigureNotify:
817 AddConfigureNotify(xevent);
820 case XEventName.PropertyNotify:
821 if (xevent.PropertyEvent.atom == NetAtoms[(int)NA._NET_ACTIVE_WINDOW]) {
826 IntPtr prop = IntPtr.Zero;
829 prev_active = ActiveWindow;
830 XGetWindowProperty(DisplayHandle, RootWindow, NetAtoms[(int)NA._NET_ACTIVE_WINDOW], 0, 1, false, Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
831 if ((nitems > 0) && (prop != IntPtr.Zero)) {
832 ActiveWindow = Hwnd.GetHandleFromWindow((IntPtr)Marshal.ReadInt32(prop));
835 if (prev_active != ActiveWindow) {
836 if (prev_active != IntPtr.Zero) {
837 PostMessage(prev_active, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
839 if (ActiveWindow != IntPtr.Zero) {
840 PostMessage(ActiveWindow, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_ACTIVE, IntPtr.Zero);
843 if (ModalWindows.Count == 0) {
846 // Modality handling, if we are modal and the new active window is one
847 // of ours but not the modal one, switch back to the modal window
849 if (NativeWindow.FindWindow(ActiveWindow) != null) {
850 if (ActiveWindow != (IntPtr)ModalWindows.Peek()) {
851 Activate((IntPtr)ModalWindows.Peek());
863 pending = XPending (DisplayHandle);
868 private IntPtr GetMousewParam(int Delta) {
871 if ((MouseState & MouseButtons.Left) != 0) {
872 result |= (int)MsgButtons.MK_LBUTTON;
875 if ((MouseState & MouseButtons.Middle) != 0) {
876 result |= (int)MsgButtons.MK_MBUTTON;
879 if ((MouseState & MouseButtons.Right) != 0) {
880 result |= (int)MsgButtons.MK_RBUTTON;
883 Keys mods = ModifierKeys;
884 if ((mods & Keys.Control) != 0) {
885 result |= (int)MsgButtons.MK_CONTROL;
888 if ((mods & Keys.Shift) != 0) {
889 result |= (int)MsgButtons.MK_SHIFT;
892 result |= Delta << 16;
894 return (IntPtr)result;
896 private IntPtr XGetParent(IntPtr handle) {
903 XQueryTree(DisplayHandle, handle, out Root, out Parent, out Children, out ChildCount);
906 if (Children!=IntPtr.Zero) {
914 private int HandleError(IntPtr display, ref XErrorEvent error_event) {
915 if (ErrorExceptions) {
916 throw new XException(error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code);
918 Console.WriteLine("X11 Error encountered: {0}{1}\n", XException.GetMessage(error_event.display, error_event.resourceid, error_event.serial, error_event.error_code, error_event.request_code, error_event.minor_code), WhereString());
922 #endregion // Private Methods
925 private void MouseHover(object sender, EventArgs e) {
926 if ((HoverState.X == MousePosition.X) && (HoverState.Y == MousePosition.Y)) {
929 HoverState.Timer.Enabled = false;
931 if (HoverState.Window != IntPtr.Zero) {
932 xevent = new XEvent ();
934 xevent.type = XEventName.ClientMessage;
935 xevent.ClientMessageEvent.display = DisplayHandle;
936 xevent.ClientMessageEvent.window = (IntPtr)HoverState.Window;
937 xevent.ClientMessageEvent.message_type = (IntPtr)HoverState.Atom;
938 xevent.ClientMessageEvent.format = 32;
939 xevent.ClientMessageEvent.ptr1 = (IntPtr) (HoverState.Y << 16 | HoverState.X);
941 MessageQueue.EnqueueLocked (xevent);
948 private void CaretCallback(object sender, EventArgs e) {
952 Caret.On = !Caret.On;
954 XDrawLine(DisplayHandle, Caret.Hwnd, Caret.gc, Caret.X, Caret.Y, Caret.X, Caret.Y + Caret.Height);
956 #endregion // Callbacks
958 #region Public Properties
959 internal override Size CursorSize {
964 if (XQueryBestCursor(DisplayHandle, RootWindow, 32, 32, out x, out y) != 0) {
965 return new Size(x, y);
967 return new Size(16, 16);
972 internal override bool DragFullWindows {
978 internal override Size DragSize {
980 return new Size(4, 4);
984 internal override Size IconSize {
990 if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
994 current = (long)list;
997 size = new XIconSize();
999 for (int i = 0; i < count; i++) {
1000 size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
1001 current += Marshal.SizeOf(size);
1003 // Look for our preferred size
1004 if (size.min_width == 32) {
1006 return new Size(32, 32);
1009 if (size.max_width == 32) {
1011 return new Size(32, 32);
1014 if (size.min_width < 32 && size.max_width > 32) {
1017 // check if we can fit one
1019 while (x < size.max_width) {
1020 x += size.width_inc;
1023 return new Size(32, 32);
1028 if (largest < size.max_width) {
1029 largest = size.max_width;
1033 // We didn't find a match or we wouldn't be here
1034 return new Size(largest, largest);
1037 return new Size(32, 32);
1042 internal override int KeyboardSpeed {
1045 // A lot harder: need to do:
1046 // XkbQueryExtension(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 1
1047 // XkbAllocKeyboard(0x08051008, 0xbfffdf4c, 0xbfffdf50, 0xbfffdf54, 0xbfffdf58) = 0x080517a8
1048 // XkbGetControls(0x08051008, 1, 0x080517a8, 0xbfffdf54, 0xbfffdf58) = 0
1050 // And from that we can tell the repetition rate
1052 // Notice, the values must map to:
1053 // [0, 31] which maps to 2.5 to 30 repetitions per second.
1059 internal override int KeyboardDelay {
1062 // Return values must range from 0 to 4, 0 meaning 250ms,
1063 // and 4 meaning 1000 ms.
1065 return 1; // ie, 500 ms
1069 internal override Size MaxWindowTrackSize {
1071 return new Size (WorkingArea.Width, WorkingArea.Height);
1075 internal override Size MinimizedWindowSize {
1077 return new Size(1, 1);
1081 internal override Size MinimizedWindowSpacingSize {
1083 return new Size(1, 1);
1087 internal override Size MinimumWindowSize {
1089 return new Size(1, 1);
1093 internal override Size MinWindowTrackSize {
1095 return new Size(1, 1);
1099 internal override Size SmallIconSize {
1105 if (XGetIconSizes(DisplayHandle, RootWindow, out list, out count) != 0) {
1109 current = (long)list;
1112 size = new XIconSize();
1114 for (int i = 0; i < count; i++) {
1115 size = (XIconSize)Marshal.PtrToStructure((IntPtr)current, size.GetType());
1116 current += Marshal.SizeOf(size);
1118 // Look for our preferred size
1119 if (size.min_width == 16) {
1121 return new Size(16, 16);
1124 if (size.max_width == 16) {
1126 return new Size(16, 16);
1129 if (size.min_width < 16 && size.max_width > 16) {
1132 // check if we can fit one
1134 while (x < size.max_width) {
1135 x += size.width_inc;
1138 return new Size(16, 16);
1143 if (smallest == 0 || smallest > size.min_width) {
1144 smallest = size.min_width;
1148 // We didn't find a match or we wouldn't be here
1149 return new Size(smallest, smallest);
1152 return new Size(16, 16);
1157 internal override int MouseButtonCount {
1163 internal override bool MouseButtonsSwapped {
1165 return false; // FIXME - how to detect?
1169 internal override bool MouseWheelPresent {
1171 return true; // FIXME - how to detect?
1175 internal override Rectangle VirtualScreen {
1181 internal override Rectangle WorkingArea {
1187 IntPtr prop = IntPtr.Zero;
1191 XGetWindowProperty(DisplayHandle, RootWindow, NetAtoms[(int)NA._NET_DESKTOP_GEOMETRY], 0, 256, false, Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
1192 if ((nitems == 2) && (prop != IntPtr.Zero)) {
1193 width = Marshal.ReadInt32(prop, 0);
1194 height = Marshal.ReadInt32(prop, 4);
1197 return new Rectangle(0, 0, width, height);
1199 XWindowAttributes attributes=new XWindowAttributes();
1202 XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
1205 return new Rectangle(0, 0, attributes.width, attributes.height);
1209 #endregion // Public properties
1211 #region Public Static Methods
1212 internal override IntPtr InitializeDriver() {
1214 if (DisplayHandle==IntPtr.Zero) {
1215 SetDisplay(XOpenDisplay(IntPtr.Zero));
1221 internal override void ShutdownDriver(IntPtr token) {
1223 if (DisplayHandle!=IntPtr.Zero) {
1224 XCloseDisplay(DisplayHandle);
1225 DisplayHandle=IntPtr.Zero;
1230 internal override void EnableThemes() {
1231 ThemesEnabled = true;
1235 internal override void Activate(IntPtr handle) {
1237 SendNetWMMessage(Hwnd.ObjectFromHandle(handle).whole_window, (IntPtr)NetAtoms[(int)NA._NET_ACTIVE_WINDOW], IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
1238 //XRaiseWindow(DisplayHandle, handle);
1243 internal override void CaretVisible(IntPtr handle, bool visible) {
1244 // Visible is cumulative; two hides require two shows before the caret is visible again
1245 if (Caret.Hwnd == handle) {
1247 if (Caret.Visible < 1) {
1250 if (Caret.Visible == 1) {
1252 Caret.Timer.Start();
1257 if (Caret.Visible == 0) {
1265 internal override bool CalculateWindowRect(IntPtr handle, ref Rectangle ClientRect, int Style, int ExStyle, IntPtr MenuHandle, out Rectangle WindowRect) {
1266 BorderStyle border_style;
1267 TitleStyle title_style;
1269 title_style = TitleStyle.None;
1270 if ((Style & (int)WindowStyles.WS_CAPTION) != 0) {
1271 if ((ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
1272 title_style = TitleStyle.Tool;
1274 title_style = TitleStyle.Normal;
1278 border_style = BorderStyle.None;
1279 if ((Style & (int)WindowStyles.WS_CHILD) != 0) {
1280 if ((Style & (int)WindowStyles.WS_THICKFRAME) != 0) {
1281 border_style = BorderStyle.Fixed3D;
1282 } else if ((Style & (int)WindowStyles.WS_BORDER) != 0) {
1283 border_style = BorderStyle.FixedSingle;
1287 WindowRect = Hwnd.GetWindowRectangle(border_style, MenuHandle, title_style, ClientRect);
1292 internal override void ClientToScreen(IntPtr handle, ref int x, ref int y) {
1298 hwnd = Hwnd.ObjectFromHandle(handle);
1301 XTranslateCoordinates(DisplayHandle, hwnd.client_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
1308 internal override void CreateCaret(IntPtr handle, int width, int height) {
1309 XGCValues gc_values;
1312 hwnd = Hwnd.ObjectFromHandle(handle);
1314 if (Caret.Hwnd != IntPtr.Zero) {
1315 DestroyCaret(Caret.Hwnd);
1318 Caret.Hwnd = handle;
1319 Caret.Window = hwnd.client_window;
1320 Caret.Width = width;
1321 Caret.Height = height;
1325 gc_values = new XGCValues();
1326 gc_values.line_width = width;
1328 Caret.gc = XCreateGC(DisplayHandle, Caret.Window, GCFunction.GCLineWidth, ref gc_values);
1329 if (Caret.gc == IntPtr.Zero) {
1330 Caret.Hwnd = IntPtr.Zero;
1334 XSetFunction(DisplayHandle, Caret.gc, GXFunction.GXinvert);
1337 internal override IntPtr CreateWindow(CreateParams cp) {
1338 XSetWindowAttributes Attributes;
1344 IntPtr ParentHandle;
1346 IntPtr ClientWindow;
1347 Rectangle ClientRect;
1352 SetHwndStyles(hwnd, cp);
1354 Attributes = new XSetWindowAttributes();
1360 if (Width<1) Width=1;
1361 if (Height<1) Height=1;
1363 if (cp.Parent != IntPtr.Zero) {
1364 ParentHandle = Hwnd.ObjectFromHandle(cp.Parent).client_window;
1366 if ((cp.Style & (int)WindowStyles.WS_CHILD) != 0) {
1367 // We need to use our foster parent window until this poor child gets it's parent assigned
1368 ParentHandle=FosterParent;
1369 } else if ((cp.Style & (int)WindowStyles.WS_POPUP) != 0) {
1370 ParentHandle=RootWindow;
1372 // Default position on screen, if window manager doesn't place us somewhere else
1375 ParentHandle=RootWindow;
1379 // Save what's under the toolwindow
1380 if ((cp.ExStyle & (int)WindowStyles.WS_EX_TOOLWINDOW) != 0) {
1381 Attributes.save_under = true;
1385 // If we're a popup without caption we override the WM
1386 if ((cp.Style & ((int)WindowStyles.WS_POPUP)) != 0) {
1387 if ((cp.Style & (int)WindowStyles.WS_CAPTION) == 0) {
1388 Attributes.override_redirect = true;
1392 Attributes.bit_gravity = Gravity.NorthWestGravity;
1393 Attributes.win_gravity = Gravity.NorthWestGravity;
1398 hwnd.height = Height;
1399 hwnd.parent = Hwnd.ObjectFromHandle(cp.Parent);
1401 ClientRect = hwnd.ClientRect;
1402 ClientWindow = IntPtr.Zero;
1405 WholeWindow = XCreateWindow(DisplayHandle, ParentHandle, X, Y, Width, Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, IntPtr.Zero, SetWindowValuemask.BitGravity | SetWindowValuemask.WinGravity | SetWindowValuemask.SaveUnder | SetWindowValuemask.OverrideRedirect, ref Attributes);
1406 if (WholeWindow != IntPtr.Zero) {
1407 ClientWindow = XCreateWindow(DisplayHandle, WholeWindow, ClientRect.X, ClientRect.Y, ClientRect.Width, ClientRect.Height, 0, (int)CreateWindowArgs.CopyFromParent, (int)CreateWindowArgs.InputOutput, IntPtr.Zero, SetWindowValuemask.Nothing, ref Attributes);
1411 if ((WholeWindow == IntPtr.Zero) || (ClientWindow == IntPtr.Zero)) {
1412 throw new Exception("Could not create X11 windows");
1415 hwnd.WholeWindow = WholeWindow;
1416 hwnd.ClientWindow = ClientWindow;
1419 Console.WriteLine("Created window {0:X} / {1:X} parent {2:X}", ClientWindow.ToInt32(), WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0);
1423 XSelectInput(DisplayHandle, hwnd.whole_window, SelectInputMask);
1424 XSelectInput(DisplayHandle, hwnd.client_window, SelectInputMask);
1426 if ((cp.Style & (int)WindowStyles.WS_VISIBLE) != 0) {
1427 XMapWindow(DisplayHandle, hwnd.whole_window);
1428 XMapWindow(DisplayHandle, hwnd.client_window);
1429 hwnd.visible = true;
1433 SetWMStyles(hwnd, cp);
1438 internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height) {
1439 CreateParams create_params = new CreateParams();
1441 create_params.Caption = "";
1442 create_params.X = X;
1443 create_params.Y = Y;
1444 create_params.Width = Width;
1445 create_params.Height = Height;
1447 create_params.ClassName=XplatUI.DefaultClassName;
1448 create_params.ClassStyle = 0;
1449 create_params.ExStyle=0;
1450 create_params.Parent=IntPtr.Zero;
1451 create_params.Param=0;
1453 return CreateWindow(create_params);
1456 internal override IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot) {
1458 Bitmap cursor_bitmap;
1466 IntPtr cursor_pixmap;
1473 if (XQueryBestCursor(DisplayHandle, RootWindow, bitmap.Width, bitmap.Height, out width, out height) == 0) {
1477 // Win32 only allows creation cursors of a certain size
1478 if ((bitmap.Width != width) || (bitmap.Width != height)) {
1479 cursor_bitmap = new Bitmap(bitmap, new Size(width, height));
1480 cursor_mask = new Bitmap(mask, new Size(width, height));
1482 cursor_bitmap = bitmap;
1486 width = cursor_bitmap.Width;
1487 height = cursor_bitmap.Height;
1489 cursor_bits = new Byte[(width / 8) * height];
1490 mask_bits = new Byte[(width / 8) * height];
1492 for (int y = 0; y < height; y++) {
1493 for (int x = 0; x < width; x++) {
1494 c_pixel = cursor_bitmap.GetPixel(x, y);
1495 m_pixel = cursor_mask.GetPixel(x, y);
1497 and = c_pixel == cursor_pixel;
1498 xor = m_pixel == mask_pixel;
1502 // cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8))); // The bit already is 0
1503 mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
1504 } else if (!and && xor) {
1506 cursor_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
1507 mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
1509 } else if (and && !xor) {
1511 } else if (and && xor) {
1514 // X11 doesn't know the 'reverse screen' concept, so we'll treat them the same
1515 // we want both to be 0 so nothing to be done
1516 //cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));
1517 //mask_bits[y * width / 8 + x / 8] |= (byte)(01 << (x % 8));
1523 cursor_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, cursor_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
1524 mask_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, mask_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
1528 fg.pixel = XWhitePixel(DisplayHandle, ScreenNo);
1529 fg.red = (ushort)65535;
1530 fg.green = (ushort)65535;
1531 fg.blue = (ushort)65535;
1533 bg.pixel = XBlackPixel(DisplayHandle, ScreenNo);
1535 cursor = XCreatePixmapCursor(DisplayHandle, cursor_pixmap, mask_pixmap, ref fg, ref bg, xHotSpot, yHotSpot);
1537 XFreePixmap(DisplayHandle, cursor_pixmap);
1538 XFreePixmap(DisplayHandle, mask_pixmap);
1543 internal override IntPtr DefineStdCursor(StdCursor id) {
1544 CursorFontShape shape;
1547 // FIXME - define missing shapes
1550 case StdCursor.AppStarting: {
1551 shape = CursorFontShape.XC_watch;
1555 case StdCursor.Arrow: {
1559 case StdCursor.Cross: {
1560 shape = CursorFontShape.XC_crosshair;
1564 case StdCursor.Default: {
1568 case StdCursor.Hand: {
1569 shape = CursorFontShape.XC_hand2;
1573 case StdCursor.Help: {
1574 shape = CursorFontShape.XC_question_arrow;
1578 case StdCursor.HSplit: {
1579 shape = CursorFontShape.XC_sb_h_double_arrow;
1583 case StdCursor.IBeam: {
1584 shape = CursorFontShape.XC_xterm;
1588 case StdCursor.No: {
1589 shape = CursorFontShape.XC_circle;
1593 case StdCursor.NoMove2D: {
1594 shape = CursorFontShape.XC_fleur;
1598 case StdCursor.NoMoveHoriz: {
1599 shape = CursorFontShape.XC_fleur;
1603 case StdCursor.NoMoveVert: {
1604 shape = CursorFontShape.XC_fleur;
1608 case StdCursor.PanEast: {
1609 shape = CursorFontShape.XC_fleur;
1613 case StdCursor.PanNE: {
1614 shape = CursorFontShape.XC_fleur;
1618 case StdCursor.PanNorth: {
1619 shape = CursorFontShape.XC_fleur;
1623 case StdCursor.PanNW: {
1624 shape = CursorFontShape.XC_fleur;
1628 case StdCursor.PanSE: {
1629 shape = CursorFontShape.XC_fleur;
1633 case StdCursor.PanSouth: {
1634 shape = CursorFontShape.XC_fleur;
1638 case StdCursor.PanSW: {
1639 shape = CursorFontShape.XC_fleur;
1643 case StdCursor.PanWest: {
1644 shape = CursorFontShape.XC_sizing;
1648 case StdCursor.SizeAll: {
1649 shape = CursorFontShape.XC_fleur;
1653 case StdCursor.SizeNESW: {
1654 shape = CursorFontShape.XC_sizing;
1658 case StdCursor.SizeNS: {
1659 shape = CursorFontShape.XC_fleur;
1663 case StdCursor.SizeNWSE: {
1664 shape = CursorFontShape.XC_bottom_right_corner;
1668 case StdCursor.SizeWE: {
1669 shape = CursorFontShape.XC_fleur;
1673 case StdCursor.UpArrow: {
1674 shape = CursorFontShape.XC_center_ptr;
1678 case StdCursor.VSplit: {
1679 shape = CursorFontShape.XC_sb_v_double_arrow;
1683 case StdCursor.WaitCursor: {
1684 shape = CursorFontShape.XC_watch;
1694 cursor = XCreateFontCursor(DisplayHandle, shape);
1699 internal override IntPtr DefWndProc(ref Message msg) {
1700 switch((Msg)msg.Msg) {
1701 case Msg.WM_ERASEBKGND: {
1704 hwnd = Hwnd.ObjectFromHandle(msg.HWnd);
1705 XClearArea(DisplayHandle, hwnd.client_window, hwnd.invalid.X, hwnd.invalid.Y, hwnd.invalid.Width, hwnd.invalid.Height, false);
1713 internal override void DestroyCaret(IntPtr handle) {
1714 if (Caret.Hwnd == handle) {
1715 if (Caret.Visible == 1) {
1719 if (Caret.gc != IntPtr.Zero) {
1720 XFreeGC(DisplayHandle, Caret.gc);
1721 Caret.gc = IntPtr.Zero;
1723 Caret.Hwnd = IntPtr.Zero;
1729 internal override void DestroyCursor(IntPtr cursor) {
1731 XFreeCursor(DisplayHandle, cursor);
1735 internal override void DestroyWindow(IntPtr handle) {
1738 hwnd = Hwnd.ObjectFromHandle(handle);
1742 Console.WriteLine("window {0:X} already destroyed", handle.ToInt32());
1748 Console.WriteLine("Destroying window {0:X}", handle.ToInt32());
1751 // Make sure if the caret is in the window, that we destroy the caret, too
1752 if (Caret.Hwnd == hwnd.client_window) {
1753 DestroyCaret(handle);
1757 if (hwnd.client_window != IntPtr.Zero) {
1758 XDestroyWindow(DisplayHandle, hwnd.client_window);
1761 if (hwnd.whole_window != IntPtr.Zero) {
1762 XDestroyWindow(DisplayHandle, hwnd.whole_window);
1769 internal override IntPtr DispatchMessage(ref MSG msg) {
1770 return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
1773 internal override void DoEvents() {
1774 MSG msg = new MSG ();
1775 while (PeekMessage(ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
1776 if (msg.message == Msg.WM_PAINT) {
1777 TranslateMessage (ref msg);
1778 DispatchMessage (ref msg);
1783 internal override void EnableWindow(IntPtr handle, bool Enable) {
1784 // We do nothing; On X11 SetModal is used to create modal dialogs, on Win32 this function is used (see comment there)
1787 internal override void EraseWindowBackground(IntPtr handle, IntPtr wParam) {
\r
1790 hwnd = Hwnd.ObjectFromHandle(handle);
\r
1793 XClearArea (DisplayHandle, hwnd.client_window, hwnd.invalid.Left, hwnd.invalid.Top, hwnd.invalid.Width, hwnd.invalid.Height, false);
1797 internal override void Exit() {
1798 GetMessageResult = false;
1801 internal override IntPtr GetActive() {
1806 IntPtr prop = IntPtr.Zero;
1807 IntPtr active = IntPtr.Zero;
1809 XGetWindowProperty(DisplayHandle, RootWindow, NetAtoms[(int)NA._NET_ACTIVE_WINDOW], 0, 1, false, Atom.XA_WINDOW, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
1810 if ((nitems > 0) && (prop != IntPtr.Zero)) {
1811 active = (IntPtr)Marshal.ReadInt32(prop);
1815 if (active != IntPtr.Zero) {
1818 hwnd = Hwnd.GetObjectFromWindow(active);
1820 active = hwnd.Handle;
1822 active = IntPtr.Zero;
1828 internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y) {
1829 throw new NotImplementedException ();
1832 internal override void GetDisplaySize(out Size size) {
1833 XWindowAttributes attributes=new XWindowAttributes();
1836 // FIXME - use _NET_WM messages instead?
1837 XGetWindowAttributes(DisplayHandle, XRootWindow(DisplayHandle, 0), ref attributes);
1840 size = new Size(attributes.width, attributes.height);
1843 internal override IntPtr GetParent(IntPtr handle) {
1846 hwnd = Hwnd.ObjectFromHandle(handle);
1847 if (hwnd != null && hwnd.parent != null) {
1848 return hwnd.parent.Handle;
1853 internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
1863 if (handle != IntPtr.Zero) {
1864 use_handle = Hwnd.ObjectFromHandle(handle).client_window;
1866 use_handle = RootWindow;
1870 XQueryPointer(DisplayHandle, use_handle, out root, out child, out root_x, out root_y, out win_x, out win_y, out keys_buttons);
1873 if (handle != IntPtr.Zero) {
1882 internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent) {
1883 return GetFontMetrics(g.GetHdc(), font.ToHfont(), out ascent, out descent);
1886 internal override Graphics GetMenuDC(IntPtr handle, IntPtr ncpaint_region) {
1889 hwnd = Hwnd.ObjectFromHandle(handle);
1891 return Graphics.FromHwnd(hwnd.whole_window);
1894 internal override Point GetMenuOrigin(IntPtr handle) {
1897 hwnd = Hwnd.ObjectFromHandle(handle);
1900 return hwnd.MenuOrigin;
1905 internal override bool GetMessage(ref MSG msg, IntPtr handle, int wFilterMin, int wFilterMax) {
1912 if (MessageQueue.Count > 0) {
1913 xevent = (XEvent) MessageQueue.Dequeue ();
1915 UpdateMessageQueue ();
1917 if (MessageQueue.Count > 0) {
1918 xevent = (XEvent) MessageQueue.Dequeue ();
1920 msg.hwnd= IntPtr.Zero;
1921 msg.message = Msg.WM_ENTERIDLE;
1926 // FIXME - handle filtering
1928 hwnd = Hwnd.GetObjectFromWindow(xevent.AnyEvent.window);
1930 // Handle messages for windows that are already destroyed
1933 Console.WriteLine("GetMessage(): Got message for non-existent window {0:X}", xevent.AnyEvent.window.ToInt32());
1935 goto ProcessNextMessage;
1938 if (hwnd.client_window == xevent.AnyEvent.window) {
1940 //Console.WriteLine("Client message, sending to window {0:X}", msg.hwnd.ToInt32());
1943 //Console.WriteLine("Non-Client message, sending to window {0:X}", msg.hwnd.ToInt32());
1946 msg.hwnd = hwnd.Handle;
1949 // If you add a new event to this switch make sure to add it in
1950 // UpdateMessage also unless it is not coming through the X event system.
1952 switch(xevent.type) {
1953 case XEventName.KeyPress: {
1954 Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
1958 case XEventName.KeyRelease: {
1959 Keyboard.KeyEvent (FocusWindow, xevent, ref msg);
1963 case XEventName.ButtonPress: {
1964 switch(xevent.ButtonEvent.button) {
1966 MouseState |= MouseButtons.Left;
1968 msg.message = Msg.WM_LBUTTONDOWN;
1970 msg.message = Msg.WM_NCLBUTTONDOWN;
1971 ClientToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
\r
1973 msg.wParam=GetMousewParam(0);
1978 MouseState |= MouseButtons.Middle;
1980 msg.message = Msg.WM_MBUTTONDOWN;
1982 msg.message = Msg.WM_NCMBUTTONDOWN;
1983 ClientToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
\r
1985 msg.wParam=GetMousewParam(0);
1990 MouseState |= MouseButtons.Right;
1992 msg.message = Msg.WM_RBUTTONDOWN;
1994 msg.message = Msg.WM_NCRBUTTONDOWN;
1995 ClientToScreen (msg.hwnd, ref xevent.ButtonEvent.x, ref xevent.ButtonEvent.y);
\r
1997 msg.wParam=GetMousewParam(0);
2002 msg.message=Msg.WM_MOUSEWHEEL;
2003 msg.wParam=GetMousewParam(120);
2008 msg.message=Msg.WM_MOUSEWHEEL;
2009 msg.wParam=GetMousewParam(-120);
2015 msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
2016 MousePosition.X = xevent.ButtonEvent.x;
2017 MousePosition.Y = xevent.ButtonEvent.y;
2019 if (!ClickPending.Pending) {
2020 ClickPending.Pending = true;
2021 ClickPending.Hwnd = msg.hwnd;
2022 ClickPending.Message = msg.message;
2023 ClickPending.wParam = msg.wParam;
2024 ClickPending.lParam = msg.lParam;
2025 ClickPending.Time = (long)xevent.ButtonEvent.time;
2027 if ((((long)xevent.ButtonEvent.time - ClickPending.Time) < DoubleClickInterval) && (msg.wParam == ClickPending.wParam) && (msg.lParam == ClickPending.lParam) && (msg.message == ClickPending.Message)) {
2028 // Looks like a genuine double click, clicked twice on the same spot with the same keys
2029 switch(xevent.ButtonEvent.button) {
2031 msg.message = client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK;
2036 msg.message = client ? Msg.WM_MBUTTONDBLCLK : Msg.WM_NCMBUTTONDBLCLK;
2041 msg.message = client ? Msg.WM_RBUTTONDBLCLK : Msg.WM_NCRBUTTONDBLCLK;
2046 ClickPending.Pending = false;
2052 case XEventName.ButtonRelease: {
2053 switch(xevent.ButtonEvent.button) {
2055 MouseState &= ~MouseButtons.Left;
2056 msg.message = client ? Msg.WM_LBUTTONUP : Msg.WM_NCLBUTTONUP;
2057 msg.wParam=GetMousewParam(0);
2062 MouseState &= ~MouseButtons.Middle;
2063 msg.message = client ? Msg.WM_MBUTTONUP : Msg.WM_NCMBUTTONUP;
2064 msg.wParam=GetMousewParam(0);
2069 MouseState &= ~MouseButtons.Right;
2070 msg.message = client ? Msg.WM_RBUTTONUP : Msg.WM_NCRBUTTONUP;
2071 msg.wParam=GetMousewParam(0);
2084 msg.lParam=(IntPtr) (xevent.ButtonEvent.y << 16 | xevent.ButtonEvent.x);
2085 MousePosition.X = xevent.ButtonEvent.x;
2086 MousePosition.Y = xevent.ButtonEvent.y;
2090 case XEventName.MotionNotify: {
2092 NativeWindow.WndProc(msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
2094 msg.message = Msg.WM_MOUSEMOVE;
2095 msg.wParam = GetMousewParam(0);
2096 msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x);
2098 HoverState.X = MousePosition.X = xevent.MotionEvent.x;
2099 HoverState.Y = MousePosition.Y = xevent.MotionEvent.y;
2103 msg.message = Msg.WM_NCHITTEST;
2104 msg.lParam = (IntPtr) (xevent.MotionEvent.y << 16 | xevent.MotionEvent.x);
2106 MousePosition.X = xevent.MotionEvent.x;
2107 MousePosition.Y = xevent.MotionEvent.y;
2113 case XEventName.EnterNotify: {
2114 if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
2117 msg.message = Msg.WM_MOUSE_ENTER;
2118 HoverState.Timer.Enabled = true;
2119 HoverState.Window = xevent.CrossingEvent.window;
2123 case XEventName.LeaveNotify: {
2124 if (xevent.CrossingEvent.mode != NotifyMode.NotifyNormal) {
2127 msg.message=Msg.WM_MOUSE_LEAVE;
2128 HoverState.Timer.Enabled = false;
2129 HoverState.Window = IntPtr.Zero;
2134 case XEventName.CreateNotify: {
2135 if (client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) {
2136 msg.message = WM_CREATE;
2137 // Set up CreateStruct
2139 goto ProcessNextMessage;
2145 case XEventName.ConfigureNotify: {
2146 if (!client && (xevent.ConfigureEvent.xevent == xevent.ConfigureEvent.window)) { // Ignore events for children (SubstructureNotify) and client areas
2147 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
2151 #if DriverDebugExtra
2152 Console.WriteLine("GetMessage(): Window {0:X} ConfigureNotify x={1} y={2} width={3} height={4}", hwnd.client_window.ToInt32(), xevent.ConfigureEvent.x, xevent.ConfigureEvent.y, xevent.ConfigureEvent.width, xevent.ConfigureEvent.height);
2154 msg.message = Msg.WM_WINDOWPOSCHANGED;
2155 hwnd.configure_pending = false;
2157 // We need to adjust our client window to track the resize of whole_window
2158 rect = hwnd.DefaultClientRect;
2160 ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
2161 ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));
2163 ncp.rgrc1.left = rect.Left;
2164 ncp.rgrc1.top = rect.Top;
2165 ncp.rgrc1.right = rect.Right;
2166 ncp.rgrc1.bottom = rect.Bottom;
2168 Marshal.StructureToPtr(ncp, ptr, true);
2169 NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
2170 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
2171 Marshal.FreeHGlobal(ptr);
2173 // FIXME - debug this with Menus, need to set hwnd.ClientRect
2175 rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
2177 XMoveResizeWindow(DisplayHandle, hwnd.client_window, rect.X, rect.Y, rect.Width, rect.Height);
2179 goto ProcessNextMessage;
2182 msg.lParam=IntPtr.Zero; // FIXME - Generate LPWINDOWPOS structure and pass on
2186 case XEventName.FocusIn: {
2187 msg.message=Msg.WM_SETFOCUS;
2188 msg.wParam=IntPtr.Zero;
2192 case XEventName.FocusOut: {
2193 msg.message=Msg.WM_KILLFOCUS;
2194 msg.wParam=IntPtr.Zero;
2198 case XEventName.Expose: {
2200 #if DriverDebugExtra
2201 Console.WriteLine("GetMessage(): Window {0:X} Exposed non-client area {1},{2} {3}x{4}", hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
2203 msg.message = Msg.WM_NCPAINT;
2204 hwnd.nc_expose_pending = false;
2207 #if DriverDebugExtra
2208 Console.WriteLine("GetMessage(): Window {0:X} Exposed area {1},{2} {3}x{4}", hwnd.client_window.ToInt32(), xevent.ExposeEvent.x, xevent.ExposeEvent.y, xevent.ExposeEvent.width, xevent.ExposeEvent.height);
2210 if (Caret.Visible == 1) {
2211 Caret.Paused = true;
2215 if (Caret.Visible == 1) {
2217 Caret.Paused = false;
2219 msg.message = Msg.WM_PAINT;
2223 case XEventName.DestroyNotify: {
2225 // This is a bit tricky, we don't receive our own DestroyNotify, we only get those for our children
2226 hwnd = Hwnd.ObjectFromHandle(xevent.DestroyWindowEvent.window);
2228 // We may get multiple for the same window, act only one the first (when Hwnd still knows about it)
2230 msg.hwnd = hwnd.client_window;
2231 msg.message=Msg.WM_DESTROY;
2235 Console.WriteLine("Got DestroyNotify on Window {0:X}", msg.hwnd.ToInt32());
2238 goto ProcessNextMessage;
2244 case XEventName.ClientMessage: {
2245 if (xevent.ClientMessageEvent.message_type == (IntPtr)AsyncAtom) {
2247 AsyncMethodData data;
2248 AsyncMethodResult result;
2251 gchandle = (GCHandle)xevent.ClientMessageEvent.ptr1;
2252 data = (AsyncMethodData)gchandle.Target;
2253 result = data.Result.Target as AsyncMethodResult;
2254 ret = data.Method.DynamicInvoke (data.Args);
2256 if (result != null) {
2257 result.Complete (ret);
2263 if (xevent.ClientMessageEvent.message_type == (IntPtr)HoverState.Atom) {
2264 msg.message = Msg.WM_MOUSEHOVER;
2265 msg.wParam = GetMousewParam(0);
2266 msg.lParam = (IntPtr) (xevent.ClientMessageEvent.ptr1);
2270 if (xevent.ClientMessageEvent.message_type == (IntPtr)PostAtom) {
2271 msg.hwnd = xevent.ClientMessageEvent.ptr1;
2272 msg.message = (Msg) xevent.ClientMessageEvent.ptr2.ToInt32 ();
2273 msg.wParam = xevent.ClientMessageEvent.ptr3;
2274 msg.lParam = xevent.ClientMessageEvent.ptr4;
2278 if (xevent.ClientMessageEvent.message_type == (IntPtr)NetAtoms[(int)NA.WM_PROTOCOLS]) {
2279 if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms[(int)NA.WM_DELETE_WINDOW]) {
2280 msg.message = Msg.WM_CLOSE;
2284 // We should not get this, but I'll leave the code in case we need it in the future
2285 if (xevent.ClientMessageEvent.ptr1 == (IntPtr)NetAtoms[(int)NA.WM_TAKE_FOCUS]) {
2286 goto ProcessNextMessage;
2292 case XEventName.TimerNotify: {
2293 xevent.TimerNotifyEvent.handler (this, EventArgs.Empty);
2298 goto ProcessNextMessage;
2302 return GetMessageResult;
2305 internal override bool GetText(IntPtr handle, out string text) {
2308 textptr = IntPtr.Zero;
2311 // FIXME - use _NET properties
2312 XFetchName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, ref textptr);
2314 if (textptr != IntPtr.Zero) {
2315 text = Marshal.PtrToStringAnsi(textptr);
2324 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) {
2328 hwnd = Hwnd.ObjectFromHandle(handle);
2331 rect = hwnd.ClientRect;
2336 height = hwnd.height;
2338 client_width = rect.Width;
2339 client_height = rect.Height;
2344 // Should we throw an exception or fail silently?
2345 // throw new ArgumentException("Called with an invalid window handle", "handle");
2355 internal override FormWindowState GetWindowState(IntPtr handle) {
2360 IntPtr prop = IntPtr.Zero;
2363 XWindowAttributes attributes;
2366 hwnd = Hwnd.ObjectFromHandle(handle);
2369 XGetWindowProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._NET_WM_STATE], 0, 256, false, Atom.XA_ATOM, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
2370 if ((nitems > 0) && (prop != IntPtr.Zero)) {
2371 for (int i = 0; i < nitems; i++) {
2372 atom = (IntPtr)Marshal.ReadInt32(prop, i * 4);
2373 if ((atom == (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ]) || (atom == (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT])) {
2380 if (maximized == 2) {
2381 return FormWindowState.Maximized;
2385 attributes = new XWindowAttributes();
2386 XGetWindowAttributes(DisplayHandle, handle, ref attributes);
2387 if (attributes.map_state == MapState.IsUnmapped) {
2388 return FormWindowState.Minimized;
2391 return FormWindowState.Normal;
2394 internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea) {
2396 GrabConfined = Grab.Confined;
2397 GrabArea = Grab.Area;
2400 internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle) {
2402 IntPtr confine_to_window;
2404 confine_to_window = IntPtr.Zero;
2406 if (confine_to_handle != IntPtr.Zero) {
2407 XWindowAttributes attributes = new XWindowAttributes();
2409 hwnd = Hwnd.ObjectFromHandle(confine_to_handle);
2412 XGetWindowAttributes(DisplayHandle, hwnd.client_window, ref attributes);
2414 Grab.Area.X = attributes.x;
2415 Grab.Area.Y = attributes.y;
2416 Grab.Area.Width = attributes.width;
2417 Grab.Area.Height = attributes.height;
2418 Grab.Confined = true;
2419 confine_to_window = hwnd.client_window;
2424 hwnd = Hwnd.ObjectFromHandle(handle);
2427 XGrabPointer(DisplayHandle, hwnd.client_window, false,
2428 EventMask.ButtonPressMask | EventMask.ButtonMotionMask |
2429 EventMask.ButtonReleaseMask | EventMask.PointerMotionMask,
2430 GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, confine_to_window, 0, 0);
2434 internal override void UngrabWindow(IntPtr hwnd) {
2436 XUngrabPointer(DisplayHandle, 0);
2438 Grab.Hwnd = IntPtr.Zero;
2439 Grab.Confined = false;
2442 internal override void HandleException(Exception e) {
2443 StackTrace st = new StackTrace(e, true);
2444 Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
2445 Console.WriteLine("{0}{1}", e.Message, st.ToString());
2448 internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear) {
2452 hwnd = Hwnd.ObjectFromHandle(handle);
2455 xevent = new XEvent ();
2456 xevent.type = XEventName.Expose;
2457 xevent.ExposeEvent.display = DisplayHandle;
2458 xevent.ExposeEvent.window = Hwnd.ObjectFromHandle(handle).client_window;
2461 hwnd.erase_pending = true;
2462 xevent.ExposeEvent.x = hwnd.X;
2463 xevent.ExposeEvent.y = hwnd.Y;
2464 xevent.ExposeEvent.width = hwnd.Width;
2465 xevent.ExposeEvent.height = hwnd.Height;
2467 xevent.ExposeEvent.x = rc.X;
2468 xevent.ExposeEvent.y = rc.Y;
2469 xevent.ExposeEvent.width = rc.Width;
2470 xevent.ExposeEvent.height = rc.Height;
2476 internal override bool IsVisible(IntPtr handle) {
2477 return Hwnd.ObjectFromHandle(handle).visible;
2480 internal override void KillTimer(Timer timer) {
2482 TimerList.Remove(timer);
2486 internal override void MenuToScreen(IntPtr handle, ref int x, ref int y) {
2492 hwnd = Hwnd.ObjectFromHandle(handle);
2495 XTranslateCoordinates(DisplayHandle, hwnd.whole_window, RootWindow, x, y, out dest_x_return, out dest_y_return, out child);
2502 internal override void OverrideCursor(IntPtr cursor) {
2503 OverrideCursorHandle = cursor;
2506 internal override PaintEventArgs PaintEventStart(IntPtr handle) {
2507 PaintEventArgs paint_event;
2510 hwnd = Hwnd.ObjectFromHandle(handle);
2512 if (Caret.Visible == 1) {
2513 Caret.Paused = true;
2517 if (hwnd.erase_pending) {
2518 // In our implementation WM_ERASEBKGND always returns 1; otherwise we'd check the result and only call clear if it returned 0
2519 NativeWindow.WndProc(hwnd.client_window, Msg.WM_ERASEBKGND, IntPtr.Zero, IntPtr.Zero);
2520 hwnd.erase_pending = false;
2524 hwnd.client_dc = Graphics.FromHwnd (hwnd.client_window);
2525 paint_event = new PaintEventArgs(hwnd.client_dc, hwnd.invalid);
2530 internal override void PaintEventEnd(IntPtr handle) {
2533 hwnd = Hwnd.ObjectFromHandle(handle);
2535 hwnd.ClearInvalidArea();
2537 hwnd.client_dc.Flush();
2538 hwnd.client_dc.Dispose();
2539 hwnd.client_dc = null;
2541 if (Caret.Visible == 1) {
2543 Caret.Paused = false;
2547 internal override bool PeekMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
2550 // FIXME - imlement filtering
2552 if ((flags & (uint)PeekMessageFlags.PM_REMOVE) == 0) {
2553 throw new NotImplementedException("PeekMessage PM_NOREMOVE is not implemented yet"); // FIXME - Implement PM_NOREMOVE flag
2557 if (MessageQueue.Count > 0) {
2560 // Only call UpdateMessageQueue if real events are pending
2561 // otherwise we go to sleep on the socket
2562 if (XPending(DisplayHandle) != 0) {
2563 UpdateMessageQueue();
2570 return GetMessage(ref msg, hWnd, wFilterMin, wFilterMax);
2573 internal static void PostMessage (IntPtr handle, Msg message, IntPtr wparam, IntPtr lparam) {
2574 XEvent xevent = new XEvent ();
2576 xevent.type = XEventName.ClientMessage;
2577 xevent.ClientMessageEvent.display = DisplayHandle;
2578 xevent.ClientMessageEvent.window = Hwnd.ObjectFromHandle(handle).whole_window;
2579 xevent.ClientMessageEvent.message_type = (IntPtr) PostAtom;
2580 xevent.ClientMessageEvent.format = 32;
2581 xevent.ClientMessageEvent.ptr1 = handle;
2582 xevent.ClientMessageEvent.ptr2 = (IntPtr) message;
2583 xevent.ClientMessageEvent.ptr3 = wparam;
2584 xevent.ClientMessageEvent.ptr4 = lparam;
2586 MessageQueue.Enqueue (xevent);
2589 internal override void ReleaseMenuDC(IntPtr handle, Graphics dc) {
2593 internal override void ScreenToClient(IntPtr handle, ref int x, ref int y) {
2599 hwnd = Hwnd.ObjectFromHandle(handle);
2602 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.client_window, x, y, out dest_x_return, out dest_y_return, out child);
2609 internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y) {
2615 hwnd = Hwnd.ObjectFromHandle(handle);
2618 XTranslateCoordinates (DisplayHandle, RootWindow, hwnd.client_window, x, y, out dest_x_return, out dest_y_return, out child);
2625 internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children) {
2628 XGCValues gc_values;
2630 hwnd = Hwnd.ObjectFromHandle(handle);
2632 if (hwnd.invalid != Rectangle.Empty) {
2633 // BIG FAT WARNING. This only works with how we use this function right now
2634 // where we basically still scroll the whole window, but work around areas
2635 // that are covered by our children
2637 hwnd.invalid.X += XAmount;
2638 hwnd.invalid.Y += YAmount;
2640 if (hwnd.invalid.X < 0) {
2641 hwnd.invalid.Width += hwnd.invalid.X;
2645 if (hwnd.invalid.Y < 0) {
2646 hwnd.invalid.Height += hwnd.invalid.Y;
2651 gc_values = new XGCValues();
2653 if (with_children) {
2654 gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
2657 gc = XCreateGC(DisplayHandle, hwnd.client_window, 0, ref gc_values);
2659 XCopyArea(DisplayHandle, hwnd.client_window, hwnd.client_window, gc, area.X - XAmount, area.Y - YAmount, area.Width, area.Height, area.X, area.Y);
2661 // Generate an expose for the area exposed by the horizontal scroll
2663 hwnd.AddInvalidArea (area.X, area.Y, XAmount, area.Height);
2664 } else if (XAmount < 0) {
2665 hwnd.AddInvalidArea (XAmount + area.X + area.Width, area.Y, -XAmount, area.Height);
2668 // Generate an expose for the area exposed by the vertical scroll
2670 hwnd.AddInvalidArea (area.X, area.Y, area.Width, YAmount);
2671 } else if (YAmount < 0) {
2672 hwnd.AddInvalidArea (area.X, YAmount + area.Y + area.Height, area.Width, -YAmount);
2674 XFreeGC(DisplayHandle, gc);
2676 UpdateWindow(handle);
2679 internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool with_children) {
2682 hwnd = Hwnd.GetObjectFromWindow(handle);
2684 ScrollWindow(handle, hwnd.ClientRect, XAmount, YAmount, with_children);
2687 internal override void SendAsyncMethod (AsyncMethodData method) {
2688 XEvent xevent = new XEvent ();
2690 xevent.type = XEventName.ClientMessage;
2691 xevent.ClientMessageEvent.display = DisplayHandle;
2692 xevent.ClientMessageEvent.window = IntPtr.Zero;
2693 xevent.ClientMessageEvent.message_type = (IntPtr)AsyncAtom;
2694 xevent.ClientMessageEvent.format = 32;
2695 xevent.ClientMessageEvent.ptr1 = (IntPtr) GCHandle.Alloc (method);
2697 MessageQueue.EnqueueLocked (xevent);
2702 internal override void SetBorderStyle(IntPtr handle, BorderStyle border_style) {
2705 hwnd = Hwnd.ObjectFromHandle(handle);
2706 hwnd.border_style = border_style;
2708 // FIXME - do we need to trigger some resize?
2711 internal override void SetCaretPos(IntPtr handle, int x, int y) {
2712 if (Caret.Hwnd == handle) {
2719 if (Caret.Visible == 1) {
2721 Caret.Timer.Start();
2726 internal override void SetCursor(IntPtr handle, IntPtr cursor) {
2729 if (OverrideCursorHandle == IntPtr.Zero) {
2730 if ((LastCursorWindow == handle) && (LastCursorHandle == cursor)) {
2734 LastCursorHandle = cursor;
2735 LastCursorWindow = handle;
2737 hwnd = Hwnd.ObjectFromHandle(handle);
2739 if (cursor != IntPtr.Zero) {
2740 XDefineCursor(DisplayHandle, hwnd.whole_window, cursor);
2742 XUndefineCursor(DisplayHandle, hwnd.whole_window);
2748 hwnd = Hwnd.ObjectFromHandle(handle);
2750 XDefineCursor(DisplayHandle, hwnd.whole_window, OverrideCursorHandle);
2754 internal override void SetCursorPos(IntPtr handle, int x, int y) {
2755 if (handle == IntPtr.Zero) {
2757 XWarpPointer(DisplayHandle, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x, y);
2763 hwnd = Hwnd.ObjectFromHandle(handle);
2765 XWarpPointer(DisplayHandle, IntPtr.Zero, hwnd.client_window, 0, 0, 0, 0, x, y);
2771 internal override void SetFocus(IntPtr handle) {
2774 hwnd = Hwnd.ObjectFromHandle(handle);
2776 if (FocusWindow != IntPtr.Zero) {
2777 PostMessage(FocusWindow, Msg.WM_KILLFOCUS, hwnd.client_window, IntPtr.Zero);
2779 PostMessage(hwnd.client_window, Msg.WM_SETFOCUS, FocusWindow, IntPtr.Zero);
2780 FocusWindow = hwnd.client_window;
2782 //XSetInputFocus(DisplayHandle, Hwnd.ObjectFromHandle(handle).client_window, RevertTo.None, IntPtr.Zero);
2785 internal override void SetIcon(IntPtr handle, Icon icon) {
2788 hwnd = Hwnd.ObjectFromHandle(handle);
2790 SetIcon(hwnd, icon);
2794 internal override void SetMenu(IntPtr handle, IntPtr menu_handle) {
2797 hwnd = Hwnd.ObjectFromHandle(handle);
2798 hwnd.menu_handle = menu_handle;
2800 // FIXME - do we need to trigger some resize?
2803 internal override void SetModal(IntPtr handle, bool Modal) {
2805 ModalWindows.Push(handle);
2807 if (ModalWindows.Contains(handle)) {
2810 if (ModalWindows.Count > 0) {
2811 Activate((IntPtr)ModalWindows.Peek());
2816 internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
2819 hwnd = Hwnd.ObjectFromHandle(handle);
2820 hwnd.parent = Hwnd.ObjectFromHandle(parent);
2824 Console.WriteLine("Parent for window {0:X} / {1:X} = {2:X} (Handle:{3:X})", hwnd.ClientWindow.ToInt32(), hwnd.WholeWindow.ToInt32(), hwnd.parent != null ? hwnd.parent.Handle.ToInt32() : 0, parent.ToInt32());
2826 XReparentWindow(DisplayHandle, hwnd.whole_window, hwnd.parent.client_window, hwnd.x, hwnd.y);
2832 internal override void SetTimer (Timer timer) {
2834 TimerList.Add(timer);
2839 internal override bool SetTopmost(IntPtr handle, IntPtr handle_owner, bool enabled) {
2843 hwnd = Hwnd.ObjectFromHandle(handle);
2845 if (handle_owner != IntPtr.Zero) {
2846 hwnd_owner = Hwnd.ObjectFromHandle(handle_owner);
2853 if (hwnd_owner != null) {
2854 XSetTransientForHint(DisplayHandle, hwnd.whole_window, hwnd_owner.whole_window);
2856 XSetTransientForHint(DisplayHandle, hwnd.whole_window, FosterParent);
2861 XDeleteProperty(DisplayHandle, hwnd.whole_window, (int)Atom.XA_WM_TRANSIENT_FOR);
2867 internal override bool SetVisible(IntPtr handle, bool visible) {
2870 hwnd = Hwnd.ObjectFromHandle(handle);
2871 hwnd.visible = visible;
2875 XMapWindow(DisplayHandle, hwnd.whole_window);
2876 XMapWindow(DisplayHandle, hwnd.client_window);
2878 XUnmapWindow(DisplayHandle, hwnd.whole_window);
2884 internal override void SetWindowBackground(IntPtr handle, Color color) {
2888 hwnd = Hwnd.ObjectFromHandle(handle);
2889 xcolor = new XColor();
2891 xcolor.red = (ushort)(color.R * 257);
2892 xcolor.green = (ushort)(color.G * 257);
2893 xcolor.blue = (ushort)(color.B * 257);
2896 XAllocColor(DisplayHandle, DefaultColormap, ref xcolor);
2897 XSetWindowBackground(DisplayHandle, hwnd.client_window, xcolor.pixel);
2898 XClearWindow(DisplayHandle, hwnd.client_window);
2902 internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height) {
2904 Rectangle client_rect;
2906 hwnd = Hwnd.ObjectFromHandle(handle);
2907 // Save a server roundtrip (and prevent a feedback loop)
2908 if ((hwnd.x == x) && (hwnd.y == y) && (hwnd.width == width) && (hwnd.height == height)) {
2912 // X requires a sanity check for width & height; otherwise it dies
2921 client_rect = Hwnd.GetClientRectangle(hwnd.border_style, hwnd.menu_handle, hwnd.title_style, width, height);
2924 XMoveResizeWindow(DisplayHandle, hwnd.whole_window, x, y, width, height);
2925 XMoveResizeWindow(DisplayHandle, hwnd.client_window, client_rect.X, client_rect.Y, client_rect.Width, client_rect.Height);
2928 // Prevent an old queued ConfigureNotify from setting our width with outdated data, set it now
2930 hwnd.height = height;
2933 internal override void SetWindowState(IntPtr handle, FormWindowState state) {
2934 FormWindowState current_state;
2937 hwnd = Hwnd.ObjectFromHandle(handle);
2939 current_state = GetWindowState(handle);
2941 if (current_state == state) {
2946 case FormWindowState.Normal: {
2948 if (current_state == FormWindowState.Minimized) {
2949 XMapWindow(DisplayHandle, hwnd.whole_window);
2950 XMapWindow(DisplayHandle, hwnd.client_window);
2951 } else if (current_state == FormWindowState.Maximized) {
2952 SendNetWMMessage(hwnd.whole_window, (IntPtr)(uint)NetAtoms[(int)NA._NET_WM_STATE], (IntPtr)2 /* toggle */, (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
2959 case FormWindowState.Minimized: {
2961 if (current_state == FormWindowState.Maximized) {
2962 SendNetWMMessage(hwnd.whole_window, (IntPtr)NetAtoms[(int)NA._NET_WM_STATE], (IntPtr)2 /* toggle */, (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
2964 XIconifyWindow(DisplayHandle, hwnd.whole_window, 0);
2969 case FormWindowState.Maximized: {
2971 if (current_state == FormWindowState.Minimized) {
2972 XMapWindow(DisplayHandle, hwnd.whole_window);
2973 XMapWindow(DisplayHandle, hwnd.client_window);
2976 SendNetWMMessage(hwnd.whole_window, (IntPtr)NetAtoms[(int)NA._NET_WM_STATE], (IntPtr)1 /* Add */, (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_HORZ], (IntPtr)NetAtoms[(int)NA._NET_WM_STATE_MAXIMIZED_VERT]);
2984 internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
2987 hwnd = Hwnd.ObjectFromHandle(handle);
2988 SetHwndStyles(hwnd, cp);
2989 SetWMStyles(hwnd, cp);
2991 internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool top, bool bottom) {
2995 hwnd = Hwnd.ObjectFromHandle(handle);
2996 if (after_handle != IntPtr.Zero) {
2997 after_hwnd = Hwnd.ObjectFromHandle(after_handle);
3004 XRaiseWindow(DisplayHandle, hwnd.whole_window);
3007 } else if (!bottom) {
3008 XWindowChanges values = new XWindowChanges();
3010 if (after_hwnd == null) {
3011 throw new ArgumentNullException("after_handle", "Need sibling to adjust z-order");
3013 values.sibling = after_hwnd.whole_window;
3014 values.stack_mode = StackMode.Below;
3017 XConfigureWindow(DisplayHandle, hwnd.whole_window, ChangeWindowFlags.CWStackMode | ChangeWindowFlags.CWSibling, ref values);
3022 XLowerWindow(DisplayHandle, hwnd.whole_window);
3029 internal override void ShowCursor(bool show) {
3030 ; // FIXME - X11 doesn't 'hide' the cursor. we could create an empty cursor
3033 internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt) {
3034 GetSystrayManagerWindow();
3036 if (SystrayMgrWindow != IntPtr.Zero) {
3038 XSizeHints size_hints;
3041 hwnd = Hwnd.ObjectFromHandle(handle);
3043 size_hints = new XSizeHints();
3045 size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize);
3046 size_hints.min_width = icon.Width;
3047 size_hints.min_height = icon.Height;
3049 size_hints.max_width = icon.Width;
3050 size_hints.max_height = icon.Height;
3052 size_hints.base_width = icon.Width;
3053 size_hints.base_height = icon.Height;
3054 XSetWMNormalHints(DisplayHandle, hwnd.whole_window, ref size_hints);
3056 atoms = new uint[2];
3057 atoms[0] = 1; // Version 1
3058 atoms[1] = 1; // We're not mapped
3060 // This line cost me 3 days...
3061 XChangeProperty(DisplayHandle, hwnd.whole_window, NetAtoms[(int)NA._XEMBED_INFO], NetAtoms[(int)NA._XEMBED_INFO], 32, PropertyMode.Replace, atoms, 2);
3063 // Need to pick some reasonable defaults
3065 tt.AutomaticDelay = 100;
3066 tt.InitialDelay = 250;
3067 tt.ReshowDelay = 250;
3068 tt.ShowAlways = true;
3070 if ((tip != null) && (tip != string.Empty)) {
3071 tt.SetToolTip(Control.FromHandle(handle), tip);
3077 // Make sure the window exists
3078 XSync(DisplayHandle, hwnd.whole_window);
3080 SendNetClientMessage(SystrayMgrWindow, (IntPtr)NetAtoms[(int)NA._NET_SYSTEM_TRAY_OPCODE], IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);
3087 internal override bool SystrayChange(IntPtr handle, string tip, Icon icon, ref ToolTip tt) {
3090 control = Control.FromHandle(handle);
3091 if (control != null && tt != null) {
3092 tt.SetToolTip(control, tip);
3100 internal override void SystrayRemove(IntPtr handle, ref ToolTip tt) {
3103 hwnd = Hwnd.ObjectFromHandle(handle);
3105 XUnmapWindow(DisplayHandle, hwnd.whole_window);
3106 SetParent(hwnd.whole_window, FosterParent);
3108 // The caller can now re-dock it later...
3115 internal override bool Text(IntPtr handle, string text) {
3117 // FIXME - use _NET properties
3118 XStoreName(DisplayHandle, Hwnd.ObjectFromHandle(handle).whole_window, text);
3123 internal override bool TranslateMessage(ref MSG msg) {
3124 return Keyboard.TranslateMessage (ref msg);
3127 internal override void UpdateWindow(IntPtr handle) {
3131 hwnd = Hwnd.ObjectFromHandle(handle);
3133 if (!hwnd.visible || hwnd.expose_pending) {
3137 xevent = new XEvent();
3138 xevent.type = XEventName.Expose;
3139 xevent.ExposeEvent.display = DisplayHandle;
3140 xevent.ExposeEvent.window = hwnd.client_window;
3142 MessageQueue.Enqueue(xevent);
3143 hwnd.expose_pending = true;
3145 #endregion // Public Static Methods
3148 internal override event EventHandler Idle;
3149 #endregion // Events
3152 [DllImport ("libX11", EntryPoint="XOpenDisplay")]
3153 internal extern static IntPtr XOpenDisplay(IntPtr display);
3154 [DllImport ("libX11", EntryPoint="XCloseDisplay")]
3155 internal extern static int XCloseDisplay(IntPtr display);
3156 [DllImport ("libX11", EntryPoint="XSynchronize")]
3157 internal extern static IntPtr XSynchronize(IntPtr display, bool onoff);
3159 [DllImport ("libX11", EntryPoint="XCreateWindow")]
3160 internal extern static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, SetWindowValuemask valuemask, ref XSetWindowAttributes attributes);
3161 [DllImport ("libX11", EntryPoint="XCreateSimpleWindow")]
3162 internal extern static IntPtr XCreateSimpleWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int border, int background);
3163 [DllImport ("libX11", EntryPoint="XMapWindow")]
3164 internal extern static int XMapWindow(IntPtr display, IntPtr window);
3165 [DllImport ("libX11", EntryPoint="XUnmapWindow")]
3166 internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
3167 [DllImport ("libX11", EntryPoint="XMapSubwindows")]
3168 internal extern static int XMapSubindows(IntPtr display, IntPtr window);
3169 [DllImport ("libX11", EntryPoint="XUnmapSubwindows")]
3170 internal extern static int XUnmapSubwindows(IntPtr display, IntPtr window);
3171 [DllImport ("libX11", EntryPoint="XRootWindow")]
3172 internal extern static IntPtr XRootWindow(IntPtr display, int screen_number);
3173 [DllImport ("libX11", EntryPoint="XNextEvent")]
3174 internal extern static IntPtr XNextEvent(IntPtr display, ref XEvent xevent);
3175 [DllImport ("libX11")]
3176 internal extern static int XConnectionNumber (IntPtr diplay);
3177 [DllImport ("libX11")]
3178 internal extern static int XPending (IntPtr diplay);
3179 [DllImport ("libX11")]
3180 internal extern static bool XCheckWindowEvent (IntPtr display, IntPtr window, EventMask mask, ref XEvent xevent);
3181 [DllImport ("libX11")]
3182 internal extern static bool XCheckMaskEvent (IntPtr display, EventMask mask, ref XEvent xevent);
3183 [DllImport ("libX11", EntryPoint="XSelectInput")]
3184 internal extern static IntPtr XSelectInput(IntPtr display, IntPtr window, EventMask mask);
3186 [DllImport ("libX11", EntryPoint="XDestroyWindow")]
3187 internal extern static int XDestroyWindow(IntPtr display, IntPtr window);
3189 [DllImport ("libX11", EntryPoint="XReparentWindow")]
3190 internal extern static int XReparentWindow(IntPtr display, IntPtr window, IntPtr parent, int x, int y);
3191 [DllImport ("libX11", EntryPoint="XMoveResizeWindow")]
3192 internal extern static int XMoveResizeWindow(IntPtr display, IntPtr window, int x, int y, int width, int height);
3194 [DllImport ("libX11", EntryPoint="XResizeWindow")]
3195 internal extern static int XResizeWindow(IntPtr display, IntPtr window, int width, int height);
3197 [DllImport ("libX11", EntryPoint="XGetWindowAttributes")]
3198 internal extern static int XGetWindowAttributes(IntPtr display, IntPtr window, ref XWindowAttributes attributes);
3200 [DllImport ("libX11", EntryPoint="XFlush")]
3201 internal extern static int XFlush(IntPtr display);
3203 [DllImport ("libX11", EntryPoint="XSetWMName")]
3204 internal extern static int XSetWMName(IntPtr display, IntPtr window, ref XTextProperty text_prop);
3206 [DllImport ("libX11", EntryPoint="XStoreName")]
3207 internal extern static int XStoreName(IntPtr display, IntPtr window, string window_name);
3209 [DllImport ("libX11", EntryPoint="XFetchName")]
3210 internal extern static int XFetchName(IntPtr display, IntPtr window, ref IntPtr window_name);
3212 [DllImport ("libX11", EntryPoint="XSendEvent")]
3213 internal extern static int XSendEvent(IntPtr display, IntPtr window, bool propagate, EventMask event_mask, ref XEvent send_event);
3215 [DllImport ("libX11", EntryPoint="XQueryTree")]
3216 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);
3218 [DllImport ("libX11", EntryPoint="XFree")]
3219 internal extern static int XFree(IntPtr data);
3221 [DllImport ("libX11", EntryPoint="XRaiseWindow")]
3222 internal extern static int XRaiseWindow(IntPtr display, IntPtr window);
3224 [DllImport ("libX11", EntryPoint="XLowerWindow")]
3225 internal extern static uint XLowerWindow(IntPtr display, IntPtr window);
3227 [DllImport ("libX11", EntryPoint="XConfigureWindow")]
3228 internal extern static uint XConfigureWindow(IntPtr display, IntPtr window, ChangeWindowFlags value_mask, ref XWindowChanges values);
3230 [DllImport ("libX11", EntryPoint="XInternAtom")]
3231 internal extern static int XInternAtom(IntPtr display, string atom_name, bool only_if_exists);
3233 [DllImport ("libX11", EntryPoint="XSetWMProtocols")]
3234 internal extern static int XSetWMProtocols(IntPtr display, IntPtr window, uint[] protocols, int count);
3236 [DllImport ("libX11", EntryPoint="XGrabPointer")]
3237 internal extern static int XGrabPointer(IntPtr display, IntPtr window, bool owner_events, EventMask event_mask, GrabMode pointer_mode, GrabMode keyboard_mode, IntPtr confine_to, uint cursor, uint timestamp);
3239 [DllImport ("libX11", EntryPoint="XUngrabPointer")]
3240 internal extern static int XUngrabPointer(IntPtr display, uint timestamp);
3242 [DllImport ("libX11", EntryPoint="XQueryPointer")]
3243 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);
3245 [DllImport ("libX11", EntryPoint="XTranslateCoordinates")]
3246 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);
3248 [DllImport ("libX11", EntryPoint="XGetGeometry")]
3249 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);
3251 [DllImport ("libX11", EntryPoint="XGetGeometry")]
3252 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);
3254 [DllImport ("libX11", EntryPoint="XGetGeometry")]
3255 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);
3257 [DllImport ("libX11", EntryPoint="XGetGeometry")]
3258 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);
3260 [DllImport ("libX11", EntryPoint="XWarpPointer")]
3261 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);
3263 [DllImport ("libX11", EntryPoint="XClearWindow")]
3264 internal extern static int XClearWindow(IntPtr display, IntPtr window);
3266 [DllImport ("libX11", EntryPoint="XClearArea")]
3267 internal extern static int XClearArea(IntPtr display, IntPtr window, int x, int y, int width, int height, bool exposures);
3270 [DllImport ("libX11", EntryPoint="XDefaultScreenOfDisplay")]
3271 internal extern static IntPtr XDefaultScreenOfDisplay(IntPtr display);
3273 [DllImport ("libX11", EntryPoint="XScreenNumberOfScreen")]
3274 internal extern static int XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
3276 [DllImport ("libX11", EntryPoint="XDefaultVisual")]
3277 internal extern static IntPtr XDefaultVisual(IntPtr display, int screen_number);
3279 [DllImport ("libX11", EntryPoint="XDefaultDepth")]
3280 internal extern static uint XDefaultDepth(IntPtr display, int screen_number);
3282 [DllImport ("libX11", EntryPoint="XDefaultColormap")]
3283 internal extern static IntPtr XDefaultColormap(IntPtr display, int screen_number);
3285 [DllImport ("libX11", EntryPoint="XLookupColor")]
3286 internal extern static int XLookupColor(IntPtr display, IntPtr Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
3288 [DllImport ("libX11", EntryPoint="XAllocColor")]
3289 internal extern static int XAllocColor(IntPtr display, IntPtr Colormap, ref XColor colorcell_def);
3291 [DllImport ("libX11", EntryPoint="XSetTransientForHint")]
3292 internal extern static int XSetTransientForHint(IntPtr display, IntPtr window, IntPtr prop_window);
3294 [DllImport ("libX11", EntryPoint="XChangeProperty")]
3295 internal extern static int XChangeProperty(IntPtr display, IntPtr window, int property, int type, int format, PropertyMode mode, ref MotifWmHints data, int nelements);
3297 [DllImport ("libX11", EntryPoint="XChangeProperty")]
3298 internal extern static int XChangeProperty(IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode mode, uint[] atoms, int nelements);
3300 [DllImport ("libX11", EntryPoint="XChangeProperty")]
3301 internal extern static int XChangeProperty(IntPtr display, IntPtr window, int property, int format, int type, PropertyMode mode, uint[] atoms, int nelements);
3303 [DllImport ("libX11", EntryPoint="XChangeProperty")]
3304 internal extern static int XChangeProperty(IntPtr display, IntPtr window, int property, int format, int type, PropertyMode mode, IntPtr atoms, int nelements);
3306 [DllImport ("libX11", EntryPoint="XChangeProperty")]
3307 internal extern static int XChangeProperty(IntPtr display, IntPtr window, int property, Atom format, int type, PropertyMode mode, IntPtr atoms, int nelements);
3309 [DllImport ("libX11", EntryPoint="XDeleteProperty")]
3310 internal extern static int XDeleteProperty(IntPtr display, IntPtr window, int property);
3312 [DllImport ("gdiplus", EntryPoint="GetFontMetrics")]
3313 internal extern static bool GetFontMetrics(IntPtr graphicsObject, IntPtr nativeObject, out int ascent, out int descent);
3316 [DllImport ("libX11", EntryPoint="XCreateGC")]
3317 internal extern static IntPtr XCreateGC(IntPtr display, IntPtr window, GCFunction valuemask, ref XGCValues values);
3319 [DllImport ("libX11", EntryPoint="XFreeGC")]
3320 internal extern static int XFreeGC(IntPtr display, IntPtr gc);
3322 [DllImport ("libX11", EntryPoint="XSetFunction")]
3323 internal extern static int XSetFunction(IntPtr display, IntPtr gc, GXFunction function);
3325 [DllImport ("libX11", EntryPoint="XDrawLine")]
3326 internal extern static int XDrawLine(IntPtr display, IntPtr drawable, IntPtr gc, int x1, int y1, int x2, int y2);
3328 [DllImport ("libX11", EntryPoint="XSetWindowBackground")]
3329 internal extern static int XSetWindowBackground(IntPtr display, IntPtr window, IntPtr background);
3331 [DllImport ("libX11", EntryPoint="XCopyArea")]
3332 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);
3334 [DllImport ("libX11", EntryPoint="XGetAtomName")]
3335 internal extern static string XGetAtomName(IntPtr display, int atom);
3337 [DllImport ("libX11", EntryPoint="XGetWindowProperty")]
3338 internal extern static int XGetWindowProperty(IntPtr display, IntPtr window, int atom, int long_offset, int long_length, bool delete, Atom req_type, out Atom actual_type, out int actual_format, out int nitems, out int bytes_after, ref IntPtr prop);
3340 [DllImport ("libX11", EntryPoint="XSetInputFocus")]
3341 internal extern static int XSetInputFocus(IntPtr display, IntPtr window, RevertTo revert_to, IntPtr time);
3343 [DllImport ("libX11", EntryPoint="XIconifyWindow")]
3344 internal extern static int XIconifyWindow(IntPtr display, IntPtr window, int screen_number);
3346 [DllImport ("libX11", EntryPoint="XDefineCursor")]
3347 internal extern static int XDefineCursor(IntPtr display, IntPtr window, IntPtr cursor);
3349 [DllImport ("libX11", EntryPoint="XUndefineCursor")]
3350 internal extern static int XUndefineCursor(IntPtr display, IntPtr window);
3352 [DllImport ("libX11", EntryPoint="XFreeCursor")]
3353 internal extern static int XFreeCursor(IntPtr display, IntPtr cursor);
3355 [DllImport ("libX11", EntryPoint="XCreateFontCursor")]
3356 internal extern static IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape);
3358 [DllImport ("libX11", EntryPoint="XCreatePixmapCursor")]
3359 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);
3361 [DllImport ("libX11", EntryPoint="XCreatePixmapFromBitmapData")]
3362 internal extern static IntPtr XCreatePixmapFromBitmapData(IntPtr display, IntPtr drawable, byte[] data, int width, int height, IntPtr fg, IntPtr bg, int depth);
3364 [DllImport ("libX11", EntryPoint="XFreePixmap")]
3365 internal extern static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap);
3367 [DllImport ("libX11", EntryPoint="XQueryBestCursor")]
3368 internal extern static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
3370 [DllImport ("libX11", EntryPoint="XWhitePixel")]
3371 internal extern static IntPtr XWhitePixel(IntPtr display, int screen_no);
3373 [DllImport ("libX11", EntryPoint="XBlackPixel")]
3374 internal extern static IntPtr XBlackPixel(IntPtr display, int screen_no);
3376 [DllImport ("libX11", EntryPoint="XGrabServer")]
3377 internal extern static void XGrabServer(IntPtr display);
3379 [DllImport ("libX11", EntryPoint="XUngrabServer")]
3380 internal extern static void XUngrabServer(IntPtr display);
3382 [DllImport ("libX11", EntryPoint="XGetSelectionOwner")]
3383 internal extern static IntPtr XGetSelectionOwner(IntPtr display, IntPtr selection);
3385 [DllImport ("libX11", EntryPoint="XSetWMNormalHints")]
3386 internal extern static void XSetWMNormalHints(IntPtr display, IntPtr window, ref XSizeHints hints);
3388 [DllImport ("libX11", EntryPoint="XSetWMHints")]
3389 internal extern static void XSetWMHints(IntPtr display, IntPtr window, ref XWMHints wmhints);
3391 [DllImport ("libX11", EntryPoint="XSync")]
3392 internal extern static void XSync(IntPtr display, IntPtr window);
3394 [DllImport ("libX11", EntryPoint="XGetIconSizes")]
3395 internal extern static int XGetIconSizes(IntPtr display, IntPtr window, out IntPtr size_list, out int count);
3397 [DllImport ("libX11", EntryPoint="XSetErrorHandler")]
3398 internal extern static IntPtr XSetErrorHandler(XErrorHandler error_handler);
3400 [DllImport ("libX11", EntryPoint="XGetErrorText")]
3401 internal extern static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
3403 [DllImport ("libX11", EntryPoint="XInitThreads")]
\r
3404 internal extern static int XInitThreads();
\r