]> Pileus Git - ~andy/gtk/blobdiff - gdk/win32/gdkwindow-win32.c
List the three theme gtkrc files separately, zip doesn't do anything if
[~andy/gtk] / gdk / win32 / gdkwindow-win32.c
index a87136b33eb055dcd9339e82a739b7cece007fa4..5fe64b7e9f728fb73089e79486f537297a1ad564 100644 (file)
@@ -1,6 +1,7 @@
 /* GDK - The GIMP Drawing Kit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- * Copyright (C) 1998-2002 Tor Lillqvist
+ * Copyright (C) 1998-2004 Tor Lillqvist
+ * Copyright (C) 2001-2004 Hans Breuer
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -221,7 +222,8 @@ gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
   if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only && 
       drawable_impl->colormap == NULL)
     {
-      drawable_impl->colormap = gdk_colormap_get_system ();
+      drawable_impl->colormap = 
+        gdk_screen_get_system_colormap (gdk_drawable_get_screen (drawable));
       g_object_ref (drawable_impl->colormap);
     }
   
@@ -268,6 +270,7 @@ gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable)
 {
   GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (drawable);
   GdkRectangle result_rect;
+  HDC hdc;
 
   result_rect.x = 0;
   result_rect.y = 0;
@@ -276,23 +279,54 @@ gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable)
 
   gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
 
+  /* take this win32 specific part into account (smaller when obscured) */
+  hdc = GetDC (GDK_DRAWABLE_IMPL_WIN32_HANDLE (impl));
+  if (hdc)
+    {
+      RECT r;
+      if (SIMPLEREGION == GetClipBox (hdc, &r))
+        {
+          GdkRectangle gr;
+
+          gr.x = r.left;
+          gr.y = r.top;
+          gr.width = r.right - r.left;
+          gr.height = r.bottom - r.top;
+
+          gdk_rectangle_intersect (&result_rect, &gr, &result_rect);
+        }
+      ReleaseDC (GDK_DRAWABLE_IMPL_WIN32_HANDLE (drawable), hdc);
+    }
+
   return gdk_region_rectangle (&result_rect);
 }
 
+void
+_gdk_root_window_size_init (void)
+{
+  GdkWindowImplWin32 *impl;
+  GdkRectangle rect;
+  int i;
+
+  impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) _gdk_parent_root)->impl);
+  rect = _gdk_monitors[0];
+  for (i = 1; i < _gdk_num_monitors; i++)
+    gdk_rectangle_union (&rect, _gdk_monitors+i, &rect);
+
+  impl->width = rect.width;
+  impl->height = rect.height;
+}
+
 void
 _gdk_windowing_window_init (void)
 {
   GdkWindowObject *private;
-  GdkWindowImplWin32 *impl;
   GdkDrawableImplWin32 *draw_impl;
-  GdkRectangle rect;
-  gint i;
 
   g_assert (_gdk_parent_root == NULL);
   
   _gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
   private = (GdkWindowObject *)_gdk_parent_root;
-  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
   draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
   
   draw_impl->handle = _gdk_root_window;
@@ -303,13 +337,8 @@ _gdk_windowing_window_init (void)
   private->window_type = GDK_WINDOW_ROOT;
   private->depth = gdk_visual_get_system ()->depth;
 
-  rect = _gdk_monitors[0];
-  for (i = 1; i < _gdk_num_monitors; i++)
-    gdk_rectangle_union (&rect, _gdk_monitors+i, &rect);
-
-  impl->width = rect.width;
-  impl->height = rect.height;
-
+  _gdk_root_window_size_init ();
   _gdk_window_init_position (GDK_WINDOW (private));
 
   gdk_win32_handle_table_insert (&_gdk_root_window, _gdk_parent_root);
@@ -448,10 +477,11 @@ RegisterGdkClass (GdkWindowType wtype)
   return klass;
 }
 
-GdkWindow*
-gdk_window_new (GdkWindow     *parent,
-               GdkWindowAttr *attributes,
-               gint           attributes_mask)
+static GdkWindow*
+gdk_window_new_internal (GdkWindow     *parent,
+                        GdkWindowAttr *attributes,
+                        gint           attributes_mask,
+                        gboolean       from_set_skip_taskbar_hint)
 {
   HANDLE hparent;
   ATOM klass = 0;
@@ -508,6 +538,7 @@ gdk_window_new (GdkWindow     *parent,
   private->parent = (GdkWindowObject *)parent;
 
   private->accept_focus = TRUE;
+  private->focus_on_map = TRUE;
 
   if (attributes_mask & GDK_WA_X)
     private->x = attributes->x;
@@ -529,7 +560,19 @@ gdk_window_new (GdkWindow     *parent,
   impl->width = (attributes->width > 1) ? (attributes->width) : (1);
   impl->height = (attributes->height > 1) ? (attributes->height) : (1);
   impl->extension_events_selected = FALSE;
-  private->window_type = attributes->window_type;
+  if (attributes->wclass == GDK_INPUT_ONLY)
+    {
+      /* Backwards compatiblity - we've always ignored
+       * attributes->window_type for input-only windows
+       * before
+       */
+      if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
+       private->window_type = GDK_WINDOW_TEMP;
+      else
+       private->window_type = GDK_WINDOW_CHILD;
+    }
+  else
+    private->window_type = attributes->window_type;
 
   if (attributes->wclass == GDK_INPUT_OUTPUT)
     {
@@ -554,7 +597,7 @@ gdk_window_new (GdkWindow     *parent,
       dwExStyle = WS_EX_TRANSPARENT;
       private->depth = 0;
       private->input_only = TRUE;
-      draw_impl->colormap = gdk_colormap_get_system ();
+      draw_impl->colormap = gdk_screen_get_system_colormap (screen);
       g_object_ref (draw_impl->colormap);
       GDK_NOTE (MISC, g_print ("...GDK_INPUT_ONLY, system colormap"));
     }
@@ -642,21 +685,6 @@ gdk_window_new (GdkWindow     *parent,
 
   mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
   
-#ifdef WITHOUT_WM_CREATE
-  draw_impl->handle =
-    CreateWindowEx (dwExStyle,
-                   MAKEINTRESOURCE(klass),
-                   mbtitle,
-                   dwStyle,
-                   ((attributes_mask & GDK_WA_X) ?
-                    impl->position_info.x - offset_x : CW_USEDEFAULT),
-                   impl->position_info.y - offset_y, 
-                   window_width, window_height,
-                   hparent,
-                   NULL,
-                   _gdk_app_hmodule,
-                   NULL);
-#else
   {
   HWND hwndNew =
     CreateWindowEx (dwExStyle,
@@ -695,7 +723,6 @@ gdk_window_new (GdkWindow     *parent,
   }
   g_object_ref (window);
   gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
-#endif
 
   GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@+%d+%d %p = %p\n",
                           mbtitle,
@@ -715,10 +742,8 @@ gdk_window_new (GdkWindow     *parent,
       return NULL;
     }
 
-#ifdef WITHOUT_WM_CREATE
-  g_object_ref (window);
-  gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
-#endif
+  if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP)
+    gdk_window_set_skip_taskbar_hint (window, TRUE);
 
   gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
                                  (attributes->cursor) :
@@ -727,6 +752,14 @@ gdk_window_new (GdkWindow     *parent,
   return window;
 }
 
+GdkWindow*
+gdk_window_new (GdkWindow     *parent,
+               GdkWindowAttr *attributes,
+               gint           attributes_mask)
+{
+  return gdk_window_new_internal (parent, attributes, attributes_mask, FALSE);
+}
+
 GdkWindow *
 gdk_window_foreign_new_for_display (GdkDisplay      *display,
                                     GdkNativeWindow  anid)
@@ -810,30 +843,31 @@ _gdk_windowing_window_destroy (GdkWindow *window,
   if (private->extension_events != 0)
     _gdk_input_window_destroy (window);
 
-  if (private->window_type == GDK_WINDOW_FOREIGN)
-    {
-      if (!foreign_destroy && (private->parent != NULL))
-       {
-         /* It's somebody else's window, but in our hierarchy,
-          * so reparent it to the root window, and then call
-          * DestroyWindow() on it.
-          */
-         gdk_window_hide (window);
-         gdk_window_reparent (window, NULL, 0, 0);
-         
-         /* Is this too drastic? Many (most?) applications
-          * quit if any window receives WM_QUIT I think.
-          * OTOH, I don't think foreign windows are much
-          * used, so the question is maybe academic.
-          */
-         PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
-       }
-    }
-  else if (!recursing && !foreign_destroy)
+
+  if (!recursing && !foreign_destroy)
     {
       private->destroyed = TRUE;
       DestroyWindow (GDK_WINDOW_HWND (window));
     }
+  gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
+}
+
+void
+_gdk_windowing_window_destroy_foreign (GdkWindow *window)
+{
+  /* It's somebody else's window, but in our hierarchy,
+   * so reparent it to the root window, and then call
+   * DestroyWindow() on it.
+   */
+  gdk_window_hide (window);
+  gdk_window_reparent (window, NULL, 0, 0);
+  
+  /* Is this too drastic? Many (most?) applications
+   * quit if any window receives WM_QUIT I think.
+   * OTOH, I don't think foreign windows are much
+   * used, so the question is maybe academic.
+   */
+  PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
 }
 
 /* This function is called when the window really gone.
@@ -952,7 +986,8 @@ show_window_internal (GdkWindow *window,
 {
   GdkWindowObject *private;
   HWND old_active_window;
-  
+  gboolean focus_on_map = TRUE;
+
   private = (GdkWindowObject *) window;
 
   if (private->destroyed)
@@ -995,9 +1030,27 @@ show_window_internal (GdkWindow *window,
   /* Other cases */
   
   if (!GDK_WINDOW_IS_MAPPED (window))
-    gdk_synthesize_window_state (window,
-                                GDK_WINDOW_STATE_WITHDRAWN,
-                                0);
+    {
+      gdk_synthesize_window_state (window,
+                                  GDK_WINDOW_STATE_WITHDRAWN,
+                                  0);
+      focus_on_map = private->focus_on_map;
+    }
+
+  /* Use SetWindowPos to show transparent windows so automatic redraws
+   * in other windows can be suppressed.
+   */
+  if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
+    {
+      UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
+      if (!raise)
+       flags |= SWP_NOZORDER;
+      if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
+       flags |= SWP_NOACTIVATE;
+
+      SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0, flags);
+      return;
+    }
 
   old_active_window = GetActiveWindow ();
 
@@ -1020,17 +1073,22 @@ show_window_internal (GdkWindow *window,
     ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
   else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
     ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
-  else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
+  else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
     ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
   else
     ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
 
   if (raise)
-    if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
-      SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST, 0, 0, 0, 0,
-                   SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
-    else
-      BringWindowToTop (GDK_WINDOW_HWND (window));
+    {
+      if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
+        SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST, 0, 0, 0, 0,
+                   SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+      else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL
+              || GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
+        SetForegroundWindow (GDK_WINDOW_HWND (window));
+      else
+        BringWindowToTop (GDK_WINDOW_HWND (window));
+    }
   else if (old_active_window != GDK_WINDOW_HWND (window))
     SetActiveWindow (old_active_window);
 }
@@ -1078,8 +1136,8 @@ gdk_window_hide (GdkWindow *window)
   
   if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
     {
-      SetWindowPos(GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
-                  SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
+      SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
+                   SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
     }
   else
     {
@@ -1250,6 +1308,12 @@ gdk_window_reparent (GdkWindow *window,
   g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
 
+  if (GDK_WINDOW_DESTROYED (window) ||
+      (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
+    {
+      return;
+    }
+
   if (!new_parent)
     new_parent = _gdk_parent_root;
 
@@ -2208,6 +2272,22 @@ gdk_window_set_accept_focus (GdkWindow *window,
     private->accept_focus = accept_focus;
 }
 
+void
+gdk_window_set_focus_on_map (GdkWindow *window,
+                            gboolean focus_on_map)
+{
+  GdkWindowObject *private;
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  private = (GdkWindowObject *)window;  
+  
+  focus_on_map = focus_on_map != FALSE;
+
+  if (private->focus_on_map != focus_on_map)
+    private->focus_on_map = focus_on_map;
+}
+
 static HICON
 pixbuf_to_hicon_alpha_winxp (GdkWindow *window,
                             GdkPixbuf *pixbuf)
@@ -2762,6 +2842,38 @@ gdk_window_set_static_gravities (GdkWindow *window,
   return TRUE;
 }
 
+void
+gdk_window_begin_resize_drag (GdkWindow     *window,
+                              GdkWindowEdge  edge,
+                              gint           button,
+                              gint           root_x,
+                              gint           root_y,
+                              guint32        timestamp)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  /* XXX: isn't all this default on win32 ... */  
+}
+
+void
+gdk_window_begin_move_drag (GdkWindow *window,
+                            gint       button,
+                            gint       root_x,
+                            gint       root_y,
+                            guint32    timestamp)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  /* XXX: isn't all this default on win32 ... */  
+}
+
+
 /*
  * Setting window states
  */
@@ -3058,7 +3170,7 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window,
          wa.wclass = GDK_INPUT_OUTPUT;
          wa.width = wa.height = 1;
          wa.event_mask = 0;
-         owner = gdk_window_new (NULL, &wa, 0);
+         owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
        }
 
       SetWindowLong (GDK_WINDOW_HWND (window), GWL_HWNDPARENT,
@@ -3114,6 +3226,12 @@ gdk_window_set_type_hint (GdkWindow        *window,
     case GDK_WINDOW_TYPE_HINT_UTILITY:
       break;
     case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
+      gdk_window_set_decorations (window,
+                                 GDK_DECOR_ALL |
+                                 GDK_DECOR_RESIZEH |
+                                 GDK_DECOR_MENU |
+                                 GDK_DECOR_MINIMIZE |
+                                 GDK_DECOR_MAXIMIZE);
       break;
     case GDK_WINDOW_TYPE_HINT_DOCK:
       break;
@@ -3141,41 +3259,20 @@ gdk_window_shape_combine_region (GdkWindow *window,
   /* XXX: even on X implemented conditional ... */  
 }
 
-void
-gdk_window_begin_resize_drag (GdkWindow     *window,
-                              GdkWindowEdge  edge,
-                              gint           button,
-                              gint           root_x,
-                              gint           root_y,
-                              guint32        timestamp)
+GdkWindow *
+gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  if (GDK_WINDOW_DESTROYED (window))
-    return;
+  g_return_val_if_fail (display == gdk_display_get_default(), NULL);
 
-  /* XXX: isn't all this default on win32 ... */  
+  return gdk_window_lookup (anid);
 }
 
 void
-gdk_window_begin_move_drag (GdkWindow *window,
-                            gint       button,
-                            gint       root_x,
-                            gint       root_y,
-                            guint32    timestamp)
+gdk_window_enable_synchronized_configure (GdkWindow *window)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  if (GDK_WINDOW_DESTROYED (window))
-    return;
-
-  /* XXX: isn't all this default on win32 ... */  
 }
 
-GdkWindow *
-gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
+void
+gdk_window_configure_finished (GdkWindow *window)
 {
-  g_return_val_if_fail (display == gdk_display_get_default(), NULL);
-
-  return gdk_window_lookup (anid);
 }