gdkwindow-win32.c 70.9 KB
Newer Older
1 2
/* GDK - The GIMP Drawing Kit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3
 * Copyright (C) 1998-2002 Tor Lillqvist
4 5
 *
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7 8 9 10 11 12
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16 17 18 19 20 21
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
22
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
23 24 25 26 27 28 29
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

#include <stdlib.h>

30
#include "gdk.h" /* gdk_rectangle_intersect */
31 32 33
#include "gdkevents.h"
#include "gdkpixmap.h"
#include "gdkwindow.h"
34
#include "gdkdisplay.h"
35
#include "gdkprivate-win32.h"
Tor Lillqvist's avatar
Tor Lillqvist committed
36
#include "gdkinput-win32.h"
37

Tor Lillqvist's avatar
Tor Lillqvist committed
38 39 40 41 42 43
static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
static void         gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
							GdkColormap *cmap);
static void         gdk_window_impl_win32_get_size     (GdkDrawable *drawable,
							gint *width,
							gint *height);
44
static GdkRegion*   gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable);
Tor Lillqvist's avatar
Tor Lillqvist committed
45 46 47 48 49 50 51
static void gdk_window_impl_win32_init       (GdkWindowImplWin32      *window);
static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
static void gdk_window_impl_win32_finalize   (GObject                 *object);

static gpointer parent_class = NULL;

GType
52
_gdk_window_impl_win32_get_type (void)
53
{
Tor Lillqvist's avatar
Tor Lillqvist committed
54 55 56
  static GType object_type = 0;

  if (!object_type)
57
    {
Tor Lillqvist's avatar
Tor Lillqvist committed
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
      static const GTypeInfo object_info =
      {
        sizeof (GdkWindowImplWin32Class),
        (GBaseInitFunc) NULL,
        (GBaseFinalizeFunc) NULL,
        (GClassInitFunc) gdk_window_impl_win32_class_init,
        NULL,           /* class_finalize */
        NULL,           /* class_data */
        sizeof (GdkWindowImplWin32),
        0,              /* n_preallocs */
        (GInstanceInitFunc) gdk_window_impl_win32_init,
      };
      
      object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
                                            "GdkWindowImplWin32",
Tor Lillqvist's avatar
Tor Lillqvist committed
73
                                            &object_info, 0);
74
    }
Tor Lillqvist's avatar
Tor Lillqvist committed
75 76 77 78 79 80 81
  
  return object_type;
}

GType
_gdk_window_impl_get_type (void)
{
82
  return _gdk_window_impl_win32_get_type ();
83 84
}

Tor Lillqvist's avatar
Tor Lillqvist committed
85 86 87 88 89 90 91 92 93 94
static void
gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
{
  impl->width = 1;
  impl->height = 1;

  impl->hcursor = NULL;
  impl->hint_flags = 0;
  impl->extension_events_selected = FALSE;
}
95

96
static void
Tor Lillqvist's avatar
Tor Lillqvist committed
97
gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
98
{
Tor Lillqvist's avatar
Tor Lillqvist committed
99 100 101 102 103 104 105 106 107 108
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
  
  parent_class = g_type_class_peek_parent (klass);

  object_class->finalize = gdk_window_impl_win32_finalize;

  drawable_class->set_colormap = gdk_window_impl_win32_set_colormap;
  drawable_class->get_colormap = gdk_window_impl_win32_get_colormap;
  drawable_class->get_size = gdk_window_impl_win32_get_size;
109 110 111 112

  /* Visible and clip regions are the same */
  drawable_class->get_clip_region = gdk_window_impl_win32_get_visible_region;
  drawable_class->get_visible_region = gdk_window_impl_win32_get_visible_region;
Tor Lillqvist's avatar
Tor Lillqvist committed
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
}

static void
gdk_window_impl_win32_finalize (GObject *object)
{
  GdkWindowObject *wrapper;
  GdkDrawableImplWin32 *draw_impl;
  GdkWindowImplWin32 *window_impl;
  
  g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));

  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
  window_impl = GDK_WINDOW_IMPL_WIN32 (object);
  
  wrapper = (GdkWindowObject*) draw_impl->wrapper;

  if (!GDK_WINDOW_DESTROYED (wrapper))
130
    {
Tor Lillqvist's avatar
Tor Lillqvist committed
131
      gdk_win32_handle_table_remove (draw_impl->handle);
132 133
    }

Tor Lillqvist's avatar
Tor Lillqvist committed
134 135
  if (window_impl->hcursor != NULL)
    {
136 137
      if (GetCursor () == window_impl->hcursor)
	SetCursor (NULL);
138 139
      if (!DestroyCursor (window_impl->hcursor))
        WIN32_GDI_FAILED("DestroyCursor");
Tor Lillqvist's avatar
Tor Lillqvist committed
140 141
      window_impl->hcursor = NULL;
    }
142

Tor Lillqvist's avatar
Tor Lillqvist committed
143
  G_OBJECT_CLASS (parent_class)->finalize (object);
144
}
145

Tor Lillqvist's avatar
Tor Lillqvist committed
146 147
static GdkColormap*
gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
148
{
Tor Lillqvist's avatar
Tor Lillqvist committed
149
  GdkDrawableImplWin32 *drawable_impl;
150
  
Tor Lillqvist's avatar
Tor Lillqvist committed
151 152 153
  g_return_val_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable), NULL);

  drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
154

Tor Lillqvist's avatar
Tor Lillqvist committed
155 156
  if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only && 
      drawable_impl->colormap == NULL)
157
    {
Tor Lillqvist's avatar
Tor Lillqvist committed
158
      drawable_impl->colormap = gdk_colormap_get_system ();
159
      gdk_colormap_ref (drawable_impl->colormap);
160
    }
Tor Lillqvist's avatar
Tor Lillqvist committed
161 162 163
  
  return drawable_impl->colormap;
}
164

Tor Lillqvist's avatar
Tor Lillqvist committed
165 166 167 168 169 170 171 172
static void
gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
				    GdkColormap *cmap)
{
  GdkWindowImplWin32 *impl;
  GdkDrawableImplWin32 *draw_impl;
  
  g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
173

Tor Lillqvist's avatar
Tor Lillqvist committed
174 175
  impl = GDK_WINDOW_IMPL_WIN32 (drawable);
  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
176

177 178
  /* chain up */
  GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
179
  
180 181 182 183 184
  if (cmap)
    {
      /* XXX */
      g_print("gdk_window_impl_win32_set_colormap: XXX\n");
    }
Tor Lillqvist's avatar
Tor Lillqvist committed
185 186 187 188 189 190 191 192 193 194 195 196 197
}

static void
gdk_window_impl_win32_get_size (GdkDrawable *drawable,
				gint        *width,
				gint        *height)
{
  g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));

  if (width)
    *width = GDK_WINDOW_IMPL_WIN32 (drawable)->width;
  if (height)
    *height = GDK_WINDOW_IMPL_WIN32 (drawable)->height;
198 199
}

200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
static GdkRegion*
gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable)
{
  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (drawable);
  GdkRectangle result_rect;

  result_rect.x = 0;
  result_rect.y = 0;
  result_rect.width = impl->width;
  result_rect.height = impl->height;

  gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);

  return gdk_region_rectangle (&result_rect);
}

216
void
Tor Lillqvist's avatar
Tor Lillqvist committed
217
_gdk_windowing_window_init (void)
218
{
Tor Lillqvist's avatar
Tor Lillqvist committed
219 220 221 222
  GdkWindowObject *private;
  GdkWindowImplWin32 *impl;
  GdkDrawableImplWin32 *draw_impl;
  RECT rect;
223 224 225
  guint width;
  guint height;

226
  g_assert (_gdk_parent_root == NULL);
Tor Lillqvist's avatar
Tor Lillqvist committed
227 228 229 230 231
  
  SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
  width  = rect.right - rect.left;
  height = rect.bottom - rect.top;

232 233
  _gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
  private = (GdkWindowObject *)_gdk_parent_root;
Tor Lillqvist's avatar
Tor Lillqvist committed
234 235
  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
236
  
237
  draw_impl->handle = _gdk_root_window;
Tor Lillqvist's avatar
Tor Lillqvist committed
238
  draw_impl->wrapper = GDK_DRAWABLE (private);
239 240
  draw_impl->colormap = gdk_colormap_get_system ();
  gdk_colormap_ref (draw_impl->colormap);
Tor Lillqvist's avatar
Tor Lillqvist committed
241 242 243 244 245
  
  private->window_type = GDK_WINDOW_ROOT;
  private->depth = gdk_visual_get_system ()->depth;
  impl->width = width;
  impl->height = height;
246

247 248 249 250 251 252 253 254 255 256 257 258 259 260
  _gdk_window_init_position (GDK_WINDOW (private));

  gdk_win32_handle_table_insert (&_gdk_root_window, _gdk_parent_root);
}

static const gchar *
get_default_title (void)
{
  const char *title;
  title = g_get_application_name ();
  if (!title)
    title = g_get_prgname ();

  return title;
Tor Lillqvist's avatar
Tor Lillqvist committed
261 262 263 264 265
}

/* The Win API function AdjustWindowRect may return negative values
 * resulting in obscured title bars. This helper function is coreccting it.
 */
266
static BOOL
Tor Lillqvist's avatar
Tor Lillqvist committed
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
SafeAdjustWindowRectEx (RECT* lpRect,
			DWORD dwStyle, 
			BOOL  bMenu, 
			DWORD dwExStyle)
{
  if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
    {
      WIN32_API_FAILED ("AdjustWindowRectEx");
      return FALSE;
    }
  if (lpRect->left < 0)
    {
      lpRect->right -= lpRect->left;
      lpRect->left = 0;
    }
  if (lpRect->top < 0)
    {
      lpRect->bottom -= lpRect->top;
      lpRect->top = 0;
    }
  return TRUE;
288 289 290 291 292 293 294 295 296
}

/* RegisterGdkClass
 *   is a wrapper function for RegisterWindowClassEx.
 *   It creates at least one unique class for every 
 *   GdkWindowType. If support for single window-specific icons
 *   is ever needed (e.g Dialog specific), every such window should
 *   get its own class
 */
297
static ATOM
Tor Lillqvist's avatar
Tor Lillqvist committed
298
RegisterGdkClass (GdkWindowType wtype)
299 300 301 302 303 304 305 306 307
{
  static ATOM klassTOPLEVEL = 0;
  static ATOM klassDIALOG   = 0;
  static ATOM klassCHILD    = 0;
  static ATOM klassTEMP     = 0;
  static HICON hAppIcon = NULL;
  static WNDCLASSEX wcl; 
  ATOM klass = 0;

308
  wcl.cbSize = sizeof (WNDCLASSEX);
309 310 311
  wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
                  * on WM_SIZE and WM_MOVE. Flicker, Performance!
                  */
312
  wcl.lpfnWndProc = _gdk_win32_window_procedure;
313 314
  wcl.cbClsExtra = 0;
  wcl.cbWndExtra = 0;
315
  wcl.hInstance = _gdk_app_hmodule;
316 317 318 319
  wcl.hIcon = 0;
  /* initialize once! */
  if (0 == hAppIcon)
    {
320
      gchar sLoc [MAX_PATH+1];
321

322
      if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
323
	{
324
	  hAppIcon = ExtractIcon (_gdk_app_hmodule, sLoc, 0);
325 326
	  if (0 == hAppIcon)
	    {
327 328
	      if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
		hAppIcon = ExtractIcon (_gdk_dll_hinstance, sLoc, 0);
329 330
	    }
	}
331 332
      if (0 == hAppIcon) 
	hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
333 334 335 336 337 338
    }

  wcl.lpszMenuName = NULL;
  wcl.hIconSm = 0;

  /* initialize once per class */
Hans Breuer's avatar
updated  
Hans Breuer committed
339 340 341 342 343
  /*
   * HB: Setting the background brush leads to flicker, because we
   * don't get asked how to clear the background. This is not what
   * we want, at least not for input_only windows ...
   */
344 345 346
#define ONCE_PER_CLASS() \
  wcl.hIcon = CopyIcon (hAppIcon); \
  wcl.hIconSm = CopyIcon (hAppIcon); \
347
  wcl.hbrBackground = NULL; \
348 349 350
  wcl.hCursor = LoadCursor (NULL, IDC_ARROW); 
  
  switch (wtype)
351 352 353 354 355 356 357 358 359 360 361 362
    {
    case GDK_WINDOW_TOPLEVEL:
      if (0 == klassTOPLEVEL)
	{
	  wcl.lpszClassName = "gdkWindowToplevel";
	  
	  ONCE_PER_CLASS();
	  klassTOPLEVEL = RegisterClassEx (&wcl);
	}
      klass = klassTOPLEVEL;
      break;
      
363 364
    case GDK_WINDOW_CHILD:
      if (0 == klassCHILD)
Tor Lillqvist's avatar
Tor Lillqvist committed
365 366 367 368 369 370 371
	{
	  wcl.lpszClassName = "gdkWindowChild";
	  
	  wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
	  ONCE_PER_CLASS();
	  klassCHILD = RegisterClassEx (&wcl);
	}
372 373
      klass = klassCHILD;
      break;
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
      
    case GDK_WINDOW_DIALOG:
      if (0 == klassDIALOG)
	{
	  wcl.lpszClassName = "gdkWindowDialog";
	  wcl.style |= CS_SAVEBITS;
	  ONCE_PER_CLASS();
	  klassDIALOG = RegisterClassEx (&wcl);
	}
      klass = klassDIALOG;
      break;
      
    case GDK_WINDOW_TEMP:
      if (0 == klassTEMP)
	{
	  wcl.lpszClassName = "gdkWindowTemp";
	  wcl.style |= CS_SAVEBITS;
	  ONCE_PER_CLASS();
	  klassTEMP = RegisterClassEx (&wcl);
	}
      klass = klassTEMP;
      break;
      
    default:
      g_assert_not_reached ();
      break;
    }
  
402 403 404 405 406
  if (klass == 0)
    {
      WIN32_API_FAILED ("RegisterClassEx");
      g_error ("That is a fatal error");
    }
407
  return klass;
408
}
409 410 411 412 413 414

GdkWindow*
gdk_window_new (GdkWindow     *parent,
		GdkWindowAttr *attributes,
		gint           attributes_mask)
{
415 416
  HANDLE hparent;
  ATOM klass = 0;
417
  DWORD dwStyle = 0, dwExStyle;
418
  RECT rect;
419
  GdkWindow *window;
Tor Lillqvist's avatar
Tor Lillqvist committed
420 421 422
  GdkWindowObject *private;
  GdkWindowImplWin32 *impl;
  GdkDrawableImplWin32 *draw_impl;
423
  GdkVisual *visual;
424
  const gchar *title;
425 426 427 428 429
  char *mbtitle;

  g_return_val_if_fail (attributes != NULL, NULL);

  if (!parent)
430
    parent = _gdk_parent_root;
431

Tor Lillqvist's avatar
Tor Lillqvist committed
432 433
  g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
  
434 435 436 437 438 439 440 441
  GDK_NOTE (MISC,
	    g_print ("gdk_window_new: %s\n",
		     (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
		      (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
		       (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
			(attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
			 "???"))))));

Tor Lillqvist's avatar
Tor Lillqvist committed
442
  if (GDK_WINDOW_DESTROYED (parent))
443
    return NULL;
Tor Lillqvist's avatar
Tor Lillqvist committed
444 445
  
  hparent = GDK_WINDOW_HWND (parent);
446

Tor Lillqvist's avatar
Tor Lillqvist committed
447 448 449 450 451
  window = g_object_new (GDK_TYPE_WINDOW, NULL);
  private = (GdkWindowObject *)window;
  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
  draw_impl->wrapper = GDK_DRAWABLE (window);
452

453 454 455 456 457 458
  /* Windows with a foreign parent are treated as if they are children
   * of the root window, except for actual creation.
   */
  if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
    parent = _gdk_parent_root;
  
Tor Lillqvist's avatar
Tor Lillqvist committed
459
  private->parent = (GdkWindowObject *)parent;
460

Tor Lillqvist's avatar
Tor Lillqvist committed
461
  if (attributes_mask & GDK_WA_X)
462
    private->x = attributes->x;
Tor Lillqvist's avatar
Tor Lillqvist committed
463
  else
464
    private->x = 0;
Tor Lillqvist's avatar
Tor Lillqvist committed
465 466
  
  if (attributes_mask & GDK_WA_Y)
467
    private->y = attributes->y;
Tor Lillqvist's avatar
Tor Lillqvist committed
468
  else if (attributes_mask & GDK_WA_X)
469
    private->y = 100;		/* ??? We must put it somewhere... */
Tor Lillqvist's avatar
Tor Lillqvist committed
470
  else
471
    private->y = 0;
Tor Lillqvist's avatar
Tor Lillqvist committed
472
  
473 474 475 476 477
  if (attributes_mask & GDK_WA_VISUAL)
    visual = attributes->visual;
  else
    visual = gdk_visual_get_system ();

478 479 480 481
  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;
482 483 484 485

  if (attributes->wclass == GDK_INPUT_OUTPUT)
    {
      dwExStyle = 0;
Tor Lillqvist's avatar
Tor Lillqvist committed
486 487 488 489

      private->input_only = FALSE;
      private->depth = visual->depth;
      
490
      if (attributes_mask & GDK_WA_COLORMAP)
Tor Lillqvist's avatar
Tor Lillqvist committed
491 492 493 494
	{
	  draw_impl->colormap = attributes->colormap;
          gdk_colormap_ref (attributes->colormap);
        }
495
      else
Tor Lillqvist's avatar
Tor Lillqvist committed
496
	{
497
	  draw_impl->colormap = gdk_colormap_get_system ();
Tor Lillqvist's avatar
Tor Lillqvist committed
498
	}
499 500 501 502
    }
  else
    {
      dwExStyle = WS_EX_TRANSPARENT;
Tor Lillqvist's avatar
Tor Lillqvist committed
503 504
      private->depth = 0;
      private->input_only = TRUE;
Hans Breuer's avatar
Hans Breuer committed
505 506 507
      draw_impl->colormap = gdk_colormap_get_system ();
      gdk_colormap_ref (draw_impl->colormap);
      GDK_NOTE (MISC, g_print ("...GDK_INPUT_ONLY, system colormap\n"));
508 509
    }

Tor Lillqvist's avatar
Tor Lillqvist committed
510
  switch (private->window_type)
511 512 513
    {
    case GDK_WINDOW_TOPLEVEL:
      dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
514
      hparent = _gdk_root_window;
515
      break;
Tor Lillqvist's avatar
Tor Lillqvist committed
516

517 518 519
    case GDK_WINDOW_CHILD:
      dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
      break;
Tor Lillqvist's avatar
Tor Lillqvist committed
520

521 522
    case GDK_WINDOW_DIALOG:
      dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
523
#if 0
524
      dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
525
#endif
526
      hparent = _gdk_root_window;
527
      break;
Tor Lillqvist's avatar
Tor Lillqvist committed
528

529
    case GDK_WINDOW_TEMP:
Hans Breuer's avatar
Hans Breuer committed
530 531
      dwStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
      /* a temp window is not necessarily a top level window */
532
      dwStyle |= (_gdk_parent_root == parent ? WS_POPUP : WS_CHILDWINDOW);
533 534
      dwExStyle |= WS_EX_TOOLWINDOW;
      break;
Tor Lillqvist's avatar
Tor Lillqvist committed
535

536 537 538 539
    case GDK_WINDOW_ROOT:
      g_error ("cannot make windows of type GDK_WINDOW_ROOT");
      break;

540 541 542
    default:
      g_assert_not_reached ();
    }
543

Tor Lillqvist's avatar
Tor Lillqvist committed
544
  if (private->window_type != GDK_WINDOW_CHILD)
545
    {
546 547
      rect.left = private->x;
      rect.top = private->y;
Tor Lillqvist's avatar
Tor Lillqvist committed
548 549
      rect.right = rect.left + impl->width;
      rect.bottom = rect.top + impl->height;
550

551
      SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
552

553 554 555 556
      private->x = rect.left;
      private->y = rect.top;
      impl->width = rect.right - rect.left;
      impl->height = rect.bottom - rect.top;
557
    }
558 559 560 561 562 563 564 565

  _gdk_window_init_position (GDK_WINDOW (private));

  if (impl->position_info.big)
    private->guffaw_gravity = TRUE;

  if (attributes_mask & GDK_WA_TITLE)
    title = attributes->title;
566
  else
567 568 569 570 571 572 573
    title = get_default_title ();
  if (!title || !*title)
    title = "GDK client window";

  private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
      
  if (private->parent && private->parent->guffaw_gravity)
574
    {
575
      /* XXX ??? */
576 577
    }

578 579 580 581 582
  if (private->parent)
    private->parent->children = g_list_prepend (private->parent->children, window);

  klass = RegisterGdkClass (private->window_type);

583
  mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
584
  
Tor Lillqvist's avatar
Update.  
Tor Lillqvist committed
585
#ifdef WITHOUT_WM_CREATE
586 587 588 589 590 591 592 593 594 595 596 597 598
  draw_impl->handle =
    CreateWindowEx (dwExStyle,
		    MAKEINTRESOURCE(klass),
		    mbtitle,
		    dwStyle,
		    ((attributes_mask & GDK_WA_X) ?
		     impl->position_info.x : CW_USEDEFAULT),
		    impl->position_info.y, 
		    impl->position_info.width, impl->position_info.height,
		    hparent,
		    NULL,
		    _gdk_app_hmodule,
		    NULL);
Tor Lillqvist's avatar
Update.  
Tor Lillqvist committed
599 600 601 602 603 604 605
#else
  {
  HWND hwndNew =
    CreateWindowEx (dwExStyle,
		    MAKEINTRESOURCE(klass),
		    mbtitle,
		    dwStyle,
606 607 608
		    ((attributes_mask & GDK_WA_X) ?
		     impl->position_info.x : CW_USEDEFAULT),
		    impl->position_info.y, 
Hans Breuer's avatar
Hans Breuer committed
609
		    impl->position_info.width, impl->position_info.height,
Tor Lillqvist's avatar
Update.  
Tor Lillqvist committed
610 611
		    hparent,
		    NULL,
612
		    _gdk_app_hmodule,
Tor Lillqvist's avatar
Update.  
Tor Lillqvist committed
613 614 615
		    window);
  if (GDK_WINDOW_HWND (window) != hwndNew)
    {
616 617 618
      g_warning("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
		GDK_WINDOW_HWND (window),
		hwndNew);
Tor Lillqvist's avatar
Update.  
Tor Lillqvist committed
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638

      /* HB: IHMO due to a race condition the handle was increased by
       * one, which causes much trouble. Because I can't find the 
       * real bug, try to workaround it ...
       * To reproduce: compile with MSVC 5, DEBUG=1
       */
# if 0
      gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
      GDK_WINDOW_HWND (window) = hwndNew;
      gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
# else
      /* the old behaviour, but with warning */
      GDK_WINDOW_HWND (window) = hwndNew;
# endif

    }
  }
  gdk_drawable_ref (window);
  gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
#endif
639 640

  GDK_NOTE (MISC,
641
	    g_print ("... \"%s\" %dx%d@+%d+%d %p = %p\n",
642
		     mbtitle,
643 644 645 646
		     impl->position_info.width, impl->position_info.height,
		     ((attributes_mask & GDK_WA_X) ?
		      impl->position_info.x : CW_USEDEFAULT),
		     impl->position_info.y, 
647
		     hparent,
648
		     GDK_WINDOW_HWND (window)));
649 650 651

  g_free (mbtitle);

Tor Lillqvist's avatar
Tor Lillqvist committed
652
  if (draw_impl->handle == NULL)
653
    {
654
      WIN32_API_FAILED ("CreateWindowEx");
Tor Lillqvist's avatar
Tor Lillqvist committed
655
      g_object_unref ((GObject *) window);
656 657 658
      return NULL;
    }

Tor Lillqvist's avatar
Update.  
Tor Lillqvist committed
659
#ifdef WITHOUT_WM_CREATE
660
  gdk_drawable_ref (window);
Tor Lillqvist's avatar
Update.  
Tor Lillqvist committed
661 662
  gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
#endif
663 664 665 666 667 668 669 670 671

  gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
				  (attributes->cursor) :
				  NULL));

  return window;
}

GdkWindow *
672 673
gdk_window_foreign_new_for_display (GdkDisplay      *display,
                                    GdkNativeWindow  anid)
674 675
{
  GdkWindow *window;
Tor Lillqvist's avatar
Tor Lillqvist committed
676 677 678 679
  GdkWindowObject *private;
  GdkWindowImplWin32 *impl;
  GdkDrawableImplWin32 *draw_impl;

680 681 682 683
  HANDLE parent;
  RECT rect;
  POINT point;

Owen Taylor's avatar
Owen Taylor committed
684
  g_return_val_if_fail (display == gdk_display_get_default (), NULL);
685

Tor Lillqvist's avatar
Tor Lillqvist committed
686 687 688 689 690
  window = g_object_new (GDK_TYPE_WINDOW, NULL);
  private = (GdkWindowObject *)window;
  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
  draw_impl->wrapper = GDK_DRAWABLE (window);
691
  parent = GetParent ((HWND)anid);
Tor Lillqvist's avatar
Tor Lillqvist committed
692
  
Tor Lillqvist's avatar
Tor Lillqvist committed
693
  private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
694 695
  if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
    private->parent = (GdkWindowObject *)_gdk_parent_root;
Tor Lillqvist's avatar
Tor Lillqvist committed
696
  
697
  private->parent->children = g_list_prepend (private->parent->children, window);
698

Tor Lillqvist's avatar
Tor Lillqvist committed
699
  draw_impl->handle = (HWND) anid;
700 701 702 703
  GetClientRect ((HWND) anid, &rect);
  point.x = rect.left;
  point.y = rect.right;
  ClientToScreen ((HWND) anid, &point);
704
  if (parent != _gdk_root_window)
705 706 707
    ScreenToClient (parent, &point);
  private->x = point.x;
  private->y = point.y;
Tor Lillqvist's avatar
Tor Lillqvist committed
708 709 710 711
  impl->width = rect.right - rect.left;
  impl->height = rect.bottom - rect.top;
  private->window_type = GDK_WINDOW_FOREIGN;
  private->destroyed = FALSE;
712
  private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
Hans Breuer's avatar
updated  
Hans Breuer committed
713 714 715 716
  if (IsWindowVisible ((HWND) anid))
    private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
  else
    private->state |= GDK_WINDOW_STATE_WITHDRAWN;
Tor Lillqvist's avatar
Tor Lillqvist committed
717
  private->depth = gdk_visual_get_system ()->depth;
718

719 720
  _gdk_window_init_position (GDK_WINDOW (private));

721
  gdk_drawable_ref (window);
Tor Lillqvist's avatar
Update.  
Tor Lillqvist committed
722
  gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
723 724 725 726

  return window;
}

727 728 729 730 731 732
GdkWindow*
gdk_window_lookup (GdkNativeWindow hwnd)
{
  return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd); 
}

733 734 735 736
void
_gdk_windowing_window_destroy (GdkWindow *window,
			       gboolean   recursing,
			       gboolean   foreign_destroy)
737
{
Tor Lillqvist's avatar
Tor Lillqvist committed
738
  GdkWindowObject *private = (GdkWindowObject *)window;
739

Tor Lillqvist's avatar
Tor Lillqvist committed
740 741
  g_return_if_fail (GDK_IS_WINDOW (window));
  
742 743
  GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy %p\n",
			   GDK_WINDOW_HWND (window)));
744

745
  if (private->extension_events != 0)
746
    _gdk_input_window_destroy (window);
747

Tor Lillqvist's avatar
Tor Lillqvist committed
748
  if (private->window_type == GDK_WINDOW_FOREIGN)
749
    {
750
      if (!foreign_destroy && (private->parent != NULL))
751
	{
Tor Lillqvist's avatar
Tor Lillqvist committed
752
	  /* It's somebody else's window, but in our hierarchy,
753 754 755 756 757
	   * so reparent it to the root window, and then call
	   * DestroyWindow() on it.
	   */
	  gdk_window_hide (window);
	  gdk_window_reparent (window, NULL, 0, 0);
758
	  
759 760 761 762 763
	  /* 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.
	   */
Tor Lillqvist's avatar
Tor Lillqvist committed
764
	  PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
765 766
	}
    }
767
  else if (!recursing && !foreign_destroy)
768 769 770 771
    {
      private->destroyed = TRUE;
      DestroyWindow (GDK_WINDOW_HWND (window));
    }
772 773
}

774 775
/* This function is called when the window really gone.
 */
776 777 778 779
void
gdk_window_destroy_notify (GdkWindow *window)
{
  g_return_if_fail (window != NULL);
780
  g_return_if_fail (GDK_IS_WINDOW (window));
781

782
  GDK_NOTE (EVENTS,
783 784
	    g_print ("gdk_window_destroy_notify: %p  %s\n",
		     GDK_WINDOW_HWND (window),
Tor Lillqvist's avatar
Tor Lillqvist committed
785
		     (GDK_WINDOW_DESTROYED (window) ? "(destroyed)" : "")));
786

Tor Lillqvist's avatar
Tor Lillqvist committed
787
  if (!GDK_WINDOW_DESTROYED (window))
788
    {
Tor Lillqvist's avatar
Tor Lillqvist committed
789
      if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
790 791
	g_warning ("window %p unexpectedly destroyed",
		   GDK_WINDOW_HWND (window));
792

793
      _gdk_window_destroy (window, TRUE);
794 795
    }
  
Tor Lillqvist's avatar
Tor Lillqvist committed
796
  gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
797
  gdk_drawable_unref (window);
798 799
}

Hans Breuer's avatar
Hans Breuer committed
800 801
static void
show_window_internal (GdkWindow *window,
Tor Lillqvist's avatar
Tor Lillqvist committed
802 803
                      gboolean   raise,
		      gboolean   deiconify)
804
{
Tor Lillqvist's avatar
Tor Lillqvist committed
805
  GdkWindowObject *private;
Tor Lillqvist's avatar
Tor Lillqvist committed
806
  HWND old_active_window;
Tor Lillqvist's avatar
Tor Lillqvist committed
807
  
Hans Breuer's avatar
Hans Breuer committed
808 809
  private = GDK_WINDOW_OBJECT (window);

Tor Lillqvist's avatar
Tor Lillqvist committed
810 811
  if (private->destroyed)
    return;
812

Tor Lillqvist's avatar
Tor Lillqvist committed
813 814 815 816 817 818 819 820 821 822 823 824 825 826 827
  GDK_NOTE (MISC, g_print ("show_window_internal: %p %s%s%s\n",
			   GDK_WINDOW_HWND (window),
			   _gdk_win32_window_state_to_string (private->state),
			   (raise ? " raise" : ""),
			   (deiconify ? " deiconify" : "")));
  
  /* If asked to show (not deiconify) an withdrawn and iconified
   * window, do that.
   */
  if (!deiconify &&
      !GDK_WINDOW_IS_MAPPED (window) &&
      (private->state & GDK_WINDOW_STATE_ICONIFIED))
    {	
      ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
      return;
828
    }
Tor Lillqvist's avatar
Tor Lillqvist committed
829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869
  
  /* If asked to just show an iconified window, do nothing. */
  if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED))
    return;
  
  /* If asked to deiconify an already noniconified window, do
   * nothing. (Especially, don't cause the window to rise and
   * activate. There are different calls for that.)
   */
  if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED))
    return;
  
  /* If asked to show (but not raise) a window that is already
   * visible, do nothing.
   */
  if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
    return;

  /* Other cases */
  
  if (!GDK_WINDOW_IS_MAPPED (window))
    gdk_synthesize_window_state (window,
				 GDK_WINDOW_STATE_WITHDRAWN,
				 0);
  if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
    {
      /* Don't really know if this makes sense, can't remember whether
       * this case is handled like this because it is necessary, or
       * if this is just old crap.
       */
      SetWindowPos(GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0,
		   SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE);
      return;
    }

  old_active_window = GetActiveWindow ();

  if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
    ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
  else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
    ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
Tor Lillqvist's avatar
Tor Lillqvist committed
870 871
  else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
    ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
Tor Lillqvist's avatar
Tor Lillqvist committed
872 873 874 875
  else
    ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);

  if (raise)
Tor Lillqvist's avatar
Tor Lillqvist committed
876 877 878 879 880
    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));
Tor Lillqvist's avatar
Tor Lillqvist committed
881 882
  else if (old_active_window != GDK_WINDOW_HWND (window))
    SetActiveWindow (old_active_window);
883 884
}

Hans Breuer's avatar
Hans Breuer committed
885 886 887 888 889
void
gdk_window_show_unraised (GdkWindow *window)
{
  g_return_if_fail (GDK_IS_WINDOW (window));
  
Tor Lillqvist's avatar
Tor Lillqvist committed
890
  show_window_internal (window, FALSE, FALSE);
Hans Breuer's avatar
Hans Breuer committed
891 892 893 894 895 896 897
}

void
gdk_window_show (GdkWindow *window)
{
  g_return_if_fail (GDK_IS_WINDOW (window));

Tor Lillqvist's avatar
Tor Lillqvist committed
898
  show_window_internal (window, TRUE, FALSE);
Hans Breuer's avatar
Hans Breuer committed
899 900
}

901 902 903
void
gdk_window_hide (GdkWindow *window)
{
Tor Lillqvist's avatar
Tor Lillqvist committed
904 905
  GdkWindowObject *private;
  
906 907
  g_return_if_fail (window != NULL);

Tor Lillqvist's avatar
Tor Lillqvist committed
908 909
  private = (GdkWindowObject*) window;
  if (!private->destroyed)
910
    {
Tor Lillqvist's avatar
Tor Lillqvist committed
911 912 913
      GDK_NOTE (MISC, g_print ("gdk_window_hide: %p %s\n",
			       GDK_WINDOW_HWND (window),
			       _gdk_win32_window_state_to_string (private->state)));
Tor Lillqvist's avatar
Tor Lillqvist committed
914

Tor Lillqvist's avatar
Tor Lillqvist committed
915 916 917 918
      if (GDK_WINDOW_IS_MAPPED (window))
        gdk_synthesize_window_state (window,
                                     0,
                                     GDK_WINDOW_STATE_WITHDRAWN);
919 920 921

      _gdk_window_clear_update_area (window);

Tor Lillqvist's avatar
Tor Lillqvist committed
922 923 924
      if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
	ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);

Tor Lillqvist's avatar
Tor Lillqvist committed
925 926 927 928 929 930 931 932 933
      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);
	}
      else
	{
	  ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
	}
934 935 936 937 938 939
    }
}

void
gdk_window_withdraw (GdkWindow *window)
{
Tor Lillqvist's avatar
Tor Lillqvist committed
940 941
  GdkWindowObject *private;
  
942
  g_return_if_fail (window != NULL);
Tor Lillqvist's avatar
Tor Lillqvist committed
943 944 945
  
  private = (GdkWindowObject*) window;
  if (!private->destroyed)
946
    {
Tor Lillqvist's avatar
Tor Lillqvist committed
947 948 949
      GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %p %s\n",
			       GDK_WINDOW_HWND (window),
			       _gdk_win32_window_state_to_string (private->state)));
950

Tor Lillqvist's avatar
Tor Lillqvist committed
951
      gdk_window_hide (window);	/* ??? */
952 953 954 955 956 957 958 959
    }
}

void
gdk_window_move (GdkWindow *window,
		 gint       x,
		 gint       y)
{
Tor Lillqvist's avatar
Tor Lillqvist committed
960 961
  GdkWindowObject *private = (GdkWindowObject *)window;
  GdkWindowImplWin32 *impl;
962 963
  RECT rect;
  LONG style, extended_style;
964 965

  g_return_if_fail (window != NULL);
Tor Lillqvist's avatar
Tor Lillqvist committed
966
  g_return_if_fail (GDK_IS_WINDOW (window));
967

Tor Lillqvist's avatar
Tor Lillqvist committed
968 969 970
  GDK_NOTE (MISC, g_print ("gdk_window_move: %p +%d+%d\n",
			   GDK_WINDOW_HWND (window), x, y));
      
Tor Lillqvist's avatar
Tor Lillqvist committed
971 972
  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
  
Hans Breuer's avatar
Hans Breuer committed
973 974 975 976 977 978 979
  if (!GDK_WINDOW_DESTROYED (window))
    {
      if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
	_gdk_window_move_resize_child (window, x, y,
				       impl->width, impl->height);
      else
	{
980 981 982 983 984 985 986 987
	  /* SetWindowPos uses non-client coordinates, we have client
	   * coordinates. Thus offset them.
	   */
	  style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
	  extended_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
	  GetClientRect (GDK_WINDOW_HWND (window), &rect);
	  AdjustWindowRectEx (&rect, style, FALSE, extended_style);

Hans Breuer's avatar
Hans Breuer committed
988
	  if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL,
989
	                     x + rect.left, y + rect.top, 0, 0,
Hans Breuer's avatar
Hans Breuer committed
990 991 992 993
	                     SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER))
	    WIN32_API_FAILED ("SetWindowPos");
	}
    }
994 995 996 997 998 999 1000
}

void
gdk_window_resize (GdkWindow *window,
		   gint       width,
		   gint       height)
{
Tor Lillqvist's avatar
Tor Lillqvist committed
1001 1002 1003
  GdkWindowObject *private = (GdkWindowObject*) window;
  GdkWindowImplWin32 *impl;
  int x, y;
1004 1005

  g_return_if_fail (window != NULL);
Tor Lillqvist's avatar
Tor Lillqvist committed
1006
  g_return_if_fail (GDK_IS_WINDOW (window));
1007

Tor Lillqvist's avatar
Tor Lillqvist committed
1008
  if (width < 1)
1009
    width = 1;
Tor Lillqvist's avatar
Tor Lillqvist committed
1010
  if (height < 1)
1011 1012
    height = 1;

Tor Lillqvist's avatar
Tor Lillqvist committed
1013 1014 1015
  GDK_NOTE (MISC, g_print ("gdk_window_resize: %p  %dx%d\n",
			   GDK_WINDOW_HWND (window), width, height));

Tor Lillqvist's avatar
Tor Lillqvist committed
1016 1017
  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
  
Hans Breuer's avatar
Hans Breuer committed
1018
  if (!GDK_WINDOW_DESTROYED (window))
1019
    {
Hans Breuer's avatar
Hans Breuer committed
1020 1021 1022 1023
      if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
	_gdk_window_move_resize_child (window, private->x, private->y,
				       width, height);
      else
1024 1025 1026 1027 1028 1029 1030 1031
	{
	  POINT pt;
	  RECT rect;
	  DWORD dwStyle;
	  DWORD dwExStyle;

	  pt.x = 0;
	  pt.y = 0; 
Tor Lillqvist's avatar
Tor Lillqvist committed
1032
	  ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1033 1034 1035 1036 1037
	  rect.left = pt.x;
	  rect.top = pt.y;
	  rect.right = pt.x + width;
	  rect.bottom = pt.y + height;

Tor Lillqvist's avatar
Tor Lillqvist committed
1038 1039
	  dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
	  dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1040
	  if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
1041
	    WIN32_API_FAILED ("AdjustWindowRectEx");
1042 1043 1044 1045 1046

	  x = rect.left;
	  y = rect.top;
	  width = rect.right - rect.left;
	  height = rect.bottom - rect.top;
Hans Breuer's avatar
Hans Breuer committed
1047 1048 1049 1050
	  if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL,
	                     x, y, width, height,
	                     SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER))
	    WIN32_API_FAILED ("SetWindowPos");
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
	}
      private->resize_count += 1;
    }
}

void
gdk_window_move_resize (GdkWindow *window,
			gint       x,
			gint       y,
			gint       width,
			gint       height)
{
Tor Lillqvist's avatar
Tor Lillqvist committed
1063 1064
  GdkWindowObject *private = (GdkWindowObject*) window;
  GdkWindowImplWin32 *impl;
1065 1066

  g_return_if_fail (window != NULL);
Tor Lillqvist's avatar
Tor Lillqvist committed
1067
  g_return_if_fail (GDK_IS_WINDOW (window));
1068

Tor Lillqvist's avatar
Tor Lillqvist committed
1069
  if (width < 1)
1070
    width = 1;
Tor Lillqvist's avatar
Tor Lillqvist committed
1071
  if (height < 1)
1072
    height = 1;
Tor Lillqvist's avatar
Tor Lillqvist committed
1073 1074
  
  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1075

Tor Lillqvist's avatar
Tor Lillqvist committed
1076
  if (!private->destroyed)
1077 1078 1079 1080 1081
    {
      RECT rect;
      DWORD dwStyle;
      DWORD dwExStyle;

1082 1083
      GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %p %dx%d@+%d+%d\n",
			       GDK_WINDOW_HWND (window),
Tor Lillqvist's avatar
Tor Lillqvist committed
1084
			       width, height, x, y));
1085
      
Tor Lillqvist's avatar
Tor Lillqvist committed
1086 1087 1088
      if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
	_gdk_window_move_resize_child (window, x, y, width, height);
      else
1089
	{
Tor Lillqvist's avatar
Tor Lillqvist committed
1090 1091 1092 1093
	  rect.left = x;
	  rect.top = y;
	  rect.right = x + width;
	  rect.bottom = y + height;
1094

Tor Lillqvist's avatar
Tor Lillqvist committed
1095 1096 1097 1098 1099
	  dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
	  dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
	  if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
	    WIN32_API_FAILED ("AdjustWindowRectEx");

1100 1101
	  GDK_NOTE (MISC, g_print ("...SetWindowPos(%p,%ldx%ld@+%ld+%ld)\n",
				   GDK_WINDOW_HWND (window),
Tor Lillqvist's avatar
Tor Lillqvist committed
1102 1103
				   rect.right - rect.left, rect.bottom - rect.top,
				   rect.left, rect.top));
Hans Breuer's avatar
Hans Breuer committed
1104 1105 1106 1107 1108
	  if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL,
	                     rect.left, rect.top,
	                     rect.right - rect.left, rect.bottom - rect.top,
	                     SWP_NOACTIVATE | SWP_NOZORDER))
	    WIN32_API_FAILED ("SetWindowPos");
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
	}
    }
}

void
gdk_window_reparent (GdkWindow *window,
		     GdkWindow *new_parent,
		     gint       x,
		     gint       y)
{
Tor Lillqvist's avatar
Tor Lillqvist committed
1119 1120 1121 1122
  GdkWindowObject *window_private;
  GdkWindowObject *parent_private;
  GdkWindowObject *old_parent_private;
  GdkWindowImplWin32 *impl;
1123 1124

  g_return_if_fail (window != NULL);
1125 1126 1127
  g_return_if_fail (GDK_IS_WINDOW (window));
  g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
  g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1128 1129

  if (!new_parent)
1130
    new_parent = _gdk_parent_root;
1131

Tor Lillqvist's avatar
Tor Lillqvist committed
1132 1133 1134 1135
  window_private = (GdkWindowObject*) window;
  old_parent_private = (GdkWindowObject *) window_private->parent;
  parent_private = (GdkWindowObject*) new_parent;
  impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1136

Tor Lillqvist's avatar
Tor Lillqvist committed
1137
  if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
1138
    {
1139 1140 1141
      GDK_NOTE (MISC, g_print ("gdk_window_reparent: %p %p\n",
			       GDK_WINDOW_HWND (window),
			       GDK_WINDOW_HWND (new_parent)));
Tor Lillqvist's avatar
Tor Lillqvist committed
1142 1143
      if (!SetParent (GDK_WINDOW_HWND (window),
		      GDK_WINDOW_HWND (new_parent)))
1144
	WIN32_API_FAILED ("SetParent");
1145

Tor Lillqvist's avatar
Tor Lillqvist committed
1146 1147
      if (!MoveWindow (GDK_WINDOW_HWND (window),
		       x, y, impl->width, impl->height, TRUE))
1148
	WIN32_API_FAILED ("MoveWindow");
1149
    }
1150 1151 1152 1153 1154 1155

  /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
   * the root window
   */
  if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
    new_parent = _gdk_parent_root;
1156
  
Tor Lillqvist's avatar
Tor Lillqvist committed
1157
  window_private->parent = (GdkWindowObject *)new_parent;
1158 1159

  if (old_parent_private)
1160 1161
    old_parent_private->children =
      g_list_remove (old_parent_private->children, window);
1162

1163
#if 0
1164 1165 1166 1167
  if ((old_parent_private &&
       (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
      (!old_parent_private && parent_private->guffaw_gravity))
    gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1168 1169
#endif

1170
  parent_private->children = g_list_prepend (parent_private->children, window);
1171
  _gdk_window_init_position (GDK_WINDOW (window_private));
1172 1173 1174
}

void
1175 1176 1177 1178 1179
_gdk_windowing_window_clear_area (GdkWindow *window,
				  gint       x,
				  gint       y,
				  gint       width,
				  gint       height)
1180
{
Tor Lillqvist's avatar
Tor Lillqvist committed
1181 1182
  GdkWindowImplWin32 *impl;

1183 1184 1185
  g_return_if_fail (window != NULL);
  g_return_if_fail (GDK_IS_WINDOW (window));
  
Tor Lillqvist's avatar
Tor Lillqvist committed
1186 1187 1188
  impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);

  if (!GDK_WINDOW_DESTROYED (window))
1189 1190 1191
    {
      HDC hdc;

1192
      if (width == 0)
Tor Lillqvist's avatar
Tor Lillqvist committed
1193
	width = impl->width - x;
1194
      if (height == 0)
Tor Lillqvist's avatar
Tor Lillqvist committed
1195
	height = impl->height - y;<