2007-01-02 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Hwnd.cs
index 4a60914dc2c4d390ba069f4022e85179ca6c4b6d..3a03e010af2bca3f14755a6126e2e4ae965d5ab1 100644 (file)
@@ -54,17 +54,17 @@ namespace System.Windows.Forms {
                internal bool           allow_drop;
                internal Hwnd           parent;
                internal bool           visible;
+               internal bool           mapped;
                internal uint           opacity;
                internal bool           enabled;
                internal bool           zero_sized;
-               internal Rectangle      invalid;
+               internal ArrayList      invalid_list;
                internal Rectangle      nc_invalid;
                internal bool           expose_pending;
                internal bool           nc_expose_pending;
                internal bool           configure_pending;
                internal bool           reparented;
-               internal Graphics       client_dc;
-               internal Graphics       non_client_dc;
+               internal Stack          drawing_stack;
                internal object         user_data;
                internal Rectangle      client_rectangle;
                internal ArrayList      marshal_free_list;
@@ -72,9 +72,19 @@ namespace System.Windows.Forms {
                internal int            tool_caption_height;
                internal bool           whacky_wm;
                internal bool           fixed_size;
+               internal bool           zombie; /* X11 only flag.  true if the X windows have been destroyed but we haven't been Disposed */
+               internal Region         user_clip;
                internal static Bitmap  bmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+               internal static Graphics bmp_g = Graphics.FromImage (bmp);
+               internal XEventQueue    queue;
+               internal bool           no_activate;    // For Win32, popup windows will not steal focus
+               internal WindowExStyles initial_ex_style;
                #endregion      // Local Variables
 
+               // locks for some operations (used in XplatUIX11.cs)
+               internal object configure_lock = new object ();
+               internal object expose_lock = new object ();
+
                #region Constructors and destructors
                public Hwnd() {
                        x = 0;
@@ -88,7 +98,7 @@ namespace System.Windows.Forms {
                        whole_window = IntPtr.Zero;
                        handle = IntPtr.Zero;
                        parent = null;
-                       invalid = Rectangle.Empty;
+                       invalid_list = new ArrayList();
                        expose_pending = false;
                        nc_expose_pending = false;
                        enabled = true;
@@ -97,11 +107,19 @@ namespace System.Windows.Forms {
                        marshal_free_list = new ArrayList(2);
                        opacity = 0xffffffff;
                        fixed_size = false;
+                       drawing_stack = new Stack ();
                }
 
                public void Dispose() {
-                       windows.Remove(client_window);
-                       windows.Remove(whole_window);
+                       expose_pending = false;
+                       nc_expose_pending = false;
+                       lock (windows) {
+                               windows.Remove(client_window);
+                               windows.Remove(whole_window);
+                       }
+                       client_window = IntPtr.Zero;
+                       whole_window = IntPtr.Zero;
+                       zombie = false;
                        for (int i = 0; i < marshal_free_list.Count; i++) {
                                Marshal.FreeHGlobal((IntPtr)marshal_free_list[i]);
                        }
@@ -110,17 +128,21 @@ namespace System.Windows.Forms {
                #endregion
 
                #region Static Methods
-               public void SetObjectWindow(Hwnd obj, IntPtr window) {
-                       windows[window] = obj;
-               }
-
                public static Hwnd ObjectFromWindow(IntPtr window) {
-                       return (Hwnd)windows[window];
+                       Hwnd rv;
+                       lock (windows) {
+                               rv = (Hwnd)windows[window];
+                       }
+                       return rv;
                }
 
                public static Hwnd ObjectFromHandle(IntPtr handle) {
                        //return (Hwnd)(((GCHandle)handle).Target);
-                       return (Hwnd)windows[handle];
+                       Hwnd rv;
+                       lock (windows) {
+                               rv = (Hwnd)windows[handle];
+                       }
+                       return rv;
                }
 
                public static IntPtr HandleFromObject(Hwnd obj) {
@@ -128,13 +150,19 @@ namespace System.Windows.Forms {
                }
 
                public static Hwnd GetObjectFromWindow(IntPtr window) {
-                       return (Hwnd)windows[window];
+                       Hwnd rv;
+                       lock (windows) {
+                               rv = (Hwnd)windows[window];
+                       }
+                       return rv;
                }
 
                public static IntPtr GetHandleFromWindow(IntPtr window) {
                        Hwnd    hwnd;
 
-                       hwnd = (Hwnd)windows[window];
+                       lock (windows) {
+                               hwnd = (Hwnd)windows[window];
+                       }
                        if (hwnd != null) {
                                return hwnd.handle;
                        } else {
@@ -152,13 +180,8 @@ namespace System.Windows.Forms {
 
                        if (menu != null) {
                                int menu_height = menu.Rect.Height;
-                               if (menu_height == 0) {
-                                       Graphics g;
-
-                                       g = Graphics.FromImage(bmp);
-                                       menu_height = ThemeEngine.Current.CalcMenuBarSize(g, menu, client_rect.Width);
-                                       g.Dispose();
-                               }
+                               if (menu_height == 0)
+                                       menu_height = ThemeEngine.Current.CalcMenuBarSize(bmp_g, menu, client_rect.Width);
 
                                rect.Y -= menu_height;
                                rect.Height += menu_height;
@@ -221,21 +244,6 @@ namespace System.Windows.Forms {
                        }
                }
 
-               public Graphics ClientDC {
-                       get {
-                               return client_dc;
-                       }
-
-                       set {
-                               client_dc = value;
-                       }
-               }
-
-               public Graphics NonClientDC {
-                       get { return non_client_dc; }
-                       set { non_client_dc = value; }
-               }
-
                public Rectangle ClientRect {
                        get {
                                if (client_rectangle == Rectangle.Empty) {
@@ -258,12 +266,28 @@ namespace System.Windows.Forms {
                                client_window = value;
                                handle = value;
 
-                               if (windows[client_window] == null) {
-                                       windows[client_window] = this;
+                               zombie = false;
+
+                               if (client_window != IntPtr.Zero) {
+                                       lock (windows) {
+                                               if (windows[client_window] == null) {
+                                                       windows[client_window] = this;
+                                               }
+                                       }
                                }
                        }
                }
 
+               public Region UserClip {
+                       get {
+                               return user_clip;
+                       }
+
+                       set {
+                               user_clip = value;
+                       }
+               }
+
                public Rectangle DefaultClientRect {
                        get {
                                // We pass a Zero for the menu handle so the menu size is
@@ -277,10 +301,6 @@ namespace System.Windows.Forms {
                        get {
                                return expose_pending;
                        }
-
-                       set {
-                               expose_pending = value;
-                       }
                }
 
                public IntPtr Handle {
@@ -332,6 +352,16 @@ namespace System.Windows.Forms {
                        }
                }
 
+               public XEventQueue Queue {
+                       get {
+                               return queue;
+                       }
+
+                       set {
+                               queue = value;
+                       }
+               }
+
                public bool Enabled {
                        get {
                                if (!enabled) {
@@ -387,14 +417,23 @@ namespace System.Windows.Forms {
 
                public Rectangle Invalid {
                        get {
-                               return invalid;
-                       }
+                               if (invalid_list.Count == 0)
+                                       return Rectangle.Empty;
 
-                       set {
-                               invalid = value;
+                               Rectangle result = (Rectangle)invalid_list[0];
+                               for (int i = 1; i < invalid_list.Count; i ++) {
+                                       result = Rectangle.Union (result, (Rectangle)invalid_list[i]);
+                               }
+                               return result;
                        }
                }
 
+               public Rectangle[] ClipRectangles {
+                       get {
+                               return (Rectangle[]) invalid_list.ToArray (typeof (Rectangle));
+                       }
+               }
+
                public Rectangle NCInvalid {
                        get { return nc_invalid; }
                        set { nc_invalid = value; }
@@ -405,10 +444,6 @@ namespace System.Windows.Forms {
                        get {
                                return nc_expose_pending;
                        }
-
-                       set {
-                               nc_expose_pending = value;
-                       }
                }
 
                public Hwnd Parent {
@@ -421,6 +456,24 @@ namespace System.Windows.Forms {
                        }
                }
 
+               public bool Mapped {
+                       get {
+                               if (!mapped) {
+                                       return false;
+                               }
+
+                               if (parent != null) {
+                                       return parent.Mapped;
+                               }
+
+                               return true;
+                       }
+
+                       set {
+                               mapped = value;
+                       }
+               }
+
                public int CaptionHeight {
                        get { return caption_height; }
                        set { caption_height = value; }
@@ -459,8 +512,14 @@ namespace System.Windows.Forms {
                        set {
                                whole_window = value;
 
-                               if (windows[whole_window] == null) {
-                                       windows[whole_window] = this;
+                               zombie = false;
+
+                               if (whole_window != IntPtr.Zero) {
+                                       lock (windows) {
+                                               if (windows[whole_window] == null) {
+                                                       windows[whole_window] = this;
+                                               }
+                                       }
                                }
                        }
                }
@@ -509,31 +568,22 @@ namespace System.Windows.Forms {
 
                #region Methods
                public void AddInvalidArea(int x, int y, int width, int height) {
-                       if (invalid == Rectangle.Empty) {
-                               invalid = new Rectangle (x, y, width, height);
-                               return;
-                       }
-
-                       int right, bottom;
-                       right = Math.Max (invalid.Right, x + width);
-                       bottom = Math.Max (invalid.Bottom, y + height);
-                       invalid.X = Math.Min (invalid.X, x);
-                       invalid.Y = Math.Min (invalid.Y, y);
-
-                       invalid.Width = right - invalid.X;
-                       invalid.Height = bottom - invalid.Y;
+                       AddInvalidArea(new Rectangle(x, y, width, height));
                }
 
                public void AddInvalidArea(Rectangle rect) {
-                       if (invalid == Rectangle.Empty) {
-                               invalid = rect;
-                               return;
+                       ArrayList tmp = new ArrayList ();
+                       foreach (Rectangle r in invalid_list) {
+                               if (!rect.Contains (r)) {
+                                       tmp.Add (r);
+                               }
                        }
-                       invalid = Rectangle.Union (invalid, rect);
+                       tmp.Add (rect);
+                       invalid_list = tmp;
                }
 
                public void ClearInvalidArea() {
-                       invalid = Rectangle.Empty;
+                       invalid_list.Clear();
                        expose_pending = false;
                }
 
@@ -567,7 +617,7 @@ namespace System.Windows.Forms {
                }
 
                public override string ToString() {
-                       return String.Format("Hwnd, ClientWindow:0x{0:X}, WholeWindow:0x{1:X}, Parent:[{2:X}]", client_window.ToInt32(), whole_window.ToInt32(), parent != null ? parent.ToString() : "<null>");
+                       return String.Format("Hwnd, Mapped:{3} ClientWindow:0x{0:X}, WholeWindow:0x{1:X}, Parent:[{2:X}]", client_window.ToInt32(), whole_window.ToInt32(), parent != null ? parent.ToString() : "<null>", Mapped);
                }
 
                #endregion      // Methods