Alexandre Julliard : winex11: Separate fetching the window icon bits and setting the WM hints.

Alexandre Julliard julliard at winehq.org
Fri Sep 21 14:22:39 CDT 2012


Module: wine
Branch: master
Commit: 16410ead78e35b74c95f9b5c0fdbba0c9a066271
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=16410ead78e35b74c95f9b5c0fdbba0c9a066271

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Sep 21 11:52:29 2012 +0200

winex11: Separate fetching the window icon bits and setting the WM hints.

---

 dlls/winex11.drv/window.c |  109 ++++++++++++++++++++++-----------------------
 dlls/winex11.drv/x11drv.h |    7 ++-
 2 files changed, 57 insertions(+), 59 deletions(-)

diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index d4f3f9b..d07be48 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -527,7 +527,7 @@ failed:
 /***********************************************************************
  *              create_icon_pixmaps
  */
-static BOOL create_icon_pixmaps( HDC hdc, const ICONINFO *icon, struct x11drv_win_data *data )
+static BOOL create_icon_pixmaps( HDC hdc, const ICONINFO *icon, Pixmap *icon_ret, Pixmap *mask_ret )
 {
     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
     BITMAPINFO *info = (BITMAPINFO *)buffer;
@@ -573,8 +573,8 @@ static BOOL create_icon_pixmaps( HDC hdc, const ICONINFO *icon, struct x11drv_wi
     bits.ptr = NULL;
     if (!mask_pixmap) goto failed;
 
-    data->icon_pixmap = color_pixmap;
-    data->icon_mask = mask_pixmap;
+    *icon_ret = color_pixmap;
+    *mask_ret = mask_pixmap;
     return TRUE;
 
 failed:
@@ -586,18 +586,16 @@ failed:
 
 
 /***********************************************************************
- *              set_icon_hints
- *
- * Set the icon wm hints
+ *              fetch_icon_data
  */
-static void set_icon_hints( HWND hwnd, HICON icon_big, HICON icon_small )
+static void fetch_icon_data( HWND hwnd, HICON icon_big, HICON icon_small )
 {
-    Display *display = thread_display();
     struct x11drv_win_data *data;
     ICONINFO ii, ii_small;
     HDC hDC;
     unsigned int size;
     unsigned long *bits;
+    Pixmap icon_pixmap, mask_pixmap;
 
     if (!icon_big)
     {
@@ -611,13 +609,6 @@ static void set_icon_hints( HWND hwnd, HICON icon_big, HICON icon_small )
         if (!icon_small) icon_small = (HICON)GetClassLongPtrW( hwnd, GCLP_HICONSM );
     }
 
-    if (!(data = X11DRV_get_win_data( hwnd ))) return;
-
-    if (data->icon_pixmap) XFreePixmap( gdi_display, data->icon_pixmap );
-    if (data->icon_mask) XFreePixmap( gdi_display, data->icon_mask );
-    data->icon_pixmap = data->icon_mask = 0;
-    data->wm_hints->flags &= ~(IconPixmapHint | IconMaskHint);
-
     if (!GetIconInfo(icon_big, &ii)) return;
 
     hDC = CreateCompatibleDC(0);
@@ -642,22 +633,30 @@ static void set_icon_hints( HWND hwnd, HICON icon_big, HICON icon_small )
         DeleteObject( ii_small.hbmColor );
         DeleteObject( ii_small.hbmMask );
     }
-    if (bits)
-        XChangeProperty( display, data->whole_window, x11drv_atom(_NET_WM_ICON),
-                         XA_CARDINAL, 32, PropModeReplace, (unsigned char *)bits, size );
-    else
-        XDeleteProperty( display, data->whole_window, x11drv_atom(_NET_WM_ICON) );
-    HeapFree( GetProcessHeap(), 0, bits );
 
-    if (create_icon_pixmaps( hDC, &ii, data ))
-    {
-        data->wm_hints->icon_pixmap = data->icon_pixmap;
-        data->wm_hints->icon_mask = data->icon_mask;
-        data->wm_hints->flags |= IconPixmapHint | IconMaskHint;
-    }
+    if (!create_icon_pixmaps( hDC, &ii, &icon_pixmap, &mask_pixmap )) icon_pixmap = mask_pixmap = 0;
+
     DeleteObject( ii.hbmColor );
     DeleteObject( ii.hbmMask );
     DeleteDC(hDC);
+
+    if ((data = get_win_data( hwnd )))
+    {
+        if (data->icon_pixmap) XFreePixmap( gdi_display, data->icon_pixmap );
+        if (data->icon_mask) XFreePixmap( gdi_display, data->icon_mask );
+        HeapFree( GetProcessHeap(), 0, data->icon_bits );
+        data->icon_pixmap = icon_pixmap;
+        data->icon_mask = mask_pixmap;
+        data->icon_bits = bits;
+        data->icon_size = size;
+        release_win_data( data );
+    }
+    else
+    {
+        if (icon_pixmap) XFreePixmap( gdi_display, icon_pixmap );
+        if (mask_pixmap) XFreePixmap( gdi_display, mask_pixmap );
+        HeapFree( GetProcessHeap(), 0, bits );
+    }
 }
 
 
@@ -746,6 +745,7 @@ static void set_style_hints( Display *display, struct x11drv_win_data *data, DWO
     Window group_leader = data->whole_window;
     HWND owner = GetWindow( data->hwnd, GW_OWNER );
     Window owner_win = X11DRV_get_whole_window( owner );
+    XWMHints *wm_hints;
     Atom window_type;
 
     if (owner_win)
@@ -766,15 +766,29 @@ static void set_style_hints( Display *display, struct x11drv_win_data *data, DWO
     XChangeProperty(display, data->whole_window, x11drv_atom(_NET_WM_WINDOW_TYPE),
 		    XA_ATOM, 32, PropModeReplace, (unsigned char*)&window_type, 1);
 
-    /* wm hints */
-    if (data->wm_hints)
+    if ((wm_hints = XAllocWMHints()))
     {
-        data->wm_hints->flags |= InputHint | StateHint | WindowGroupHint;
-        data->wm_hints->input = !use_take_focus && !(style & WS_DISABLED);
-        data->wm_hints->initial_state = (style & WS_MINIMIZE) ? IconicState : NormalState;
-        data->wm_hints->window_group = group_leader;
-        XSetWMHints( display, data->whole_window, data->wm_hints );
+        wm_hints->flags = InputHint | StateHint | WindowGroupHint;
+        wm_hints->input = !use_take_focus && !(style & WS_DISABLED);
+        wm_hints->initial_state = (style & WS_MINIMIZE) ? IconicState : NormalState;
+        wm_hints->window_group = group_leader;
+        if (data->icon_pixmap)
+        {
+            wm_hints->icon_pixmap = data->icon_pixmap;
+            wm_hints->icon_mask = data->icon_mask;
+            wm_hints->flags |= IconPixmapHint | IconMaskHint;
+        }
+        XSetWMHints( display, data->whole_window, wm_hints );
+        XFree( wm_hints );
     }
+
+    if (data->icon_bits)
+        XChangeProperty( display, data->whole_window, x11drv_atom(_NET_WM_ICON),
+                         XA_CARDINAL, 32, PropModeReplace,
+                         (unsigned char *)data->icon_bits, data->icon_size );
+    else
+        XDeleteProperty( display, data->whole_window, x11drv_atom(_NET_WM_ICON) );
+
 }
 
 
@@ -858,13 +872,6 @@ static void set_initial_wm_hints( HWND hwnd )
     if (user_time_window)
         XChangeProperty( display, data->whole_window, x11drv_atom(_NET_WM_USER_TIME_WINDOW),
                          XA_WINDOW, 32, PropModeReplace, (unsigned char *)&user_time_window, 1 );
-
-    data->wm_hints = XAllocWMHints();
-    if (data->wm_hints)
-    {
-        data->wm_hints->flags = 0;
-        set_icon_hints( hwnd, 0, 0 );
-    }
 }
 
 
@@ -1378,6 +1385,7 @@ static Window create_whole_window( HWND hwnd )
     if (!data->whole_window) goto done;
 
     set_initial_wm_hints( hwnd );
+    fetch_icon_data( hwnd, 0, 0 );
     set_wm_hints( hwnd );
 
     XSaveContext( display, data->whole_window, winContext, (char *)data->hwnd );
@@ -1444,8 +1452,6 @@ static void destroy_whole_window( Display *display, struct x11drv_win_data *data
     }
     /* Outlook stops processing messages after destroying a dialog, so we need an explicit flush */
     XFlush( display );
-    XFree( data->wm_hints );
-    data->wm_hints = NULL;
     if (data->surface) window_surface_release( data->surface );
     data->surface = NULL;
     RemovePropA( data->hwnd, whole_window_prop );
@@ -1507,6 +1513,7 @@ void CDECL X11DRV_DestroyWindow( HWND hwnd )
     if (thread_data->last_xic_hwnd == hwnd) thread_data->last_xic_hwnd = 0;
     if (data->icon_pixmap) XFreePixmap( gdi_display, data->icon_pixmap );
     if (data->icon_mask) XFreePixmap( gdi_display, data->icon_mask );
+    HeapFree( GetProcessHeap(), 0, data->icon_bits );
     XDeleteContext( gdi_display, (XID)hwnd, win_data_context );
     release_win_data( data );
     HeapFree( GetProcessHeap(), 0, data );
@@ -2245,26 +2252,16 @@ UINT CDECL X11DRV_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp )
  * hIcon or hIconSm has changed (or is being initialised for the
  * first time). Complete the X11 driver-specific initialisation
  * and set the window hints.
- *
- * This is not entirely correct, may need to create
- * an icon window and set the pixmap as a background
  */
 void CDECL X11DRV_SetWindowIcon( HWND hwnd, UINT type, HICON icon )
 {
-    Display *display = thread_display();
     struct x11drv_win_data *data;
 
-
     if (!(data = X11DRV_get_win_data( hwnd ))) return;
     if (!data->whole_window) return;
-    if (!data->managed) return;
-
-    if (data->wm_hints)
-    {
-        if (type == ICON_BIG) set_icon_hints( hwnd, icon, 0 );
-        else set_icon_hints( hwnd, 0, icon );
-        XSetWMHints( display, data->whole_window, data->wm_hints );
-    }
+    if (type == ICON_BIG) fetch_icon_data( hwnd, icon, 0 );
+    else fetch_icon_data( hwnd, 0, icon );
+    set_wm_hints( hwnd );
 }
 
 
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 28cbe6a..4f355ad 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -538,7 +538,6 @@ struct x11drv_win_data
     RECT        whole_rect;     /* X window rectangle for the whole window relative to parent */
     RECT        client_rect;    /* client area relative to parent */
     XIC         xic;            /* X input context */
-    XWMHints   *wm_hints;       /* window manager hints */
     BOOL        managed : 1;    /* is window managed? */
     BOOL        mapped : 1;     /* is window mapped? (in either normal or iconic state) */
     BOOL        iconic : 1;     /* is window in iconic state? */
@@ -549,8 +548,10 @@ struct x11drv_win_data
     Window      embedder;       /* window id of embedder */
     unsigned long configure_serial; /* serial number of last configure request */
     struct window_surface *surface;
-    Pixmap      icon_pixmap;
-    Pixmap      icon_mask;
+    Pixmap         icon_pixmap;
+    Pixmap         icon_mask;
+    unsigned long *icon_bits;
+    unsigned int   icon_size;
 };
 
 extern struct x11drv_win_data *get_win_data( HWND hwnd ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list