gdkwindow-win32.c

Go to the documentation of this file.
00001 /* GDK - The GIMP Drawing Kit
00002  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
00003  * Copyright (C) 1998-1999 Tor Lillqvist
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public
00016  * License along with this library; if not, write to the
00017  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018  * Boston, MA 02111-1307, USA.
00019  */
00020 
00021 /*
00022  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
00023  * file for a list of people on the GTK+ Team.  See the ChangeLog
00024  * files for a list of changes.  These files are distributed with
00025  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
00026  */
00027 
00028 #include "config.h"
00029 
00030 #include <stdlib.h>
00031 #include <stdio.h>
00032 
00033 #include "gdk.h"
00034 #include "gdkprivate-win32.h"
00035 #include "gdkinputprivate.h"
00036 #include "gdkwin32.h"
00037 
00038 static gboolean gdk_window_gravity_works(void);
00039 static void gdk_window_set_static_win_gravity(GdkWindow * window,
00040                                               gboolean on);
00041 
00042 /* The Win API function AdjustWindowRect may return negative values
00043  * resulting in obscured title bars. This helper function is coreccting it.
00044  */
00045 BOOL
00046 SafeAdjustWindowRectEx(RECT * lpRect,
00047                        DWORD dwStyle, BOOL bMenu, DWORD dwExStyle)
00048 {
00049    if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle)) {
00050       WIN32_API_FAILED("AdjustWindowRectEx");
00051       return FALSE;
00052    }
00053    if (lpRect->left < 0) {
00054       lpRect->right -= lpRect->left;
00055       lpRect->left = 0;
00056    }
00057    if (lpRect->top < 0) {
00058       lpRect->bottom -= lpRect->top;
00059       lpRect->top = 0;
00060    }
00061    return TRUE;
00062 }
00063 
00064 static void gdk_win32_window_destroy(GdkDrawable * drawable)
00065 {
00066    GDK_NOTE(MISC, g_print("gdk_win32_window_destroy: %#x\n",
00067                           GDK_DRAWABLE_XID(drawable)));
00068 
00069    if (!GDK_DRAWABLE_DESTROYED(drawable)) {
00070       if (GDK_DRAWABLE_TYPE(drawable) == GDK_WINDOW_FOREIGN)
00071          gdk_xid_table_remove(GDK_DRAWABLE_XID(drawable));
00072       else
00073          g_warning("losing last reference to undestroyed window\n");
00074    }
00075 
00076    if (GDK_WINDOW_WIN32DATA(drawable)->bg_type == GDK_WIN32_BG_PIXMAP
00077        && GDK_WINDOW_WIN32DATA(drawable)->bg_pixmap != NULL)
00078       gdk_drawable_unref(GDK_WINDOW_WIN32DATA(drawable)->bg_pixmap);
00079 
00080    if (GDK_WINDOW_WIN32DATA(drawable)->xcursor != NULL)
00081       DestroyCursor(GDK_WINDOW_WIN32DATA(drawable)->xcursor);
00082 
00083    g_free(GDK_DRAWABLE_WIN32DATA(drawable));
00084 }
00085 
00086 static GdkWindow *gdk_win32_window_alloc(void)
00087 {
00088    GdkWindow *window;
00089    GdkWindowPrivate *private;
00090 
00091    static GdkDrawableClass klass;
00092    static gboolean initialized = FALSE;
00093 
00094    if (!initialized) {
00095       initialized = TRUE;
00096 
00097       klass = _gdk_win32_drawable_class;
00098       klass.destroy = gdk_win32_window_destroy;
00099    }
00100 
00101    window = _gdk_window_alloc();
00102    private = (GdkWindowPrivate *) window;
00103 
00104    private->drawable.klass = &klass;
00105    private->drawable.klass_data = g_new(GdkWindowWin32Data, 1);
00106 
00107    GDK_WINDOW_WIN32DATA(window)->event_mask = 0;
00108    GDK_WINDOW_WIN32DATA(window)->grab_event_mask = 0;    //vo
00109    GDK_WINDOW_WIN32DATA(window)->grab_button = -1;       //vo
00110    GDK_WINDOW_WIN32DATA(window)->grab_owner_events = 0;  //vo
00111    GDK_WINDOW_WIN32DATA(window)->grab_modifiers = 0;     //vo
00112    GDK_WINDOW_WIN32DATA(window)->grab_time = 0;          //vo
00113    GDK_WINDOW_WIN32DATA(window)->grab_confine = NULL;    //vo
00114    GDK_WINDOW_WIN32DATA(window)->grab_cursor = NULL;     //vo
00115    GDK_WINDOW_WIN32DATA(window)->grab_keys = NULL;       //vo
00116    GDK_WINDOW_WIN32DATA(window)->grab_key_owner_events = 0; //vo
00117    GDK_WINDOW_WIN32DATA(window)->bg_type = GDK_WIN32_BG_NORMAL;
00118    GDK_WINDOW_WIN32DATA(window)->xcursor = NULL;
00119    GDK_WINDOW_WIN32DATA(window)->hint_flags = 0;
00120    GDK_WINDOW_WIN32DATA(window)->extension_events_selected = FALSE;
00121 
00122    GDK_WINDOW_WIN32DATA(window)->input_locale = GetKeyboardLayout(0);
00123    TranslateCharsetInfo((DWORD FAR *) GetACP(),
00124                         &GDK_WINDOW_WIN32DATA(window)->charset_info,
00125                         TCI_SRCCODEPAGE);
00126 
00127    return window;
00128 }
00129 
00130 void gdk_window_init(void)
00131 {
00132    GdkWindowPrivate *private;
00133    RECT r;
00134    guint width;
00135    guint height;
00136 
00137    SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
00138    width = r.right - r.left;
00139    height = r.bottom - r.top;
00140 
00141    gdk_parent_root = gdk_win32_window_alloc();
00142    private = (GdkWindowPrivate *) gdk_parent_root;
00143 
00144    GDK_DRAWABLE_WIN32DATA(gdk_parent_root)->xid = gdk_root_window;
00145    private->drawable.window_type = GDK_WINDOW_ROOT;
00146    private->drawable.width = width;
00147    private->drawable.height = height;
00148 
00149    gdk_xid_table_insert(&gdk_root_window, gdk_parent_root);
00150 }
00151 
00152 /* RegisterGdkClass
00153  *   is a wrapper function for RegisterWindowClassEx.
00154  *   It creates at least one unique class for every 
00155  *   GdkWindowType. If support for single window-specific icons
00156  *   is ever needed (e.g Dialog specific), every such window should
00157  *   get its own class
00158  */
00159 ATOM RegisterGdkClass(GdkDrawableType wtype)
00160 {
00161    static ATOM klassTOPLEVEL = 0;
00162    static ATOM klassDIALOG = 0;
00163    static ATOM klassCHILD = 0;
00164    static ATOM klassTEMP = 0;
00165    static HICON hAppIcon = NULL;
00166    static WNDCLASSEX wcl;
00167    ATOM klass = 0;
00168 
00169    wcl.cbSize = sizeof(WNDCLASSEX);
00170    wcl.style = 0;               /* DON'T set CS_<H,V>REDRAW. It causes total redraw
00171                                  * on WM_SIZE and WM_MOVE. Flicker, Performance!
00172                                  */
00173    wcl.lpfnWndProc = gdk_WindowProc;
00174    wcl.cbClsExtra = 0;
00175    wcl.cbWndExtra = 0;
00176    wcl.hInstance = gdk_ProgInstance;
00177    wcl.hIcon = 0;
00178    /* initialize once! */
00179    if (0 == hAppIcon) {
00180       gchar sLoc[_MAX_PATH + 1];
00181 
00182       if (0 != GetModuleFileName(gdk_ProgInstance, sLoc, _MAX_PATH)) {
00183          hAppIcon = ExtractIcon(gdk_ProgInstance, sLoc, 0);
00184          if (0 == hAppIcon) {
00185             char *gdklibname = g_strdup_printf("gdk-%s.dll", GDK_VERSION);
00186 
00187             hAppIcon = ExtractIcon(gdk_ProgInstance, gdklibname, 0);
00188             g_free(gdklibname);
00189          }
00190 
00191          if (0 == hAppIcon)
00192             hAppIcon = LoadIcon(NULL, IDI_APPLICATION);
00193       }
00194    }
00195 
00196    wcl.lpszMenuName = NULL;
00197    wcl.hIconSm = 0;
00198 
00199    /* initialize once per class */
00200 #define ONCE_PER_CLASS() \
00201   wcl.hIcon = CopyIcon (hAppIcon); \
00202   wcl.hIconSm = CopyIcon (hAppIcon); \
00203   wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0)); \
00204   wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
00205 
00206    switch (wtype) {
00207    case GDK_WINDOW_TOPLEVEL:
00208       if (0 == klassTOPLEVEL) {
00209          wcl.lpszClassName = "gdkWindowToplevel";
00210 
00211          ONCE_PER_CLASS();
00212          klassTOPLEVEL = RegisterClassEx(&wcl);
00213       }
00214       klass = klassTOPLEVEL;
00215       break;
00216    case GDK_WINDOW_CHILD:
00217       if (0 == klassCHILD) {
00218          wcl.lpszClassName = "gdkWindowChild";
00219          wcl.style |= CS_PARENTDC;      /* MSDN: ... enhances system performance. */
00220          ONCE_PER_CLASS();
00221          klassCHILD = RegisterClassEx(&wcl);
00222       }
00223       klass = klassCHILD;
00224       break;
00225    case GDK_WINDOW_DIALOG:
00226       if (0 == klassDIALOG) {
00227          wcl.lpszClassName = "gdkWindowDialog";
00228          wcl.style |= CS_SAVEBITS;
00229          ONCE_PER_CLASS();
00230          klassDIALOG = RegisterClassEx(&wcl);
00231       }
00232       klass = klassDIALOG;
00233       break;
00234    case GDK_WINDOW_TEMP:
00235       if (0 == klassTEMP) {
00236          wcl.lpszClassName = "gdkWindowTemp";
00237          wcl.style |= CS_SAVEBITS;
00238          ONCE_PER_CLASS();
00239          klassTEMP = RegisterClassEx(&wcl);
00240       }
00241       klass = klassTEMP;
00242       break;
00243    case GDK_WINDOW_ROOT:
00244       g_error("cannot make windows of type GDK_WINDOW_ROOT");
00245       break;
00246    case GDK_DRAWABLE_PIXMAP:
00247       g_error
00248           ("cannot make windows of type GDK_DRAWABLE_PIXMAP (use gdk_pixmap_new)");
00249       break;
00250    }
00251 
00252    if (klass == 0) {
00253       WIN32_API_FAILED("RegisterClassEx");
00254       g_error("That is a fatal error");
00255    }
00256    return klass;
00257 }
00258 
00259 GdkWindow *gdk_window_new(GdkWindow * parent,
00260                           GdkWindowAttr * attributes, gint attributes_mask)
00261 {
00262    GdkWindow *window;
00263    GdkWindowPrivate *private;
00264    GdkWindowPrivate *parent_private;
00265    GdkVisual *visual;
00266    HANDLE xparent;
00267    Visual *xvisual;
00268    ATOM klass = 0;
00269    DWORD dwStyle, dwExStyle;
00270    RECT rect;
00271    int width, height;
00272    int x, y;
00273    char *title;
00274    gint titlelen;
00275    wchar_t *wctitle;
00276    gint wlen;
00277    char *mbtitle;
00278 
00279    g_return_val_if_fail(attributes != NULL, NULL);
00280 
00281    if (!parent)
00282       parent = gdk_parent_root;
00283 
00284    parent_private = (GdkWindowPrivate *) parent;
00285    if (GDK_DRAWABLE_DESTROYED(parent))
00286       return NULL;
00287 
00288    xparent = GDK_DRAWABLE_XID(parent);
00289 
00290    window = gdk_win32_window_alloc();
00291    private = (GdkWindowPrivate *) window;
00292 
00293    private->parent = parent;
00294 
00295    private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
00296    private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
00297 
00298    private->drawable.width =
00299        (attributes->width > 1) ? (attributes->width) : (1);
00300    private->drawable.height =
00301        (attributes->height > 1) ? (attributes->height) : (1);
00302    private->drawable.window_type = attributes->window_type;
00303    GDK_WINDOW_WIN32DATA(window)->extension_events_selected = FALSE;
00304 
00305    if (attributes_mask & GDK_WA_VISUAL)
00306       visual = attributes->visual;
00307    else
00308       visual = gdk_visual_get_system();
00309    xvisual = ((GdkVisualPrivate *) visual)->xvisual;
00310 
00311    if (attributes_mask & GDK_WA_TITLE)
00312       title = attributes->title;
00313    else
00314       title = g_get_prgname();
00315    if (!title)
00316       title = "GDK client window";
00317 
00318    GDK_WINDOW_WIN32DATA(window)->event_mask =
00319        GDK_STRUCTURE_MASK | attributes->event_mask;
00320 
00321    if (parent_private && parent_private->guffaw_gravity) {
00322       /* XXX ??? */
00323    }
00324 
00325    if (attributes->wclass == GDK_INPUT_OUTPUT) {
00326       dwExStyle = 0;
00327       if (attributes_mask & GDK_WA_COLORMAP)
00328          private->drawable.colormap = attributes->colormap;
00329       else
00330          private->drawable.colormap = gdk_colormap_get_system();
00331    } else {
00332       dwExStyle = WS_EX_TRANSPARENT;
00333       private->drawable.colormap = NULL;
00334       GDK_WINDOW_WIN32DATA(window)->bg_type = GDK_WIN32_BG_TRANSPARENT;
00335       GDK_WINDOW_WIN32DATA(window)->bg_pixmap = NULL;
00336    }
00337 
00338    if (attributes_mask & GDK_WA_X)
00339       x = attributes->x;
00340    else
00341       x = CW_USEDEFAULT;
00342 
00343    if (attributes_mask & GDK_WA_Y)
00344       y = attributes->y;
00345    else if (attributes_mask & GDK_WA_X)
00346       y = 100;                  /* ??? We must put it somewhere... */
00347    else
00348       y = 500;                  /* x is CW_USEDEFAULT, y doesn't matter then */
00349 
00350    if (parent_private)
00351       parent_private->children =
00352           g_list_prepend(parent_private->children, window);
00353 
00354    switch (private->drawable.window_type) {
00355    case GDK_WINDOW_TOPLEVEL:
00356       dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
00357       xparent = gdk_root_window;
00358       break;
00359    case GDK_WINDOW_CHILD:
00360       dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
00361       dwExStyle |= WS_EX_TOOLWINDOW;
00362       break;
00363    case GDK_WINDOW_DIALOG:
00364       dwStyle =
00365           WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION |
00366           WS_THICKFRAME | WS_CLIPCHILDREN;
00367 #if 0
00368       dwExStyle |= WS_EX_TOPMOST;       /* //HB: want this? */
00369 #endif
00370       xparent = gdk_root_window;
00371       break;
00372    case GDK_WINDOW_TEMP:
00373       dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
00374       dwExStyle |= WS_EX_TOOLWINDOW;
00375       break;
00376    case GDK_WINDOW_ROOT:
00377       g_error("cannot make windows of type GDK_WINDOW_ROOT");
00378       break;
00379    case GDK_DRAWABLE_PIXMAP:
00380       g_error
00381           ("cannot make windows of type GDK_DRAWABLE_PIXMAP (use gdk_pixmap_new)");
00382       break;
00383    }
00384 
00385    klass = RegisterGdkClass(private->drawable.window_type);
00386 
00387    if (private->drawable.window_type != GDK_WINDOW_CHILD) {
00388       if (x == CW_USEDEFAULT) {
00389          rect.left = 100;
00390          rect.top = 100;
00391       } else {
00392          rect.left = x;
00393          rect.top = y;
00394       }
00395 
00396       rect.right = rect.left + private->drawable.width;
00397       rect.bottom = rect.top + private->drawable.height;
00398 
00399       SafeAdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
00400 
00401       if (x != CW_USEDEFAULT) {
00402          x = rect.left;
00403          y = rect.top;
00404       }
00405       width = rect.right - rect.left;
00406       height = rect.bottom - rect.top;
00407    } else {
00408       width = private->drawable.width;
00409       height = private->drawable.height;
00410    }
00411 
00412    titlelen = strlen(title);
00413    wctitle = g_new(wchar_t, titlelen + 1);
00414    mbtitle = g_new(char, 3 * titlelen + 1);
00415    wlen = gdk_nmbstowchar_ts(wctitle, title, titlelen, titlelen);
00416    wctitle[wlen] = 0;
00417    WideCharToMultiByte(GetACP(), 0, wctitle, -1,
00418                        mbtitle, 3 * titlelen, NULL, NULL);
00419 
00420    GDK_DRAWABLE_WIN32DATA(window)->xid =
00421        CreateWindowEx(dwExStyle,
00422                       MAKEINTRESOURCE(klass),
00423                       mbtitle,
00424                       dwStyle,
00425                       x, y,
00426                       width, height,
00427                       xparent, NULL, gdk_ProgInstance, NULL);
00428 
00429    GDK_NOTE(MISC,
00430             g_print("gdk_window_new: %s %s %dx%d@+%d+%d %#x = %#x\n"
00431                     "...locale %#x codepage %d\n",
00432                     (private->drawable.window_type ==
00433                      GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" : (private->drawable.
00434                                                          window_type ==
00435                                                          GDK_WINDOW_CHILD ?
00436                                                          "CHILD"
00437                                                          : (private->
00438                                                             drawable.
00439                                                             window_type ==
00440                                                             GDK_WINDOW_DIALOG
00441                                                             ? "DIALOG"
00442                                                             : (private->
00443                                                                drawable.
00444                                                                window_type
00445                                                                ==
00446                                                                GDK_WINDOW_TEMP
00447                                                                ? "TEMP" :
00448                                                                "???")))),
00449                     mbtitle, width, height,
00450                     (x == CW_USEDEFAULT ? -9999 : x), y, xparent,
00451                     GDK_DRAWABLE_XID(window),
00452                     GDK_WINDOW_WIN32DATA(window)->input_locale,
00453                     GDK_WINDOW_WIN32DATA(window)->charset_info.ciACP));
00454 
00455    g_free(mbtitle);
00456    g_free(wctitle);
00457 
00458    if (GDK_DRAWABLE_XID(window) == NULL) {
00459       WIN32_API_FAILED("CreateWindowEx");
00460       g_free(GDK_DRAWABLE_WIN32DATA(window));
00461       g_free(private);
00462       return NULL;
00463    }
00464 
00465    gdk_drawable_ref(window);
00466    gdk_xid_table_insert(&GDK_DRAWABLE_XID(window), window);
00467 
00468    if (private->drawable.colormap)
00469       gdk_colormap_ref(private->drawable.colormap);
00470 
00471    gdk_window_set_cursor(window, ((attributes_mask & GDK_WA_CURSOR) ?
00472                                   (attributes->cursor) : NULL));
00473 
00474    return window;
00475 }
00476 
00477 GdkWindow *gdk_window_foreign_new(guint32 anid)
00478 {
00479    GdkWindow *window;
00480    GdkWindowPrivate *private;
00481    GdkWindowPrivate *parent_private;
00482    HANDLE parent;
00483    RECT rect;
00484    POINT point;
00485 
00486    window = gdk_win32_window_alloc();
00487    private = (GdkWindowPrivate *) window;
00488 
00489    parent = GetParent((HWND) anid);
00490    private->parent = gdk_xid_table_lookup(parent);
00491 
00492    parent_private = (GdkWindowPrivate *) private->parent;
00493 
00494    if (parent_private)
00495       parent_private->children =
00496           g_list_prepend(parent_private->children, window);
00497 
00498    GDK_DRAWABLE_WIN32DATA(window)->xid = (HWND) anid;
00499    GetClientRect((HWND) anid, &rect);
00500    point.x = rect.left;
00501    point.y = rect.right;
00502    ClientToScreen((HWND) anid, &point);
00503    if (parent != GetDesktopWindow())
00504       ScreenToClient(parent, &point);
00505    private->x = point.x;
00506    private->y = point.y;
00507    private->drawable.width = rect.right - rect.left;
00508    private->drawable.height = rect.bottom - rect.top;
00509    private->drawable.window_type = GDK_WINDOW_FOREIGN;
00510    private->drawable.destroyed = FALSE;
00511    private->mapped = IsWindowVisible(GDK_DRAWABLE_XID(window));
00512 
00513    private->drawable.colormap = NULL;
00514 
00515    gdk_drawable_ref(window);
00516    gdk_xid_table_insert(&GDK_DRAWABLE_XID(window), window);
00517 
00518    return window;
00519 }
00520 
00521 /* Call this function when you want a window and all its children to
00522  * disappear.  When xdestroy is true, a request to destroy the window
00523  * is sent out.  When it is false, it is assumed that the window has
00524  * been or will be destroyed by destroying some ancestor of this
00525  * window.
00526  */
00527 static void
00528 gdk_window_internal_destroy(GdkWindow * window,
00529                             gboolean xdestroy, gboolean our_destroy)
00530 {
00531    GdkWindowPrivate *private;
00532    GdkWindowPrivate *temp_private;
00533    GdkWindow *temp_window;
00534    GList *children;
00535    GList *tmp;
00536 
00537    g_return_if_fail(window != NULL);
00538 
00539    private = (GdkWindowPrivate *) window;
00540 
00541    GDK_NOTE(MISC, g_print("gdk_window_internal_destroy %#x\n",
00542                           GDK_DRAWABLE_XID(window)));
00543 
00544    switch (GDK_DRAWABLE_TYPE(window)) {
00545    case GDK_WINDOW_TOPLEVEL:
00546    case GDK_WINDOW_CHILD:
00547    case GDK_WINDOW_DIALOG:
00548    case GDK_WINDOW_TEMP:
00549    case GDK_WINDOW_FOREIGN:
00550       if (!GDK_DRAWABLE_DESTROYED(window)) {
00551          if (GDK_WINDOW_WIN32DATA(window)->xcursor != NULL)
00552             DestroyCursor (GDK_WINDOW_WIN32DATA (window)->xcursor);
00553          if (private->parent) {
00554             GdkWindowPrivate *parent_private =
00555                 (GdkWindowPrivate *) private->parent;
00556             if (parent_private->children)
00557                parent_private->children =
00558                    g_list_remove(parent_private->children, window);
00559          }
00560 
00561          if (GDK_DRAWABLE_TYPE(window) != GDK_WINDOW_FOREIGN) {
00562             children = tmp = private->children;
00563             private->children = NULL;
00564 
00565             while (tmp) {
00566                temp_window = tmp->data;
00567                tmp = tmp->next;
00568 
00569                temp_private = (GdkWindowPrivate *) temp_window;
00570                if (temp_private)
00571                   gdk_window_internal_destroy(temp_window, FALSE,
00572                                               our_destroy);
00573             }
00574 
00575             g_list_free(children);
00576          }
00577 
00578          if (private->extension_events != 0)
00579             gdk_input_window_destroy(window);
00580 
00581          if (private->filters) {
00582             tmp = private->filters;
00583 
00584             while (tmp) {
00585                g_free(tmp->data);
00586                tmp = tmp->next;
00587             }
00588 
00589             g_list_free(private->filters);
00590             private->filters = NULL;
00591          }
00592 
00593          if (private->drawable.window_type == GDK_WINDOW_FOREIGN) {
00594             if (our_destroy && (private->parent != NULL)) {
00595                /* It's somebody elses window, but in our hierarchy,
00596                 * so reparent it to the root window, and then send
00597                 * it a delete event, as if we were a WM
00598                 */
00599                gdk_window_hide(window);
00600                gdk_window_reparent(window, NULL, 0, 0);
00601 
00602                /* Is this too drastic? Many (most?) applications
00603                 * quit if any window receives WM_QUIT I think.
00604                 * OTOH, I don't think foreign windows are much
00605                 * used, so the question is maybe academic.
00606                 */
00607                PostMessage(GDK_DRAWABLE_XID(window), WM_QUIT, 0, 0);
00608             }
00609          } else {
00610             private->drawable.destroyed = TRUE;
00611             if (xdestroy) {
00612                /* Calls gdk_WindowProc */
00613                DestroyWindow(GDK_DRAWABLE_XID(window));
00614             }
00615          }
00616 
00617          if (private->drawable.colormap)
00618             gdk_colormap_unref(private->drawable.colormap);
00619 
00620          private->mapped = FALSE;
00621       }
00622       break;
00623 
00624    case GDK_WINDOW_ROOT:
00625       g_error("attempted to destroy root window");
00626       break;
00627 
00628    case GDK_DRAWABLE_PIXMAP:
00629       g_error
00630           ("called gdk_window_destroy on a pixmap (use gdk_drawable_unref)");
00631       break;
00632    }
00633 }
00634 
00635 /* Like internal_destroy, but also destroys the reference created by
00636    gdk_window_new. */
00637 
00638 void gdk_window_destroy(GdkWindow * window, gboolean xdestroy)
00639 {
00640    GDK_NOTE(MISC,
00641             g_print("gdk_window_destroy: %#x\n",
00642                     GDK_DRAWABLE_XID(window)));
00643    gdk_window_internal_destroy(window, xdestroy, TRUE);
00644    gdk_drawable_unref(window);
00645 }
00646 
00647 /* This function is called when the window really gone.  */
00648 
00649 void gdk_window_destroy_notify(GdkWindow * window)
00650 {
00651    g_return_if_fail(window != NULL);
00652 
00653    GDK_NOTE(EVENTS,
00654             g_print("gdk_window_destroy_notify: %#x  %s\n",
00655                     GDK_DRAWABLE_XID(window),
00656                     (GDK_DRAWABLE_DESTROYED(window) ? "yes" : "no")));
00657 
00658    if (!GDK_DRAWABLE_DESTROYED(window)) {
00659       if (GDK_DRAWABLE_TYPE(window) != GDK_WINDOW_FOREIGN)
00660          g_warning("window %#x unexpectedly destroyed",
00661                    GDK_DRAWABLE_XID(window));
00662 
00663       gdk_window_internal_destroy(window, FALSE, FALSE);
00664    }
00665 
00666    gdk_xid_table_remove(GDK_DRAWABLE_XID(window));
00667    gdk_drawable_unref(window);
00668 }
00669 
00670 void gdk_window_show(GdkWindow * window)
00671 {
00672    g_return_if_fail(window != NULL);
00673 
00674    if (!GDK_DRAWABLE_DESTROYED(window)) {
00675       GDK_NOTE(MISC, g_print("gdk_window_show: %#x\n",
00676                              GDK_DRAWABLE_XID(window)));
00677 
00678       ((GdkWindowPrivate *) window)->mapped = TRUE;
00679       if (GDK_DRAWABLE_TYPE(window) == GDK_WINDOW_TEMP) {
00680          ShowWindow(GDK_DRAWABLE_XID(window), SW_SHOWNOACTIVATE);
00681          SetWindowPos(GDK_DRAWABLE_XID(window), HWND_TOPMOST, 0, 0, 0, 0,
00682                       SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
00683 #if 0
00684          /* Don't put on toolbar */
00685          ShowWindow(GDK_DRAWABLE_XID(window), SW_HIDE);
00686 #endif
00687       } else {
00688          ShowWindow(GDK_DRAWABLE_XID(window), SW_SHOWNORMAL);
00689          ShowWindow(GDK_DRAWABLE_XID(window), SW_RESTORE);
00690 //         SetForegroundWindow(GDK_DRAWABLE_XID(window)); //vo
00691          BringWindowToTop(GDK_DRAWABLE_XID(window));
00692 #if 0
00693          ShowOwnedPopups(GDK_DRAWABLE_XID(window), TRUE);
00694 #endif
00695       }
00696    }
00697 }
00698 
00699 void gdk_window_hide(GdkWindow * window)
00700 {
00701    g_return_if_fail(window != NULL);
00702 
00703    if (!GDK_DRAWABLE_DESTROYED(window)) {
00704       GDK_NOTE(MISC, g_print("gdk_window_hide: %#x\n",
00705                              GDK_DRAWABLE_XID(window)));
00706 
00707       ((GdkWindowPrivate *) window)->mapped = FALSE;
00708       if (GDK_DRAWABLE_TYPE(window) == GDK_WINDOW_TOPLEVEL)
00709          ShowOwnedPopups(GDK_DRAWABLE_XID(window), FALSE);
00710 #if 1
00711       ShowWindow(GDK_DRAWABLE_XID(window), SW_HIDE);
00712 #elif 0
00713       ShowWindow(GDK_DRAWABLE_XID(window), SW_MINIMIZE);
00714 #else
00715       CloseWindow(GDK_DRAWABLE_XID(window));
00716 #endif
00717    }
00718 }
00719 
00720 void gdk_window_withdraw(GdkWindow * window)
00721 {
00722    g_return_if_fail(window != NULL);
00723 
00724    if (!GDK_DRAWABLE_DESTROYED(window)) {
00725       GDK_NOTE(MISC, g_print("gdk_window_withdraw: %#x\n",
00726                              GDK_DRAWABLE_XID(window)));
00727 
00728       gdk_window_hide(window);  /* XXX */
00729    }
00730 }
00731 
00732 void gdk_window_move(GdkWindow * window, gint x, gint y)
00733 {
00734    GdkWindowPrivate *private;
00735 
00736    g_return_if_fail(window != NULL);
00737 
00738    if (!GDK_DRAWABLE_DESTROYED(window)) {
00739       RECT rect;
00740 
00741       GDK_NOTE(MISC, g_print("gdk_window_move: %#x +%d+%d\n",
00742                              GDK_DRAWABLE_XID(window), x, y));
00743 
00744       private = (GdkWindowPrivate *) window;
00745       GetClientRect(GDK_DRAWABLE_XID(window), &rect);
00746 
00747       if (GDK_DRAWABLE_TYPE(window) == GDK_WINDOW_FOREIGN) {
00748          private->x = x;
00749          private->y = y;
00750          return;
00751       }
00752       else if (GDK_DRAWABLE_TYPE(window) != GDK_WINDOW_CHILD) {
00753          POINT ptTL, ptBR;
00754          DWORD dwStyle;
00755          DWORD dwExStyle;
00756 
00757          ptTL.x = 0;
00758          ptTL.y = 0;
00759          ClientToScreen(GDK_DRAWABLE_XID(window), &ptTL);
00760          rect.left = x;
00761          rect.top = y;
00762 
00763          ptBR.x = rect.right;
00764          ptBR.y = rect.bottom;
00765          ClientToScreen(GDK_DRAWABLE_XID(window), &ptBR);
00766          rect.right = x + ptBR.x - ptTL.x;
00767          rect.bottom = y + ptBR.y - ptTL.y;
00768 
00769          dwStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE);
00770          dwExStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_EXSTYLE);
00771          SafeAdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
00772 
00773          x = rect.left;
00774          y = rect.top;
00775       } else {
00776          private->x = x;
00777          private->y = y;
00778       }
00779       GDK_NOTE(MISC, g_print("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
00780                              GDK_DRAWABLE_XID(window),
00781                              rect.right - rect.left,
00782                              rect.bottom - rect.top, x, y));
00783       if (!MoveWindow
00784           (GDK_DRAWABLE_XID(window), x, y, rect.right - rect.left,
00785            rect.bottom - rect.top, TRUE))
00786          WIN32_API_FAILED("MoveWindow");
00787    }
00788 }
00789 
00790 void gdk_window_resize(GdkWindow * window, gint width, gint height)
00791 {
00792    GdkWindowPrivate *private;
00793 
00794    g_return_if_fail(window != NULL);
00795 
00796    private = (GdkWindowPrivate *) window;
00797 
00798    if (!private->drawable.destroyed &&
00799        ((private->resize_count > 0) ||
00800         (private->drawable.width != (guint16) width) ||
00801         (private->drawable.height != (guint16) height))) {
00802       int x, y;
00803 
00804       GDK_NOTE(MISC, g_print("gdk_window_resize: %#x %dx%d\n",
00805                              GDK_DRAWABLE_XID(window), width, height));
00806 
00807       if (private->drawable.window_type == GDK_WINDOW_FOREIGN) {
00808          private->drawable.width = width;
00809          private->drawable.height = height;
00810          return;
00811       }
00812       else if (private->drawable.window_type != GDK_WINDOW_CHILD) {
00813          POINT pt;
00814          RECT rect;
00815          DWORD dwStyle;
00816          DWORD dwExStyle;
00817 
00818          pt.x = 0;
00819          pt.y = 0;
00820          ClientToScreen(GDK_DRAWABLE_XID(window), &pt);
00821          rect.left = pt.x;
00822          rect.top = pt.y;
00823          rect.right = pt.x + width;
00824          rect.bottom = pt.y + height;
00825 
00826          dwStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE);
00827          dwExStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_EXSTYLE);
00828          if (!AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle))
00829             WIN32_API_FAILED("AdjustWindowRectEx");
00830 
00831          x = rect.left;
00832          y = rect.top;
00833          width = rect.right - rect.left;
00834          height = rect.bottom - rect.top;
00835       } else {
00836          x = private->x;
00837          y = private->y;
00838          private->drawable.width = width;
00839          private->drawable.height = height;
00840       }
00841 
00842       private->resize_count += 1;
00843 
00844       GDK_NOTE(MISC,
00845                g_print("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
00846                        GDK_DRAWABLE_XID(window), width, height, x, y));
00847       if (!MoveWindow(GDK_DRAWABLE_XID(window), x, y, width, height, TRUE))
00848          WIN32_API_FAILED("MoveWindow");
00849    }
00850 }
00851 
00852 void
00853 gdk_window_move_resize(GdkWindow * window,
00854                        gint x, gint y, gint width, gint height)
00855 {
00856    GdkWindowPrivate *private;
00857 
00858    g_return_if_fail(window != NULL);
00859 
00860    if (!GDK_DRAWABLE_DESTROYED(window)) {
00861       RECT rect;
00862       DWORD dwStyle;
00863       DWORD dwExStyle;
00864 
00865       GDK_NOTE(MISC, g_print("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
00866                              GDK_DRAWABLE_XID(window), width, height, x,
00867                              y));
00868 
00869       private = (GdkWindowPrivate *) window;
00870       rect.left = x;
00871       rect.top = y;
00872       rect.right = x + width;
00873       rect.bottom = y + height;
00874 
00875       dwStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE);
00876       dwExStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_EXSTYLE);
00877       if (!AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle))
00878          WIN32_API_FAILED("AdjustWindowRectEx");
00879 
00880       if (private->drawable.window_type == GDK_WINDOW_CHILD) {
00881          private->x = x;
00882          private->y = y;
00883          private->drawable.width = width;
00884          private->drawable.height = height;
00885       }
00886       if (private->drawable.window_type == GDK_WINDOW_FOREIGN) {
00887          private->x = x;
00888          private->y = y;
00889          private->drawable.width = width;
00890          private->drawable.height = height;
00891          return;
00892       }
00893       GDK_NOTE(MISC, g_print("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
00894                              GDK_DRAWABLE_XID(window),
00895                              rect.right - rect.left,
00896                              rect.bottom - rect.top, rect.left, rect.top));
00897       if (!MoveWindow
00898           (GDK_DRAWABLE_XID(window), rect.left, rect.top,
00899            rect.right - rect.left, rect.bottom - rect.top, TRUE))
00900          WIN32_API_FAILED("MoveWindow");
00901 
00902       if (private->guffaw_gravity) {
00903          GList *tmp_list = private->children;
00904          while (tmp_list) {
00905             GdkWindowPrivate *child_private = tmp_list->data;
00906 
00907             child_private->x -= x - private->x;
00908             child_private->y -= y - private->y;
00909 
00910             tmp_list = tmp_list->next;
00911          }
00912       }
00913 
00914    }
00915 }
00916 
00917 void
00918 gdk_window_reparent(GdkWindow * window,
00919                     GdkWindow * new_parent, gint x, gint y)
00920 {
00921    GdkWindowPrivate *window_private;
00922    GdkWindowPrivate *parent_private;
00923    GdkWindowPrivate *old_parent_private;
00924 
00925    g_return_if_fail(window != NULL);
00926 
00927    if (!new_parent)
00928       new_parent = gdk_parent_root;
00929 
00930    window_private = (GdkWindowPrivate *) window;
00931    old_parent_private = (GdkWindowPrivate *) window_private->parent;
00932    parent_private = (GdkWindowPrivate *) new_parent;
00933 
00934    if (!GDK_DRAWABLE_DESTROYED(window)
00935        && !GDK_DRAWABLE_DESTROYED(new_parent)) {
00936       GDK_NOTE(MISC, g_print("gdk_window_reparent: %#x %#x\n",
00937                              GDK_DRAWABLE_XID(window),
00938                              GDK_DRAWABLE_XID(new_parent)));
00939       if (!SetParent(GDK_DRAWABLE_XID(window),
00940                      GDK_DRAWABLE_XID(new_parent)))
00941          WIN32_API_FAILED("SetParent");
00942 
00943       if (!MoveWindow(GDK_DRAWABLE_XID(window),
00944                       x, y,
00945                       window_private->drawable.width,
00946                       window_private->drawable.height, TRUE))
00947          WIN32_API_FAILED("MoveWindow");
00948    }
00949 
00950    window_private->parent = new_parent;
00951 
00952    if (old_parent_private)
00953       old_parent_private->children =
00954           g_list_remove(old_parent_private->children, window);
00955 
00956    if ((old_parent_private &&
00957         (!old_parent_private->guffaw_gravity !=
00958          !parent_private->guffaw_gravity)) || (!old_parent_private
00959                                                && parent_private->
00960                                                guffaw_gravity))
00961       gdk_window_set_static_win_gravity(window,
00962                                         parent_private->guffaw_gravity);
00963 
00964    parent_private->children =
00965        g_list_prepend(parent_private->children, window);
00966 }
00967 
00968 void gdk_window_clear(GdkWindow * window)
00969 {
00970    g_return_if_fail(window != NULL);
00971    g_return_if_fail(GDK_IS_WINDOW(window));
00972    if (GDK_DRAWABLE_TYPE(window) == GDK_WINDOW_FOREIGN) return;
00973 
00974    if (!GDK_DRAWABLE_DESTROYED(window))
00975       gdk_window_clear_area(window, 0, 0, 0, 0);
00976 }
00977 
00978 
00979 void
00980 gdk_window_clear_area(GdkWindow * window,
00981                       gint x, gint y, gint width, gint height)
00982 {
00983    gboolean threaded_gdk = FALSE;
00984 
00985    if (GDK_DRAWABLE_TYPE(window) == GDK_WINDOW_FOREIGN) return;
00986    g_return_if_fail(window != NULL);
00987    g_return_if_fail(GDK_IS_WINDOW(window));
00988 
00989    if (!GDK_DRAWABLE_DESTROYED(window)) {
00990       HDC hdc;
00991 
00992       if (width == 0)
00993          width = ((GdkDrawablePrivate *) window)->width - x;
00994       if (height == 0)
00995          height = ((GdkDrawablePrivate *) window)->height - y;
00996       GDK_NOTE(MISC, g_print("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
00997                              GDK_DRAWABLE_XID(window), width, height, x,
00998                              y));
00999       hdc = GetDC(GDK_DRAWABLE_XID(window));
01000       IntersectClipRect(hdc, x, y, x + width, y + height);
01001 #ifdef G_THREADS_ENABLEDxxx     /* No, doesn't work any better anyway. Just testing. */
01002       if (gdk_threads_mutex)
01003          if (!g_mutex_trylock(gdk_threads_mutex))
01004             threaded_gdk = TRUE;
01005          else
01006             g_mutex_unlock(gdk_threads_mutex);
01007       if (threaded_gdk)
01008          GDK_THREADS_LEAVE();
01009 #endif
01010 #if 1
01011       SendMessage(GDK_DRAWABLE_XID(window), WM_ERASEBKGND, (WPARAM) hdc,
01012                   0);
01013 #elif 0
01014       SendNotifyMessage(GDK_DRAWABLE_XID(window), WM_ERASEBKGND,
01015                         (WPARAM) hdc, 0);
01016 #else
01017       gdk_WindowProc(GDK_DRAWABLE_XID(window), WM_ERASEBKGND, (WPARAM) hdc,
01018                      0);
01019 #endif
01020 #ifdef G_THREADS_ENABLEDxxx
01021       if (threaded_gdk)
01022          GDK_THREADS_ENTER();
01023 #endif
01024       ReleaseDC(GDK_DRAWABLE_XID(window), hdc);
01025    }
01026 }
01027 
01028 void
01029 gdk_window_clear_area_e(GdkWindow * window,
01030                         gint x, gint y, gint width, gint height)
01031 {
01032    g_return_if_fail(window != NULL);
01033    g_return_if_fail(GDK_IS_WINDOW(window));
01034    if (GDK_DRAWABLE_TYPE(window) == GDK_WINDOW_FOREIGN) return;
01035 
01036    if (!GDK_DRAWABLE_DESTROYED(window)) {
01037       RECT rect;
01038 
01039       GDK_NOTE(MISC, g_print("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
01040                              GDK_DRAWABLE_XID(window), width, height, x,
01041                              y));
01042 
01043       rect.left = x;
01044       rect.right = x + width;
01045       rect.top = y;
01046       rect.bottom = y + height;
01047       if (!InvalidateRect(GDK_DRAWABLE_XID(window), &rect, TRUE))
01048          WIN32_GDI_FAILED("InvalidateRect");
01049       UpdateWindow(GDK_DRAWABLE_XID(window));
01050    }
01051 }
01052 
01053 void gdk_window_raise(GdkWindow * window)
01054 {
01055    g_return_if_fail(window != NULL);
01056    g_return_if_fail(GDK_IS_WINDOW(window));
01057 
01058    if (!GDK_DRAWABLE_DESTROYED(window)) {
01059       GDK_NOTE(MISC, g_print("gdk_window_raise: %#x\n",
01060                              GDK_DRAWABLE_XID(window)));
01061 
01062       if (GDK_DRAWABLE_TYPE(window) == GDK_WINDOW_TEMP) {
01063          if(!SetWindowPos((HWND)GDK_DRAWABLE_XID(window), HWND_TOPMOST, 
01064                       0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
01065             WIN32_API_FAILED("SetWindowPos");
01066       } else {
01067          if (!BringWindowToTop(GDK_DRAWABLE_XID(window)))
01068             WIN32_API_FAILED("BringWindowToTop");
01069       }
01070    }
01071 }
01072 
01073 void gdk_window_lower(GdkWindow * window)
01074 {
01075    g_return_if_fail(window != NULL);
01076    g_return_if_fail(GDK_IS_WINDOW(window));
01077 
01078    if (!GDK_DRAWABLE_DESTROYED(window)) {
01079       GDK_NOTE(MISC, g_print("gdk_window_lower: %#x\n",
01080                              GDK_DRAWABLE_XID(window)));
01081 
01082       if (!SetWindowPos(GDK_DRAWABLE_XID(window), HWND_BOTTOM, 0, 0, 0, 0,
01083                         SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
01084          WIN32_API_FAILED("SetWindowPos");
01085    }
01086 }
01087 
01088 void
01089 gdk_window_set_hints(GdkWindow * window,
01090                      gint x,
01091                      gint y,
01092                      gint min_width,
01093                      gint min_height,
01094                      gint max_width, gint max_height, gint flags)
01095 {
01096    WINDOWPLACEMENT size_hints;
01097    RECT rect;
01098    DWORD dwStyle;
01099    DWORD dwExStyle;
01100    int diff;
01101 
01102    g_return_if_fail(window != NULL);
01103    g_return_if_fail(GDK_IS_WINDOW(window));
01104 
01105    if (GDK_DRAWABLE_DESTROYED(window))
01106       return;
01107 
01108    GDK_NOTE(MISC,
01109             g_print("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
01110                     GDK_DRAWABLE_XID(window), min_width, min_height,
01111                     max_width, max_height, x, y));
01112 
01113    GDK_WINDOW_WIN32DATA(window)->hint_flags = flags;
01114    size_hints.length = sizeof(size_hints);
01115 
01116    if (flags) {
01117       if (flags & GDK_HINT_POS)
01118          if (!GetWindowPlacement(GDK_DRAWABLE_XID(window), &size_hints))
01119             WIN32_API_FAILED("GetWindowPlacement");
01120          else {
01121             GDK_NOTE(MISC, g_print("...rcNormalPosition:"
01122                                    " (%d,%d)--(%d,%d)\n",
01123                                    size_hints.rcNormalPosition.left,
01124                                    size_hints.rcNormalPosition.top,
01125                                    size_hints.rcNormalPosition.right,
01126                                    size_hints.rcNormalPosition.bottom));
01127             /* What are the corresponding window coordinates for client
01128              * area coordinates x, y
01129              */
01130             rect.left = x;
01131             rect.top = y;
01132             rect.right = rect.left + 200;       /* dummy */
01133             rect.bottom = rect.top + 200;
01134             dwStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE);
01135             dwExStyle =
01136                 GetWindowLong(GDK_DRAWABLE_XID(window), GWL_EXSTYLE);
01137             AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
01138             size_hints.flags = 0;
01139             size_hints.showCmd = SW_SHOWNA;
01140 
01141             /* Set the normal position hint to that location, with unchanged
01142              * width and height.
01143              */
01144             diff = size_hints.rcNormalPosition.left - rect.left;
01145             size_hints.rcNormalPosition.left = rect.left;
01146             size_hints.rcNormalPosition.right -= diff;
01147             diff = size_hints.rcNormalPosition.top - rect.top;
01148             size_hints.rcNormalPosition.top = rect.top;
01149             size_hints.rcNormalPosition.bottom -= diff;
01150             GDK_NOTE(MISC, g_print("...setting: (%d,%d)--(%d,%d)\n",
01151                                    size_hints.rcNormalPosition.left,
01152                                    size_hints.rcNormalPosition.top,
01153                                    size_hints.rcNormalPosition.right,
01154                                    size_hints.rcNormalPosition.bottom));
01155             if (!SetWindowPlacement(GDK_DRAWABLE_XID(window), &size_hints))
01156                WIN32_API_FAILED("SetWindowPlacement");
01157             GDK_WINDOW_WIN32DATA(window)->hint_x = rect.left;
01158             GDK_WINDOW_WIN32DATA(window)->hint_y = rect.top;
01159          }
01160 
01161       if (flags & GDK_HINT_MIN_SIZE) {
01162          rect.left = 0;
01163          rect.top = 0;
01164          rect.right = min_width;
01165          rect.bottom = min_height;
01166          dwStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE);
01167          dwExStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_EXSTYLE);
01168          AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
01169          GDK_WINDOW_WIN32DATA(window)->hint_min_width =
01170              rect.right - rect.left;
01171          GDK_WINDOW_WIN32DATA(window)->hint_min_height =
01172              rect.bottom - rect.top;
01173 
01174          /* Also chek if he current size of the window is in bounds. */
01175          GetClientRect(GDK_DRAWABLE_XID(window), &rect);
01176          if (rect.right < min_width && rect.bottom < min_height)
01177             gdk_window_resize(window, min_width, min_height);
01178          else if (rect.right < min_width)
01179             gdk_window_resize(window, min_width, rect.bottom);
01180          else if (rect.bottom < min_height)
01181             gdk_window_resize(window, rect.right, min_height);
01182       }
01183 
01184       if (flags & GDK_HINT_MAX_SIZE) {
01185          rect.left = 0;
01186          rect.top = 0;
01187          rect.right = max_width;
01188          rect.bottom = max_height;
01189          dwStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE);
01190          dwExStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_EXSTYLE);
01191          AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
01192          GDK_WINDOW_WIN32DATA(window)->hint_max_width =
01193              rect.right - rect.left;
01194          GDK_WINDOW_WIN32DATA(window)->hint_max_height =
01195              rect.bottom - rect.top;
01196          /* Again, check if the window is too large currently. */
01197          GetClientRect(GDK_DRAWABLE_XID(window), &rect);
01198          if (rect.right > max_width && rect.bottom > max_height)
01199             gdk_window_resize(window, max_width, max_height);
01200          else if (rect.right > max_width)
01201             gdk_window_resize(window, max_width, rect.bottom);
01202          else if (rect.bottom > max_height)
01203             gdk_window_resize(window, rect.right, max_height);
01204       }
01205    }
01206 }
01207 
01208 void
01209 gdk_window_set_geometry_hints(GdkWindow * window,
01210                               GdkGeometry * geometry,
01211                               GdkWindowHints geom_mask)
01212 {
01213    WINDOWPLACEMENT size_hints;
01214    RECT rect;
01215    DWORD dwStyle;
01216    DWORD dwExStyle;
01217    int diff;
01218    int maxw, maxh;
01219 
01220    g_return_if_fail(window != NULL);
01221    g_return_if_fail(GDK_IS_WINDOW(window));
01222 
01223    if (GDK_DRAWABLE_DESTROYED(window))
01224       return;
01225 
01226    size_hints.length = sizeof(size_hints);
01227    maxw = gdk_screen_width();
01228    maxh = gdk_screen_height();
01229 
01230    GDK_WINDOW_WIN32DATA(window)->hint_flags = geom_mask;
01231 
01232    if (geom_mask & GDK_HINT_POS);       /* XXX */
01233 
01234    if (geom_mask & GDK_HINT_MIN_SIZE) {
01235       rect.left = 0;
01236       rect.top = 0;
01237       rect.right = geometry->min_width;
01238       rect.bottom = geometry->min_height;
01239       dwStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE);
01240       dwExStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_EXSTYLE);
01241       AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
01242       GDK_WINDOW_WIN32DATA(window)->hint_min_width =
01243           rect.right - rect.left;
01244       GDK_WINDOW_WIN32DATA(window)->hint_min_height =
01245           rect.bottom - rect.top;
01246 
01247       /* Also check if he current size of the window is in bounds */
01248       GetClientRect(GDK_DRAWABLE_XID(window), &rect);
01249       if (rect.right < geometry->min_width
01250           && rect.bottom < geometry->min_height)
01251          gdk_window_resize(window, geometry->min_width,
01252                            geometry->min_height);
01253       else if (rect.right < geometry->min_width)
01254          gdk_window_resize(window, geometry->min_width, rect.bottom);
01255       else if (rect.bottom < geometry->min_height)
01256          gdk_window_resize(window, rect.right, geometry->min_height);
01257    }
01258 
01259    if (geom_mask & GDK_HINT_MAX_SIZE) {
01260       rect.left = 0;
01261       rect.top = 0;
01262       rect.right = geometry->max_width > maxw ? maxw : geometry->max_width;
01263       rect.bottom = geometry->max_height > maxh ? maxh : geometry->max_height;
01264       dwStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE);
01265       dwExStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_EXSTYLE);
01266       AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
01267       GDK_WINDOW_WIN32DATA(window)->hint_max_width =
01268           rect.right - rect.left;
01269       GDK_WINDOW_WIN32DATA(window)->hint_max_height =
01270           rect.bottom - rect.top;
01271 
01272       /* Again, check if the window is too large currently. */
01273       GetClientRect(GDK_DRAWABLE_XID(window), &rect);
01274       if (rect.right > geometry->max_width
01275           && rect.bottom > geometry->max_height)
01276          gdk_window_resize(window, geometry->max_width,
01277                            geometry->max_height);
01278       else if (rect.right > geometry->max_width)
01279          gdk_window_resize(window, geometry->max_width, rect.bottom);
01280       else if (rect.bottom > geometry->max_height)
01281          gdk_window_resize(window, rect.right, geometry->max_height);
01282    }
01283 
01284    /* I don't know what to do when called with zero base_width and height. */
01285    if (geom_mask & GDK_HINT_BASE_SIZE
01286        && geometry->base_width > 0 && geometry->base_height > 0)
01287       if (!GetWindowPlacement(GDK_DRAWABLE_XID(window), &size_hints))
01288          WIN32_API_FAILED("GetWindowPlacement");
01289       else {
01290          GDK_NOTE(MISC, g_print("gdk_window_set_geometry_hints:"
01291                                 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
01292                                 size_hints.rcNormalPosition.left,
01293                                 size_hints.rcNormalPosition.top,
01294                                 size_hints.rcNormalPosition.right,
01295                                 size_hints.rcNormalPosition.bottom));
01296          size_hints.rcNormalPosition.right =
01297              size_hints.rcNormalPosition.left + geometry->base_width;
01298          size_hints.rcNormalPosition.bottom =
01299              size_hints.rcNormalPosition.top + geometry->base_height;
01300          GDK_NOTE(MISC, g_print("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
01301                                 size_hints.rcNormalPosition.left,
01302                                 size_hints.rcNormalPosition.top,
01303                                 size_hints.rcNormalPosition.right,
01304                                 size_hints.rcNormalPosition.bottom));
01305          if (!SetWindowPlacement(GDK_DRAWABLE_XID(window), &size_hints))
01306             WIN32_API_FAILED("SetWindowPlacement");
01307       }
01308 
01309    if (geom_mask & GDK_HINT_RESIZE_INC) {
01310       /* XXX */
01311    }
01312 
01313    if (geom_mask & GDK_HINT_ASPECT) {
01314       /* XXX */
01315    }
01316 }
01317 
01318 void gdk_window_set_title(GdkWindow * window, const gchar * title)
01319 {
01320    gint titlelen;
01321    wchar_t *wcstr;
01322    gint wlen;
01323    char *mbstr;
01324 
01325    g_return_if_fail(window != NULL);
01326    g_return_if_fail(GDK_IS_WINDOW(window));
01327 
01328    GDK_NOTE(MISC, g_print("gdk_window_set_title: %#x %s\n",
01329                           GDK_DRAWABLE_XID(window), title));
01330    if (!GDK_DRAWABLE_DESTROYED(window)) {
01331 #if 0 // bb
01332       /* As the title is in UTF-8 we must translate it
01333        * to the system codepage.
01334        */
01335       titlelen = strlen(title);
01336       wcstr = g_new(wchar_t, titlelen + 1);
01337       mbstr = g_new(char, 3 * titlelen + 1);
01338       wlen = gdk_nmbstowchar_ts(wcstr, title, titlelen, titlelen);
01339       wcstr[wlen] = 0;
01340       WideCharToMultiByte(GetACP(), 0, wcstr, -1,
01341                           mbstr, 3 * titlelen, NULL, NULL);
01342 
01343       if (!SetWindowText(GDK_DRAWABLE_XID(window), mbstr))
01344          WIN32_API_FAILED("SetWindowText");
01345 
01346       g_free(mbstr);
01347       g_free(wcstr);
01348 #else // bb
01349       if (!SetWindowText(GDK_DRAWABLE_XID(window), title))
01350          WIN32_API_FAILED("SetWindowText");
01351 #endif // bb
01352    }
01353 }
01354 
01355 void gdk_window_set_role(GdkWindow * window, const gchar * role)
01356 {
01357    g_return_if_fail(window != NULL);
01358    g_return_if_fail(GDK_IS_WINDOW(window));
01359 
01360    GDK_NOTE(MISC, g_print("gdk_window_set_role: %#x %s\n",
01361                           GDK_DRAWABLE_XID(window),
01362                           (role ? role : "NULL")));
01363    /* XXX */
01364 }
01365 
01366 void gdk_window_set_transient_for(GdkWindow * window, GdkWindow * parent)
01367 {
01368    g_return_if_fail(window != NULL);
01369    g_return_if_fail(GDK_IS_WINDOW(window));
01370 
01371    g_return_if_fail(parent != NULL);
01372    g_return_if_fail(GDK_IS_WINDOW(parent));
01373 
01374    GDK_NOTE(MISC, g_print("gdk_window_set_transient_for: %#x %#x\n",
01375                           GDK_DRAWABLE_XID(window),
01376                           GDK_DRAWABLE_XID(parent)));
01377    SetLastError (0);
01378    if (SetWindowLong (GDK_DRAWABLE_XID(window), GWL_HWNDPARENT, 
01379        (long) GDK_DRAWABLE_XID(parent)) == 0 && GetLastError () != 0) {
01380       WIN32_API_FAILED ("SetWindowLong");
01381    }
01382 }
01383 
01384 void gdk_window_set_background(GdkWindow * window, GdkColor * color)
01385 {
01386    g_return_if_fail(window != NULL);
01387    g_return_if_fail(GDK_IS_WINDOW(window));
01388 
01389    if (!GDK_DRAWABLE_DESTROYED(window)) {
01390       GDK_NOTE(MISC, g_print("gdk_window_set_background: %#x %s\n",
01391                              GDK_DRAWABLE_XID(window),
01392                              gdk_win32_color_to_string(color)));
01393 
01394       if (GDK_WINDOW_WIN32DATA(window)->bg_type == GDK_WIN32_BG_PIXMAP) {
01395          if (GDK_WINDOW_WIN32DATA(window)->bg_pixmap != NULL) {
01396             gdk_drawable_unref(GDK_WINDOW_WIN32DATA(window)->bg_pixmap);
01397             GDK_WINDOW_WIN32DATA(window)->bg_pixmap = NULL;
01398          }
01399          GDK_WINDOW_WIN32DATA(window)->bg_type = GDK_WIN32_BG_NORMAL;
01400       }
01401       GDK_WINDOW_WIN32DATA(window)->bg_type = GDK_WIN32_BG_PIXEL;
01402       GDK_WINDOW_WIN32DATA(window)->bg_pixel = color->pixel;
01403    }
01404 }
01405 
01406 void
01407 gdk_window_set_back_pixmap(GdkWindow * window,
01408                            GdkPixmap * pixmap, gint parent_relative)
01409 {
01410    g_return_if_fail(window != NULL);
01411    g_return_if_fail(GDK_IS_WINDOW(window));
01412 
01413    if (!GDK_DRAWABLE_DESTROYED(window)) {
01414       if (GDK_WINDOW_WIN32DATA(window)->bg_type == GDK_WIN32_BG_PIXMAP) {
01415          if (GDK_WINDOW_WIN32DATA(window)->bg_pixmap != NULL) {
01416             gdk_drawable_unref(GDK_WINDOW_WIN32DATA(window)->bg_pixmap);
01417             GDK_WINDOW_WIN32DATA(window)->bg_pixmap = NULL;
01418          }
01419          GDK_WINDOW_WIN32DATA(window)->bg_type = GDK_WIN32_BG_NORMAL;
01420       }
01421       if (parent_relative) {
01422          GDK_WINDOW_WIN32DATA(window)->bg_type =
01423              GDK_WIN32_BG_PARENT_RELATIVE;
01424       } else if (!pixmap) {
01425 
01426       } else {
01427          /* We must cache the pixmap in the GdkWindowWin32Data and
01428           * paint it each time we get WM_ERASEBKGND
01429           */
01430          GDK_WINDOW_WIN32DATA(window)->bg_type = GDK_WIN32_BG_PIXMAP;
01431          GDK_WINDOW_WIN32DATA(window)->bg_pixmap = pixmap;
01432          gdk_drawable_ref(pixmap);
01433       }
01434    }
01435 }
01436 
01437 void
01438 gdk_window_set_cursor (GdkWindow *window,
01439                GdkCursor *cursor)
01440 {
01441    GdkCursorPrivate *cursor_private;
01442    HCURSOR xcursor;
01443    HCURSOR prev_xcursor;
01444    DWORD ThisThreadId, WinThreadId;
01445   
01446    g_return_if_fail (window != NULL);
01447    g_return_if_fail (GDK_IS_WINDOW (window));
01448   
01449    cursor_private = (GdkCursorPrivate*) cursor;
01450 
01451    if (GDK_DRAWABLE_DESTROYED (window))
01452       return;
01453 
01454    if (!cursor)
01455       xcursor = NULL;
01456    else
01457       xcursor = cursor_private->xcursor;
01458     
01459    GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
01460                (guint) GDK_DRAWABLE_XID (window), (guint) xcursor));
01461                
01462    /* First get the old cursor, if any (we wait to free the old one */
01463    /* since it may be the current cursor set in the win32 api right now) */
01464    prev_xcursor = GDK_WINDOW_WIN32DATA (window)->xcursor;
01465   
01466    /* New cursor is NULL */
01467    if (xcursor == NULL)
01468       GDK_WINDOW_WIN32DATA (window)->xcursor = NULL;
01469     
01470    /* New cursor is non-NULL.  We must copy the cursor as it is OK to */
01471    /* destroy the GdkCursor while still in use for some window. See for */
01472    /* instance gimp_change_win_cursor() which calls gdk_window_set_cursor */
01473    /* (win, cursor), and immediately afterwards gdk_cursor_destroy (cursor). */
01474    else {
01475       GDK_WINDOW_WIN32DATA (window)->xcursor = CopyCursor (xcursor);
01476       if (GDK_WINDOW_WIN32DATA (window)->xcursor == NULL) {
01477          WIN32_API_FAILED ("CopyCursor");
01478       }
01479       GDK_NOTE (MISC, g_print ("...CopyCursor (%#x) = %#x\n",
01480                    (guint) xcursor,
01481                    (guint) GDK_WINDOW_WIN32DATA (window)->xcursor));
01482    }
01483     
01484    /* Set new cursor in all cases if we're over our window */
01485    if (gdk_window_get_pointer(window, NULL, NULL, NULL) == window) {
01486       if (GDK_DRAWABLE_TYPE(window) == GDK_WINDOW_FOREIGN) {
01487          ThisThreadId = GetCurrentThreadId();
01488          WinThreadId = GetWindowThreadProcessId(GDK_DRAWABLE_XID(window), NULL);
01489          if (WinThreadId != ThisThreadId)
01490             AttachThreadInput(ThisThreadId, WinThreadId, TRUE);
01491          SetCursor (GDK_WINDOW_WIN32DATA (window)->xcursor);
01492          if (WinThreadId != ThisThreadId)
01493             AttachThreadInput(ThisThreadId, WinThreadId, FALSE);
01494       }
01495       else {
01496          SetCursor (GDK_WINDOW_WIN32DATA (window)->xcursor);
01497       }
01498    }
01499     
01500    /* Destroy the previous cursor:  Need to make sure it's no longer */
01501    /* in use before we destroy it, in case we're not over our window */
01502    /* but the cursor is still set to our old one. */
01503    if (prev_xcursor != NULL) {
01504       GDK_NOTE (MISC, g_print ("...DestroyCursor (%#x)\n",(guint) prev_xcursor));
01505       DestroyCursor (prev_xcursor);
01506    }
01507 }
01508 
01509 void
01510 gdk_window_get_geometry(GdkWindow * window,
01511                         gint * x,
01512                         gint * y,
01513                         gint * width, gint * height, gint * depth)
01514 {
01515    g_return_if_fail(window == NULL || GDK_IS_WINDOW(window));
01516 
01517    if (!window)
01518       window = gdk_parent_root;
01519 
01520    if (!GDK_DRAWABLE_DESTROYED(window)) {
01521       RECT rect;
01522 
01523       if (!GetClientRect(GDK_DRAWABLE_XID(window), &rect))
01524          WIN32_API_FAILED("GetClientRect");
01525 
01526       if (x)
01527          *x = rect.left;
01528       if (y)
01529          *y = rect.top;
01530       if (width)
01531          *width = rect.right - rect.left;
01532       if (height)
01533          *height = rect.bottom - rect.top;
01534       if (depth)
01535          *depth = gdk_drawable_get_visual(window)->depth;
01536    }
01537 }
01538 
01539 gint gdk_window_get_origin(GdkWindow * window, gint * x, gint * y)
01540 {
01541    gint return_val;
01542    gint tx = 0;
01543    gint ty = 0;
01544 
01545    g_return_val_if_fail(window != NULL, 0);
01546 
01547    if (!GDK_DRAWABLE_DESTROYED(window)) {
01548       POINT pt;
01549 
01550       pt.x = 0;
01551       pt.y = 0;
01552       ClientToScreen(GDK_DRAWABLE_XID(window), &pt);
01553       tx = pt.x;
01554       ty = pt.y;
01555       return_val = 1;
01556    } else
01557       return_val = 0;
01558 
01559    if (x)
01560       *x = tx;
01561    if (y)
01562       *y = ty;
01563 
01564    GDK_NOTE(MISC, g_print("gdk_window_get_origin: %#x: +%d+%d\n",
01565                           GDK_DRAWABLE_XID(window), tx, ty));
01566    return return_val;
01567 }
01568 
01569 gboolean
01570 gdk_window_get_deskrelative_origin(GdkWindow * window, gint * x, gint * y)
01571 {
01572    return gdk_window_get_origin(window, x, y);
01573 }
01574 
01575 void gdk_window_get_root_origin(GdkWindow * window, gint * x, gint * y)
01576 {
01577    GdkWindowPrivate *rover;
01578    POINT pt;
01579 
01580    g_return_if_fail(window != NULL);
01581    g_return_if_fail(GDK_IS_WINDOW(window));
01582 
01583    rover = (GdkWindowPrivate *) window;
01584    if (x)
01585       *x = 0;
01586    if (y)
01587       *y = 0;
01588    if (GDK_DRAWABLE_DESTROYED(window))
01589       return;
01590 
01591    while (rover->parent && ((GdkWindowPrivate *) rover->parent)->parent)
01592       rover = (GdkWindowPrivate *) rover->parent;
01593    if (rover->drawable.destroyed)
01594       return;
01595 
01596    pt.x = 0;
01597    pt.y = 0;
01598    ClientToScreen(GDK_DRAWABLE_XID(rover), &pt);
01599    if (x)
01600       *x = pt.x;
01601    if (y)
01602       *y = pt.y;
01603 
01604    GDK_NOTE(MISC,
01605             g_print("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
01606                     GDK_DRAWABLE_XID(window), GDK_DRAWABLE_XID(rover),
01607                     pt.x, pt.y));
01608 }
01609 
01610 GdkWindow*
01611 gdk_window_get_pointer (GdkWindow *window, gint *x, gint *y, GdkModifierType *mask)
01612 {
01613    GdkWindow *return_val;
01614    POINT screen_point, point;
01615    HWND hwnd, hwndc;
01616 
01617    g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
01618   
01619    if (!window)
01620       window = gdk_parent_root;
01621 
01622    return_val = NULL;
01623    GetCursorPos (&screen_point);
01624    point = screen_point;
01625    ScreenToClient (GDK_DRAWABLE_XID (window), &point);
01626 
01627    if (x)
01628       *x = point.x;
01629    if (y)
01630       *y = point.y;
01631 
01632    hwnd = WindowFromPoint (screen_point);
01633    if (hwnd != NULL) {
01634       BOOL done = FALSE;
01635 
01636       while (!done) {
01637          point = screen_point;
01638          ScreenToClient (hwnd, &point);
01639          hwndc = ChildWindowFromPoint (hwnd, point);
01640          if (hwndc == NULL)
01641             done = TRUE;
01642          else if (hwndc == hwnd)
01643             done = TRUE;
01644          else
01645             hwnd = hwndc;
01646       }
01647       return_val = gdk_window_lookup (hwnd);
01648    }
01649    else {
01650       return_val = NULL;
01651    }
01652 
01653    if (mask) {
01654       BYTE kbd[256];
01655 
01656       GetKeyboardState (kbd);
01657       *mask = 0;
01658       if (kbd[VK_SHIFT] & 0x80)
01659          *mask |= GDK_SHIFT_MASK;
01660       if (kbd[VK_CAPITAL] & 0x80)
01661          *mask |= GDK_LOCK_MASK;
01662       if (kbd[VK_CONTROL] & 0x80)
01663          *mask |= GDK_CONTROL_MASK;
01664       if (kbd[VK_MENU] & 0x80)
01665          *mask |= GDK_MOD1_MASK;
01666       if (kbd[VK_LBUTTON] & 0x80)
01667          *mask |= GDK_BUTTON1_MASK;
01668       if (kbd[VK_MBUTTON] & 0x80)
01669          *mask |= GDK_BUTTON2_MASK;
01670       if (kbd[VK_RBUTTON] & 0x80)
01671          *mask |= GDK_BUTTON3_MASK;
01672    }
01673   
01674    return return_val;
01675 }
01676 
01677 GdkWindow *gdk_window_at_pointer(gint * win_x, gint * win_y)
01678 {
01679    GdkWindow *window;
01680    POINT point, pointc;
01681    HWND hwnd, hwndc;
01682    RECT rect;
01683 
01684    GetCursorPos(&pointc);
01685    point = pointc;
01686    hwnd = WindowFromPoint(point);
01687 
01688    if (hwnd == NULL) {
01689       window = gdk_parent_root;
01690       if (win_x)
01691          *win_x = pointc.x;
01692       if (win_y)
01693          *win_y = pointc.y;
01694       return window;
01695    }
01696 
01697    ScreenToClient(hwnd, &point);
01698 
01699    do {
01700       hwndc = ChildWindowFromPoint(hwnd, point);
01701       ClientToScreen(hwnd, &point);
01702       ScreenToClient(hwndc, &point);
01703    } while (hwndc != hwnd && (hwnd = hwndc, 1));
01704 
01705    window = gdk_window_lookup(hwnd);
01706 
01707    if (window && (win_x || win_y)) {
01708       GetClientRect(hwnd, &rect);
01709       if (win_x)
01710          *win_x = point.x - rect.left;
01711       if (win_y)
01712          *win_y = point.y - rect.top;
01713    }
01714 
01715    GDK_NOTE(MISC, g_print("gdk_window_at_pointer: +%d+%d %#x%s\n",
01716                           point.x, point.y, hwnd,
01717                           (window == NULL ? " NULL" : "")));
01718 
01719    return window;
01720 }
01721 
01722 GList *gdk_window_get_children(GdkWindow * window)
01723 {
01724    GdkWindowPrivate *private;
01725    GList *children;
01726 
01727    g_return_val_if_fail(window != NULL, NULL);
01728    g_return_val_if_fail(GDK_IS_WINDOW(window), NULL);
01729 
01730    if (GDK_DRAWABLE_DESTROYED(window))
01731       return NULL;
01732 
01733    /* XXX ??? */
01734    g_warning("gdk_window_get_children not implemented");
01735    children = NULL;
01736 
01737    return children;
01738 }
01739 
01740 GdkEventMask gdk_window_get_events(GdkWindow * window)
01741 {
01742    g_return_val_if_fail(window != NULL, 0);
01743    g_return_val_if_fail(GDK_IS_WINDOW(window), 0);
01744 
01745    if (GDK_DRAWABLE_DESTROYED(window))
01746       return 0;
01747 
01748    return GDK_WINDOW_WIN32DATA(window)->event_mask;
01749 }
01750 
01751 void gdk_window_set_events(GdkWindow * window, GdkEventMask event_mask)
01752 {
01753    g_return_if_fail(window != NULL);
01754    g_return_if_fail(GDK_IS_WINDOW(window));
01755 
01756    if (GDK_DRAWABLE_DESTROYED(window))
01757       return;
01758 
01759    GDK_WINDOW_WIN32DATA(window)->event_mask = event_mask;
01760 }
01761 
01762 void gdk_window_add_colormap_windows(GdkWindow * window)
01763 {
01764    g_warning("gdk_window_add_colormap_windows not implemented");
01765 }
01766 
01767 void
01768 gdk_window_shape_combine_mask(GdkWindow * window,
01769                               GdkBitmap * mask, gint x, gint y)
01770 {
01771    g_return_if_fail(window != NULL);
01772    g_return_if_fail(GDK_IS_WINDOW(window));
01773 
01774    if (!mask) {
01775       GDK_NOTE(MISC, g_print("gdk_window_shape_combine_mask: %#x none\n",
01776                              GDK_DRAWABLE_XID(window)));
01777       SetWindowRgn(GDK_DRAWABLE_XID(window), NULL, TRUE);
01778    } else {
01779       HRGN hrgn;
01780       DWORD dwStyle;
01781       DWORD dwExStyle;
01782       RECT rect;
01783 
01784       /* Convert mask bitmap to region */
01785       hrgn = BitmapToRegion(GDK_DRAWABLE_XID(mask));
01786 
01787       GDK_NOTE(MISC, g_print("gdk_window_shape_combine_mask: %#x %#x\n",
01788                              GDK_DRAWABLE_XID(window),
01789                              GDK_DRAWABLE_XID(mask)));
01790 
01791       /* SetWindowRgn wants window (not client) coordinates */
01792       dwStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE);
01793       dwExStyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_EXSTYLE);
01794       GetClientRect(GDK_DRAWABLE_XID(window), &rect);
01795       AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
01796       OffsetRgn(hrgn, -rect.left, -rect.top);
01797 
01798       OffsetRgn(hrgn, x, y);
01799 
01800       /* If this is a top-level window, add the title bar to the region */
01801       if (GDK_DRAWABLE_TYPE(window) == GDK_WINDOW_TOPLEVEL) {
01802          CombineRgn(hrgn, hrgn,
01803                     CreateRectRgn(0, 0, rect.right - rect.left, -rect.top),
01804                     RGN_OR);
01805       }
01806 
01807       SetWindowRgn(GDK_DRAWABLE_XID(window), hrgn, TRUE);
01808    }
01809 }
01810 
01811 void
01812 gdk_window_set_override_redirect(GdkWindow * window,
01813                                  gboolean override_redirect)
01814 {
01815    g_return_if_fail(window != NULL);
01816    g_return_if_fail(GDK_IS_WINDOW(window));
01817 
01818    g_warning("gdk_window_set_override_redirect not implemented");
01819 }
01820 
01821 void
01822 gdk_window_set_icon(GdkWindow * window,
01823                     GdkWindow * icon_window,
01824                     GdkPixmap * pixmap, GdkBitmap * mask)
01825 {
01826 // bb add begin  
01827    int sizex, sizey;
01828    HICON hicon;
01829    ICONINFO icon_info;
01830    HDC hdc_src, hdc_dst;
01831    HBITMAP hbitmap_mask, old_bitmap_src, old_bitmap_dst;
01832 // bb add end  
01833 
01834    g_return_if_fail(window != NULL);
01835    g_return_if_fail(GDK_IS_WINDOW(window));
01836 
01837 // bb add begin  
01838    gdk_drawable_get_size(pixmap, &sizex, &sizey);
01839    // Create temporary dc's
01840    hdc_dst = CreateCompatibleDC(NULL);
01841    hdc_src = CreateCompatibleDC(NULL);
01842 
01843    // Copy mask in color (transparent pixels should be black)
01844    old_bitmap_dst =
01845        (HBITMAP) SelectObject(hdc_dst, (HBITMAP) GDK_DRAWABLE_XID(pixmap));
01846    old_bitmap_src =
01847        (HBITMAP) SelectObject(hdc_src, (HBITMAP) GDK_DRAWABLE_XID(mask));
01848 
01849    BitBlt(hdc_dst, 0, 0, sizex, sizey, hdc_src, 0, 0, SRCAND);
01850 
01851    // Copy inverted mask in b&w bitmap
01852    hbitmap_mask = CreateCompatibleBitmap(hdc_dst, sizex, sizey);
01853    SelectObject(hdc_dst, hbitmap_mask);
01854 
01855    BitBlt(hdc_dst, 0, 0, sizex, sizey, hdc_src, 0, 0, NOTSRCCOPY);
01856 
01857    DeleteObject(old_bitmap_dst);
01858    DeleteObject(old_bitmap_src);
01859 
01860    // Delete dc's
01861    DeleteDC(hdc_dst);
01862    DeleteDC(hdc_src);
01863 
01864    // Create icon
01865    icon_info.fIcon = TRUE;
01866    icon_info.xHotspot = 0;
01867    icon_info.yHotspot = 0;
01868    icon_info.hbmMask = hbitmap_mask;
01869    icon_info.hbmColor = (HBITMAP) GDK_DRAWABLE_XID(pixmap);
01870 
01871    hicon = CreateIconIndirect(&icon_info);
01872 
01873    SetClassLong((HWND)GDK_DRAWABLE_XID(window), GCL_HICONSM, (LPARAM)CopyIcon(hicon));
01874    SetClassLong((HWND)GDK_DRAWABLE_XID(window), GCL_HICON, (LPARAM)CopyIcon(hicon));
01875 
01876    DestroyIcon(hicon);
01877    DeleteObject(hbitmap_mask);
01878 // bb add end  
01879    /* Nothing to do, really. As we share window classes between windows
01880     * we can't have window-specific icons, sorry. Don't print any warning
01881     * either.
01882     */
01883 }
01884 
01885 void gdk_window_set_icon_name(GdkWindow * window, const gchar * name)
01886 {
01887    g_return_if_fail(window != NULL);
01888    g_return_if_fail(GDK_IS_WINDOW(window));
01889 
01890    if (GDK_DRAWABLE_DESTROYED(window))
01891       return;
01892 
01893    if (!SetWindowText(GDK_DRAWABLE_XID(window), name))
01894       WIN32_API_FAILED("SetWindowText");
01895 }
01896 
01897 void gdk_window_set_group(GdkWindow * window, GdkWindow * leader)
01898 {
01899    g_return_if_fail(window != NULL);
01900    g_return_if_fail(GDK_IS_WINDOW(window));
01901    g_return_if_fail(leader != NULL);
01902    g_return_if_fail(GDK_IS_WINDOW(leader));
01903 
01904    if (GDK_DRAWABLE_DESTROYED(window) || GDK_DRAWABLE_DESTROYED(leader))
01905       return;
01906 
01907    g_warning("gdk_window_set_group not implemented");
01908 }
01909 
01910 void
01911 gdk_window_set_decorations(GdkWindow * window, GdkWMDecoration decorations)
01912 {
01913    LONG style, exstyle;
01914 
01915    g_return_if_fail(window != NULL);
01916    g_return_if_fail(GDK_IS_WINDOW(window));
01917 
01918    style = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE);
01919    exstyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_EXSTYLE);
01920 
01921    style &=
01922        (WS_OVERLAPPED | WS_POPUP | WS_CHILD | WS_MINIMIZE | WS_VISIBLE |
01923         WS_DISABLED | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_MAXIMIZE);
01924 
01925 //   exstyle &= (WS_EX_TOPMOST | WS_EX_TRANSPARENT);
01926    exstyle &= WS_EX_TRANSPARENT;
01927 
01928    if (decorations & GDK_DECOR_ALL)
01929       style |=
01930           (WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX |
01931            WS_MAXIMIZEBOX);
01932    if (decorations & GDK_DECOR_BORDER)
01933       style |= (WS_BORDER);
01934    if (decorations & GDK_DECOR_RESIZEH)
01935       style |= (WS_THICKFRAME);
01936    if (decorations & GDK_DECOR_TITLE)
01937       style |= (WS_CAPTION);
01938    if (decorations & GDK_DECOR_MENU)
01939       style |= (WS_SYSMENU);
01940    if (decorations & GDK_DECOR_MINIMIZE)
01941       style |= (WS_MINIMIZEBOX);
01942    if (decorations & GDK_DECOR_MAXIMIZE)
01943       style |= (WS_MAXIMIZEBOX);
01944 
01945    SetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE, style);
01946 }
01947 
01948 void gdk_window_set_functions(GdkWindow * window, GdkWMFunction functions)
01949 {
01950    LONG style, exstyle;
01951 
01952    g_return_if_fail(window != NULL);
01953    g_return_if_fail(GDK_IS_WINDOW(window));
01954 
01955    style = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE);
01956    exstyle = GetWindowLong(GDK_DRAWABLE_XID(window), GWL_EXSTYLE);
01957 
01958    style &=
01959        (WS_OVERLAPPED | WS_POPUP | WS_CHILD | WS_MINIMIZE | WS_VISIBLE |
01960         WS_DISABLED | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_MAXIMIZE |
01961         WS_CAPTION | WS_BORDER | WS_SYSMENU);
01962 
01963 //   exstyle &= (WS_EX_TOPMOST | WS_EX_TRANSPARENT);
01964    exstyle &= WS_EX_TRANSPARENT;
01965 
01966    if (functions & GDK_FUNC_ALL)
01967       style |= (WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
01968    if (functions & GDK_FUNC_RESIZE)
01969       style |= (WS_THICKFRAME);
01970    if (functions & GDK_FUNC_MOVE)
01971       style |= (WS_THICKFRAME);
01972    if (functions & GDK_FUNC_MINIMIZE)
01973       style |= (WS_MINIMIZEBOX);
01974    if (functions & GDK_FUNC_MAXIMIZE)
01975       style |= (WS_MAXIMIZEBOX);
01976 
01977    SetWindowLong(GDK_DRAWABLE_XID(window), GWL_STYLE, style);
01978 }
01979 
01980 /* 
01981  * propagate the shapes from all child windows of a GDK window to the parent 
01982  * window. Shamelessly ripped from Enlightenment's code
01983  * 
01984  * - Raster
01985  */
01986 
01987 static void QueryTree(HWND hwnd, HWND ** children, gint * nchildren)
01988 {
01989    guint i, n;
01990    HWND child;
01991 
01992    n = 0;
01993    do {
01994       if (n == 0)
01995          child = GetWindow(hwnd, GW_CHILD);
01996       else
01997          child = GetWindow(child, GW_HWNDNEXT);
01998       if (child != NULL)
01999          n++;
02000    } while (child != NULL);
02001 
02002    if (n > 0) {
02003       *children = g_new(HWND, n);
02004       for (i = 0; i < n; i++) {
02005          if (i == 0)
02006             child = GetWindow(hwnd, GW_CHILD);
02007          else
02008             child = GetWindow(child, GW_HWNDNEXT);
02009          *children[i] = child;
02010       }
02011    }
02012 }
02013 
02014 static void gdk_propagate_shapes(HANDLE win, gboolean merge)
02015 {
02016    RECT emptyRect;
02017    HRGN region, childRegion;
02018    RECT rect;
02019    HWND *list = NULL;
02020    gint i, num;
02021 
02022    SetRectEmpty(&emptyRect);
02023    region = CreateRectRgnIndirect(&emptyRect);
02024    if (merge)
02025       GetWindowRgn(win, region);
02026 
02027    QueryTree(win, &list, &num);
02028    if (list != NULL) {
02029       WINDOWPLACEMENT placement;
02030 
02031       placement.length = sizeof(WINDOWPLACEMENT);
02032       /* go through all child windows and combine regions */
02033       for (i = 0; i < num; i++) {
02034          GetWindowPlacement(list[i], &placement);
02035          if (placement.showCmd == SW_SHOWNORMAL) {
02036             childRegion = CreateRectRgnIndirect(&emptyRect);
02037             GetWindowRgn(list[i], childRegion);
02038             CombineRgn(region, region, childRegion, RGN_OR);
02039             DeleteObject(childRegion);
02040          }
02041       }
02042       SetWindowRgn(win, region, TRUE);
02043       g_free (list);
02044    } else
02045       DeleteObject(region);
02046 }
02047 
02048 void gdk_window_set_child_shapes(GdkWindow * window)
02049 {
02050    g_return_if_fail(window != NULL);
02051    g_return_if_fail(GDK_IS_WINDOW(window));
02052 
02053    if (GDK_DRAWABLE_DESTROYED(window))
02054       return;
02055 
02056    gdk_propagate_shapes(GDK_DRAWABLE_XID(window), FALSE);
02057 }
02058 
02059 void gdk_window_merge_child_shapes(GdkWindow * window)
02060 {
02061    g_return_if_fail(window != NULL);
02062    g_return_if_fail(GDK_IS_WINDOW(window));
02063 
02064    if (GDK_DRAWABLE_DESTROYED(window))
02065       return;
02066 
02067    gdk_propagate_shapes(GDK_DRAWABLE_XID(window), TRUE);
02068 }
02069 
02070 /* Support for windows that can be guffaw-scrolled
02071  * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
02072  */
02073 
02074 static gboolean gdk_window_gravity_works(void)
02075 {
02076    enum { UNKNOWN, NO, YES };
02077    static gint gravity_works = UNKNOWN;
02078 
02079    if (gravity_works == UNKNOWN) {
02080       GdkWindowAttr attr;
02081       GdkWindow *parent;
02082       GdkWindow *child;
02083       gint y;
02084 
02085       attr.window_type = GDK_WINDOW_TEMP;
02086       attr.wclass = GDK_INPUT_OUTPUT;
02087       attr.x = 0;
02088       attr.y = 0;
02089       attr.width = 100;
02090       attr.height = 100;
02091       attr.event_mask = 0;
02092 
02093       parent = gdk_window_new(NULL, &attr, GDK_WA_X | GDK_WA_Y);
02094 
02095       attr.window_type = GDK_WINDOW_CHILD;
02096       child = gdk_window_new(parent, &attr, GDK_WA_X | GDK_WA_Y);
02097 
02098       gdk_window_set_static_win_gravity(child, TRUE);
02099 
02100       gdk_window_resize(parent, 100, 110);
02101       gdk_window_move(parent, 0, -10);
02102       gdk_window_move_resize(parent, 0, 0, 100, 100);
02103 
02104       gdk_window_resize(parent, 100, 110);
02105       gdk_window_move(parent, 0, -10);
02106       gdk_window_move_resize(parent, 0, 0, 100, 100);
02107 
02108       gdk_window_get_geometry(child, NULL, &y, NULL, NULL, NULL);
02109 
02110       gdk_window_destroy(parent, TRUE);
02111       gdk_window_destroy(child, TRUE);
02112 
02113       gravity_works = ((y == -20) ? YES : NO);
02114    }
02115 
02116    return (gravity_works == YES);
02117 }
02118 
02119 static void
02120 gdk_window_set_static_bit_gravity(GdkWindow * window, gboolean on)
02121 {
02122    g_return_if_fail(window != NULL);
02123 
02124    GDK_NOTE(MISC,
02125             g_print
02126             ("gdk_window_set_static_bit_gravity: Not implemented\n"));
02127 }
02128 
02129 static void
02130 gdk_window_set_static_win_gravity(GdkWindow * window, gboolean on)
02131 {
02132    g_return_if_fail(window != NULL);
02133 
02134    GDK_NOTE(MISC,
02135             g_print
02136             ("gdk_window_set_static_win_gravity: Not implemented\n"));
02137 }
02138 
02139 /*************************************************************
02140  * gdk_window_set_static_gravities:
02141  *     Set the bit gravity of the given window to static,
02142  *     and flag it so all children get static subwindow
02143  *     gravity.
02144  *   arguments:
02145  *     window: window for which to set static gravity
02146  *     use_static: Whether to turn static gravity on or off.
02147  *   results:
02148  *     Does the XServer support static gravity?
02149  *************************************************************/
02150 
02151 gboolean
02152 gdk_window_set_static_gravities(GdkWindow * window, gboolean use_static)
02153 {
02154    GdkWindowPrivate *private = (GdkWindowPrivate *) window;
02155    GList *tmp_list;
02156 
02157    g_return_val_if_fail(window != NULL, FALSE);
02158    g_return_val_if_fail(GDK_IS_WINDOW(window), FALSE);
02159 
02160    if (!use_static == !private->guffaw_gravity)
02161       return TRUE;
02162 
02163    if (use_static && !gdk_window_gravity_works())
02164       return FALSE;
02165 
02166    private->guffaw_gravity = use_static;
02167 
02168    if (!GDK_DRAWABLE_DESTROYED(window)) {
02169       gdk_window_set_static_bit_gravity(window, use_static);
02170 
02171       tmp_list = private->children;
02172       while (tmp_list) {
02173          gdk_window_set_static_win_gravity(window, use_static);
02174 
02175          tmp_list = tmp_list->next;
02176       }
02177    }
02178 
02179    return TRUE;
02180 }

Generated on Tue Jul 5 14:14:40 2011 for ROOT_528-00b_version by  doxygen 1.5.1