- Added code to destroy the X window
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / XplatUIX11.cs
index 119e004150b42cad674b685ba250ea598730947c..c1197f4cac3d75982ef8f0c4623401e4d398b361 100644 (file)
@@ -50,6 +50,7 @@ namespace System.Windows.Forms {
                private static bool             themes_enabled;
 
                private static IntPtr           DisplayHandle;          // X11 handle to display
+               private static int              screen_num;             // Screen number used
                private static IntPtr           root_window;            // Handle of the root window for the screen/display
                private static IntPtr           FosterParent;           // Container to hold child windows until their parent exists
                private static int              wm_protocols;           // X Atom
@@ -199,6 +200,8 @@ namespace System.Windows.Forms {
 
                internal static void SetDisplay(IntPtr display_handle) {
                        if (display_handle != IntPtr.Zero) {
+                               IntPtr  Screen;
+
                                if (FosterParent != IntPtr.Zero) {
                                        XDestroyWindow(DisplayHandle, FosterParent);
                                }
@@ -208,19 +211,25 @@ namespace System.Windows.Forms {
 
                                DisplayHandle=display_handle;
 
+                               // We need to tell System.Drawing our DisplayHandle. FromHdcInternal has
+                               // been hacked to do this for us.
+                               Graphics.FromHdcInternal (DisplayHandle);
+
                                // Create a few things
                                key_state = Keys.None;
                                mouse_state = MouseButtons.None;
                                mouse_position = Point.Empty;
-                               root_window = XRootWindow(display_handle, 0);
-                               default_colormap = XDefaultColormap(display_handle, 0);
+                               Screen = XDefaultScreenOfDisplay(DisplayHandle);
+                               //screen_num = XScreenNumberOfScreen(DisplayHandle, Screen);
+                               screen_num = 0;
+                               root_window = XRootWindow(display_handle, screen_num);
+                               default_colormap = XDefaultColormap(display_handle, screen_num);
 
                                // Create the foster parent
                                FosterParent=XCreateSimpleWindow(display_handle, root_window, 0, 0, 1, 1, 4, 0, 0);
                                if (FosterParent==IntPtr.Zero) {
                                        Console.WriteLine("XplatUIX11 Constructor failed to create FosterParent");
                                }
-
                                // Prepare for shutdown
                                wm_protocols=XInternAtom(display_handle, "WM_PROTOCOLS", false);
                                wm_delete_window=XInternAtom(display_handle, "WM_DELETE_WINDOW", false);
@@ -334,6 +343,7 @@ namespace System.Windows.Forms {
                                        data.Dispose ();
                                        handle_data [handle] = null;
                                }
+                               XDestroyWindow(DisplayHandle, handle);
                        }
                }
 
@@ -367,12 +377,18 @@ namespace System.Windows.Forms {
                }
 
                internal override void SetWindowBackground(IntPtr handle, Color color) {
-                       uint    backcolor;
+                       XColor  xcolor;
+
+                       xcolor = new XColor();
+
+                       xcolor.red = (ushort)(color.R * 257);
+                       xcolor.green = (ushort)(color.G * 257);
+                       xcolor.blue = (ushort)(color.B * 257);
+                       XAllocColor(DisplayHandle, default_colormap, ref xcolor);
 
-//                     backcolor = ((uint)(color.ToArgb() & 0xff0000)>>16) | (uint)(color.ToArgb() & 0xff00) | (uint)((color.ToArgb() & 0xff) << 16);
-                       backcolor = ((uint)(color.ToArgb() & 0xff0000)) | (uint)(color.ToArgb() & 0xff00) | (uint)((color.ToArgb() & 0xff) );
                        lock (xlib_lock) {
-                               XSetWindowBackground(DisplayHandle, handle, backcolor);
+                               XSetWindowBackground(DisplayHandle, handle, xcolor.pixel);
+                               XClearWindow(DisplayHandle, handle);
                        }
                }
 
@@ -443,35 +459,9 @@ namespace System.Windows.Forms {
                }
 
                internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear) {
-                       XEvent                  xevent = new XEvent();
-
-                       xevent.type=XEventName.Expose;
-                       xevent.ExposeEvent.display=DisplayHandle;
-                       xevent.ExposeEvent.window=handle;
-                       xevent.ExposeEvent.count=0;
-
+                       // FIXME - we're not properly interpreting the clear flag, we're assuming it's always true
                        lock (xlib_lock) {
-
-                               if (clear) {
-                                       // Need to clear the whole window, so we force a redraw for the whole window
-                                       XWindowAttributes       attributes=new XWindowAttributes();
-
-                                       // We need info about our window to generate the expose 
-                                       XGetWindowAttributes(DisplayHandle, handle, ref attributes);
-
-                                       xevent.ExposeEvent.x=0;
-                                       xevent.ExposeEvent.y=0;
-                                       xevent.ExposeEvent.width=attributes.width;
-                                       xevent.ExposeEvent.height=attributes.height;
-                               } else {
-                                       xevent.ExposeEvent.x=rc.Left;
-                                       xevent.ExposeEvent.y=rc.Top;
-                                       xevent.ExposeEvent.width=rc.Width;
-                                       xevent.ExposeEvent.height=rc.Height;
-                               }
-
-                               XSendEvent(DisplayHandle, handle, false, EventMask.ExposureMask, ref xevent);
-                               // Flush is not needed, invalidate does not guarantee an immediate effect
+                               XClearArea(DisplayHandle, handle, rc.Left, rc.Top, (uint)rc.Width, (uint)rc.Height, true);
                        }
                }
 
@@ -685,7 +675,16 @@ namespace System.Windows.Forms {
                                                data.HasExpose = true;
                                        }
                                        break;
-                               default:
+                               case XEventName.KeyPress:
+                               case XEventName.KeyRelease:
+                               case XEventName.ButtonPress:
+                               case XEventName.ButtonRelease:
+                               case XEventName.MotionNotify:
+                               case XEventName.EnterNotify:
+                               case XEventName.LeaveNotify:
+                               case XEventName.ConfigureNotify:
+                               case XEventName.DestroyNotify:
+                               case XEventName.ClientMessage:
                                        lock (message_queue) {
                                                message_queue.Enqueue (xevent);
                                        }
@@ -716,6 +715,10 @@ namespace System.Windows.Forms {
 
                        msg.hwnd=xevent.AnyEvent.window;
 
+                       //
+                       // If you add a new event to this switch make sure to add it in
+                       // UpdateMessage also unless it is not coming through the X event system.
+                       //
                        switch(xevent.type) {
                                case XEventName.KeyPress: {
                                        msg.message = Msg.WM_KEYDOWN;
@@ -879,11 +882,11 @@ namespace System.Windows.Forms {
                                 xevent.TimerNotifyEvent.handler (this, EventArgs.Empty);
                                 break;
                         }
-                                
-                        default: {
-                                       msg.message = Msg.WM_NULL;
-                                       break;
-                               }
+                               
+                       default: {
+                               msg.message = Msg.WM_NULL;
+                               break;
+                       }
                        }
 
                        NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
@@ -1085,6 +1088,20 @@ namespace System.Windows.Forms {
                        y = dest_y_return;
                }
 
+               internal override void ClientToScreen(IntPtr handle, ref int x, ref int y) {
+                       int     dest_x_return;
+                       int     dest_y_return;
+                       IntPtr  child;
+
+                       lock (xlib_lock) {
+                               XTranslateCoordinates (DisplayHandle, handle, root_window,
+                                       x, y, out dest_x_return, out dest_y_return, out child);
+                       }
+
+                       x = dest_x_return;
+                       y = dest_y_return;
+               }
+
                internal override void SendAsyncMethod (AsyncMethodData method)
                {
                        XEvent xevent = new XEvent ();
@@ -1268,32 +1285,37 @@ namespace System.Windows.Forms {
                [DllImport ("libX11.so", EntryPoint="XGetGeometry")]
                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);
 
-               [DllImport ("libX11.so", EntryPoint="XAllocColor")]
-               internal extern static int XAllocColor(IntPtr display, uint Colormap, ref XColor colorcell_def);
+               [DllImport ("libX11.so", EntryPoint="XWarpPointer")]
+               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);
 
-               [DllImport ("libX11.so", EntryPoint="XGetStandardColormap")]
-               internal extern static int XGetStandardColormap(IntPtr display, IntPtr window, ref XStandardColormap cmap_info, Atom property);
+               [DllImport ("libX11.so", EntryPoint="XClearWindow")]
+               internal extern static int XClearWindow(IntPtr display, IntPtr window);
 
-               [DllImport ("libX11.so", EntryPoint="XSetRGBColormaps")]
-               internal extern static int XSetRGBColormaps(IntPtr display, IntPtr window, ref XStandardColormap cmap_info, int count, Atom property);
+               [DllImport ("libX11.so", EntryPoint="XClearArea")]
+               internal extern static int XClearArea(IntPtr display, IntPtr window, int x, int y, uint width, uint height, bool exposures);
 
-               [DllImport ("libX11.so", EntryPoint="XInstallColormap")]
-               internal extern static int XInstallColormap(IntPtr display, uint cmap);
+               // Colormaps
+               [DllImport ("libX11.so", EntryPoint="XDefaultScreenOfDisplay")]
+               internal extern static IntPtr XDefaultScreenOfDisplay(IntPtr display);
 
-               [DllImport ("libX11.so", EntryPoint="XDefaultColormap")]
-               internal extern static uint XDefaultColormap(IntPtr display, int screen_number);
+               [DllImport ("libX11.so", EntryPoint="XScreenNumberOfScreen")]
+               internal extern static int XScreenNumberOfScreen(IntPtr display, IntPtr Screen);
+
+               [DllImport ("libX11.so", EntryPoint="XDefaultVisual")]
+               internal extern static uint XDefaultVisual(IntPtr display, int screen_number);
 
                [DllImport ("libX11.so", EntryPoint="XDefaultDepth")]
                internal extern static uint XDefaultDepth(IntPtr display, int screen_number);
 
-               [DllImport ("libX11.so", EntryPoint="XDefaultVisual")]
-               internal extern static uint XDefaultVisual(IntPtr display, int screen_number);
+               [DllImport ("libX11.so", EntryPoint="XDefaultColormap")]
+               internal extern static uint XDefaultColormap(IntPtr display, int screen_number);
 
-               [DllImport ("libX11.so", EntryPoint="XSetWindowColormap")]
-               internal extern static uint XSetWindowColormap(IntPtr display, IntPtr window, uint cmap);
+               [DllImport ("libX11.so", EntryPoint="XLookupColor")]
+               internal extern static int XLookupColor(IntPtr display, uint Colormap, string Coloranem, ref XColor exact_def_color, ref XColor screen_def_color);
+
+               [DllImport ("libX11.so", EntryPoint="XAllocColor")]
+               internal extern static int XAllocColor(IntPtr display, uint Colormap, ref XColor colorcell_def);
 
-               [DllImport ("libX11.so", EntryPoint="XWarpPointer")]
-               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);
 
                // Drawing
                [DllImport ("libX11.so", EntryPoint="XCreateGC")]