]> Pileus Git - ~andy/gtk/blobdiff - gdk/win32/gdkwindow-win32.c
Handle pixmap == NULL when checking for a colormap. (Allin Cottrell).
[~andy/gtk] / gdk / win32 / gdkwindow-win32.c
index 043fd15d2391e6e9c1bcdb1ffb893733a8de76fb..81d764cc40e5f6cf617bd021b4611f0a5366d67b 100644 (file)
@@ -29,6 +29,9 @@
 #include <config.h>
 #include <stdlib.h>
 
+#define _WIN32_WINNT 0x0500
+#define WINVER _WIN32_WINNT
+
 #include "gdk.h" /* gdk_rectangle_intersect */
 #include "gdkevents.h"
 #include "gdkpixmap.h"
 #include "gdkprivate-win32.h"
 #include "gdkinput-win32.h"
 
-#if defined __MINGW32__ || (WINVER < 0x0500)
-typedef struct { 
-  DWORD        bV5Size; 
-  LONG         bV5Width; 
-  LONG         bV5Height; 
-  WORD         bV5Planes; 
-  WORD         bV5BitCount; 
-  DWORD        bV5Compression; 
-  DWORD        bV5SizeImage; 
-  LONG         bV5XPelsPerMeter; 
-  LONG         bV5YPelsPerMeter; 
-  DWORD        bV5ClrUsed; 
-  DWORD        bV5ClrImportant; 
-  DWORD        bV5RedMask; 
-  DWORD        bV5GreenMask; 
-  DWORD        bV5BlueMask; 
-  DWORD        bV5AlphaMask; 
-  DWORD        bV5CSType; 
-  CIEXYZTRIPLE bV5Endpoints; 
-  DWORD        bV5GammaRed; 
-  DWORD        bV5GammaGreen; 
-  DWORD        bV5GammaBlue; 
-  DWORD        bV5Intent; 
-  DWORD        bV5ProfileData; 
-  DWORD        bV5ProfileSize; 
-  DWORD        bV5Reserved; 
-} BITMAPV5HEADER;
+#if defined(_MSC_VER) && (WINVER < 0x0500)
+#define GetAncestor(hwnd,what) _gdk_win32_get_ancestor_parent(hwnd)
+
+static HWND
+_gdk_win32_get_ancestor_parent (HWND hwnd)
+{
+#ifndef GA_PARENT
+#  define GA_PARENT 1 
+#endif
+  typedef HWND (WINAPI *PFN_GetAncestor) (HWND,UINT);
+  static PFN_GetAncestor p_GetAncestor = NULL;
+  static gboolean once = FALSE;
+  
+  if (!once)
+    {
+      HMODULE user32;
+
+      user32 = GetModuleHandle ("user32.dll");
+      p_GetAncestor = (PFN_GetAncestor)GetProcAddress (user32, "GetAncestor");
+      once = TRUE;
+    }
+  if (p_GetAncestor)
+    return p_GetAncestor (hwnd, GA_PARENT);
+  else /* not completely right, but better than nothing ? */
+    return GetParent (hwnd);
+}
 
 #endif
 
@@ -857,6 +859,8 @@ _gdk_windowing_window_destroy (GdkWindow *window,
 
   if (!recursing && !foreign_destroy)
     {
+      _gdk_win32_drawable_finish (private->impl);
+
       private->destroyed = TRUE;
       DestroyWindow (GDK_WINDOW_HWND (window));
     }
@@ -1566,6 +1570,30 @@ gdk_window_set_hints (GdkWindow *window,
     }
 }
 
+void
+gdk_window_set_urgency_hint (GdkWindow *window,
+                            gboolean   urgent)
+{
+  FLASHWINFO flashwinfo;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
+  
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  flashwinfo.cbSize = sizeof (flashwinfo);
+  flashwinfo.hwnd = GDK_WINDOW_HWND (window);
+  if (urgent)
+    flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
+  else
+    flashwinfo.dwFlags = FLASHW_STOP;
+  flashwinfo.uCount = 0;
+  flashwinfo.dwTimeout = 0;
+
+  FlashWindowEx (&flashwinfo);
+}
+
 void 
 gdk_window_set_geometry_hints (GdkWindow      *window,
                               GdkGeometry    *geometry,
@@ -1709,12 +1737,12 @@ void
 gdk_window_set_title (GdkWindow   *window,
                      const gchar *title)
 {
-  char *mbtitle;
-
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (title != NULL);
 
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
   /* Empty window titles not allowed, so set it to just a period. */
   if (!title[0])
     title = ".";
@@ -1722,14 +1750,17 @@ gdk_window_set_title (GdkWindow   *window,
   GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
                           GDK_WINDOW_HWND (window), title));
   
-  if (!GDK_WINDOW_DESTROYED (window))
+  if (G_WIN32_HAVE_WIDECHAR_API ())
     {
-      /* As the title is in UTF-8 we must translate it
-       * to the system codepage.
-       */
-      mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
-      API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), mbtitle));
-      g_free (mbtitle);
+      wchar_t *wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
+      API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle));
+      g_free (wtitle);
+    }
+  else
+    {
+      char *cptitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
+      API_CALL (SetWindowTextA, (GDK_WINDOW_HWND (window), cptitle));
+      g_free (cptitle);
     }
 }
 
@@ -1818,6 +1849,12 @@ gdk_window_set_back_pixmap (GdkWindow *window,
   g_return_if_fail (pixmap == NULL || !parent_relative);
   g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
   
+  if (pixmap && !gdk_drawable_get_colormap (pixmap))
+    {
+      g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap");
+      return;
+    }
+  
   if (private->bg_pixmap &&
       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
       private->bg_pixmap != GDK_NO_BG)
@@ -2378,193 +2415,6 @@ gdk_window_set_focus_on_map (GdkWindow *window,
     private->focus_on_map = focus_on_map;
 }
 
-static HICON
-pixbuf_to_hicon_alpha_winxp (GdkWindow *window,
-                            GdkPixbuf *pixbuf)
-{
-  /* Based on code from
-   * http://www.dotnet247.com/247reference/msgs/13/66301.aspx
-   */
-  HDC hdc;
-  BITMAPV5HEADER bi;
-  HBITMAP hBitmap, hMonoBitmap;
-  guchar *indata, *inrow;
-  guchar *outdata, *outrow;
-  HICON hAlphaIcon = NULL;
-  ICONINFO ii;
-  gint width, height, i, j, rowstride;
-
-  if (pixbuf == NULL)
-    return NULL;
-
-  width = gdk_pixbuf_get_width (pixbuf); /* width of icon */
-  height = gdk_pixbuf_get_height (pixbuf); /* height of icon */
-
-  ZeroMemory (&bi, sizeof (BITMAPV5HEADER));
-  bi.bV5Size = sizeof (BITMAPV5HEADER);
-  bi.bV5Width = width;
-  bi.bV5Height = height;
-  bi.bV5Planes = 1;
-  bi.bV5BitCount = 32;
-  bi.bV5Compression = BI_BITFIELDS;
-  /* The following mask specification specifies a supported 32 BPP
-   * alpha format for Windows XP (BGRA format).
-   */
-  bi.bV5RedMask   = 0x00FF0000;
-  bi.bV5GreenMask = 0x0000FF00;
-  bi.bV5BlueMask  = 0x000000FF;
-  bi.bV5AlphaMask = 0xFF000000;
-
-  /* Create the DIB section with an alpha channel. */
-  hdc = GetDC (NULL);
-  hBitmap = CreateDIBSection (hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS,
-                             (void **)&outdata, NULL, (DWORD)0);
-  ReleaseDC (NULL, hdc);
-
-  /* Draw something on the DIB section */
-  indata = gdk_pixbuf_get_pixels (pixbuf);
-  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-  for (j=0; j<height; j++)
-    {
-      outrow = outdata + 4*j*width;
-      inrow  = indata  + (height-j-1)*rowstride;
-      for (i=0; i<width; i++)
-       {
-         outrow[4*i+0] = inrow[4*i+2];
-         outrow[4*i+1] = inrow[4*i+1];
-         outrow[4*i+2] = inrow[4*i+0];
-         outrow[4*i+3] = inrow[4*i+3];
-       }
-    }
-
-  /* Create an empty mask bitmap */
-  hMonoBitmap = CreateBitmap (width, height, 1, 1, NULL);
-
-  ii.fIcon = TRUE;
-  ii.xHotspot = 0;
-  ii.yHotspot = 0;
-  ii.hbmMask = hMonoBitmap;
-  ii.hbmColor = hBitmap;
-
-  /* Create the alpha cursor with the alpha DIB section */
-  hAlphaIcon = CreateIconIndirect (&ii);
-
-  GDI_CALL (DeleteObject, (hBitmap));
-  GDI_CALL (DeleteObject, (hMonoBitmap));
-
-  return hAlphaIcon;
-}
-
-static HICON
-pixbuf_to_hicon_normal (GdkWindow *window,
-                       GdkPixbuf *pixbuf)
-{
-  GdkPixmap *pixmap;
-  GdkBitmap *mask;
-  HBITMAP hbmmask = NULL;
-  ICONINFO ii;
-  HICON hIcon;
-  gint w = 0, h = 0;
-
-  if (pixbuf == NULL)
-    return NULL;
-
-  /* create a normal icon with a bitmap mask */
-  w = gdk_pixbuf_get_width (pixbuf);
-  h = gdk_pixbuf_get_height (pixbuf);
-  gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, 
-                                                 gdk_drawable_get_colormap (window),
-                                                 &pixmap,
-                                                 &mask,
-                                                 128);
-
-  /* we need the inverted mask for the XOR op */
-  {
-    HDC hdc1 = CreateCompatibleDC (NULL);
-    HBITMAP hbmold1;
-
-    hbmmask = CreateCompatibleBitmap (hdc1, w, h);
-    hbmold1 = SelectObject (hdc1, hbmmask);
-    if (mask)
-      {
-       HDC hdc2 = CreateCompatibleDC (NULL);
-       HBITMAP hbmold2 = SelectObject (hdc2, GDK_PIXMAP_HBITMAP (mask));
-       GDI_CALL (BitBlt, (hdc1, 0,0,w,h, hdc2, 0,0, NOTSRCCOPY));
-       GDI_CALL (SelectObject, (hdc2, hbmold2));
-       GDI_CALL (DeleteDC, (hdc2));
-      }
-    else
-      {
-       RECT rect;
-       GetClipBox (hdc1, &rect);
-       GDI_CALL (FillRect, (hdc1, &rect, GetStockObject (BLACK_BRUSH)));
-      }
-    GDI_CALL (SelectObject, (hdc1, hbmold1));
-    GDI_CALL (DeleteDC, (hdc1));
-  }
-
-  ii.fIcon = TRUE;
-  ii.xHotspot = ii.yHotspot = 0; /* ignored for icons */
-  ii.hbmMask = hbmmask;
-  ii.hbmColor = GDK_PIXMAP_HBITMAP (pixmap);
-  hIcon = CreateIconIndirect (&ii);
-  if (!hIcon)
-    WIN32_API_FAILED ("CreateIconIndirect");
-  GDI_CALL (DeleteObject, (hbmmask));
-
-#if 0 /* to debug pixmap and mask setting */
-  {
-    static int num = 0;
-    GdkPixbuf* pixbuf = NULL;
-    char name[256];
-
-    pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0, w, h);
-    if (pixbuf)
-      {
-       num = (num + 1) % 999; /* restrict maximim number */
-       sprintf (name, "c:\\temp\\ico%03dpixm.png", num); 
-       gdk_pixbuf_save (pixbuf, name, "png", NULL, NULL);
-       gdk_pixbuf_unref (pixbuf);
-      }
-  }
-#endif
-
-  if (pixmap)
-    g_object_unref (pixmap);
-  if (mask)
-    g_object_unref (mask);
-
-  return hIcon;
-}
-
-static HICON
-pixbuf_to_hicon (GdkWindow *window,
-                GdkPixbuf *pixbuf)
-{
-  static gboolean is_win_xp=FALSE, is_win_xp_checked=FALSE;
-
-  if (!is_win_xp_checked)
-    {
-      OSVERSIONINFO version;
-
-      is_win_xp_checked = TRUE;
-      memset (&version, 0, sizeof (version));
-      version.dwOSVersionInfoSize = sizeof (version);
-      is_win_xp = GetVersionEx (&version)
-       && version.dwPlatformId == VER_PLATFORM_WIN32_NT
-       && (version.dwMajorVersion > 5
-           || (version.dwMajorVersion == 5 && version.dwMinorVersion >= 1));
-    }
-
-  if (pixbuf == NULL)
-    return NULL;
-
-  if (is_win_xp && gdk_pixbuf_get_has_alpha (pixbuf))
-    return pixbuf_to_hicon_alpha_winxp (window, pixbuf);
-  else
-    return pixbuf_to_hicon_normal (window, pixbuf);
-}
-
 void          
 gdk_window_set_icon_list (GdkWindow *window,
                          GList     *pixbufs)
@@ -2628,8 +2478,8 @@ gdk_window_set_icon_list (GdkWindow *window,
     }
 
   /* Create the icons */
-  big_hicon = pixbuf_to_hicon (window, big_pixbuf);
-  small_hicon = pixbuf_to_hicon (window, small_pixbuf);
+  big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
+  small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
 
   /* Set the icons */
   SendMessage (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,