Change to the linux kernel coding style
[wmaker-crm.git] / src / client.c
dissimilarity index 85%
index 14ec9d1..1fdab42 100644 (file)
-/*
- *  Window Maker window manager
- *
- *  Copyright (c) 1997-2003 Alfredo K. Kojima
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program 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 General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- *  USA.
- */
-#include "wconfig.h"
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#ifdef SHAPE
-#include <X11/extensions/shape.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "WindowMaker.h"
-#include "wcore.h"
-#include "framewin.h"
-#include "window.h"
-#include "properties.h"
-#include "actions.h"
-#include "icon.h"
-#include "client.h"
-#include "funcs.h"
-#include "stacking.h"
-#include "appicon.h"
-#include "appmenu.h"
-#ifdef NETWM_HINTS
-# include "wmspec.h"
-#endif
-
-
-/****** Global Variables ******/
-
-/* contexts */
-extern XContext wWinContext;
-
-extern Atom _XA_WM_STATE;
-extern Atom _XA_WM_PROTOCOLS;
-extern Atom _XA_WM_COLORMAP_WINDOWS;
-
-extern Atom _XA_WINDOWMAKER_MENU;
-
-extern Atom _XA_GNUSTEP_WM_ATTR;
-extern Atom _XA_GNUSTEP_WM_RESIZEBAR;
-
-#ifdef SHAPE
-extern Bool wShapeSupported;
-#endif
-
-
-/*
- *--------------------------------------------------------------------
- * wClientRestore--
- *     Reparent the window back to the root window.
- *
- *--------------------------------------------------------------------
- */
-void
-wClientRestore(WWindow *wwin)
-{
-#if 0
-    int gx, gy;
-
-    wClientGetGravityOffsets(wwin, &gx, &gy);
-    /* set the positio of the frame on screen */
-    wwin->frame_x -= gx * FRAME_BORDER_WIDTH;
-    wwin->frame_y -= gy * FRAME_BORDER_WIDTH;
-    /* if gravity is to the south, account for the border sizes */
-    if (gy > 0)
-        wwin->frame_y += (wwin->frame->top_width + wwin->frame->bottom_width);
-#endif
-    XSetWindowBorderWidth(dpy, wwin->client_win, wwin->old_border_width);
-    XReparentWindow(dpy, wwin->client_win, wwin->screen_ptr->root_win,
-                    wwin->frame_x, wwin->frame_y);
-
-    /* don't let the window get iconified after restart */
-    /*
-     if (wwin->flags.shaded)
-     wClientSetState(wwin, NormalState, None);
-     */
-}
-
-
-/*
- *----------------------------------------------------------------------
- * wClientSetState--
- *     Set the state of the client window to one of the window
- * states defined in ICCCM (Iconic, Withdrawn, Normal)
- *
- * Side effects:
- *     The WM_STATE property of the window is updated as well as the
- * WWindow.state variable.
- *----------------------------------------------------------------------
- */
-void
-wClientSetState(WWindow *wwin, int state, Window icon_win)
-{
-    CARD32 data[2];
-
-    wwin->state = state;
-
-    data[0] = (unsigned long) state;
-    data[1] = (unsigned long) icon_win;
-
-    XChangeProperty(dpy, wwin->client_win, _XA_WM_STATE, _XA_WM_STATE, 32,
-                    PropModeReplace, (unsigned char *) data, 2);
-}
-
-
-void
-wClientGetGravityOffsets(WWindow *wwin, int *ofs_x, int *ofs_y)
-{
-    switch (wwin->normal_hints->win_gravity) {
-    case ForgetGravity:
-    case CenterGravity:
-    case StaticGravity:
-        *ofs_x = 0;
-        *ofs_y = 0;
-        break;
-    case NorthWestGravity:
-        *ofs_x = -1;
-        *ofs_y = -1;
-        break;
-    case NorthGravity:
-        *ofs_x = 0;
-        *ofs_y = -1;
-        break;
-    case NorthEastGravity:
-        *ofs_x = 1;
-        *ofs_y = -1;
-        break;
-    case WestGravity:
-        *ofs_x = -1;
-        *ofs_y = 0;
-        break;
-    case EastGravity:
-        *ofs_x = 1;
-        *ofs_y = 0;
-        break;
-    case SouthWestGravity:
-        *ofs_x = -1;
-        *ofs_y = 1;
-        break;
-    case SouthGravity:
-        *ofs_x = 0;
-        *ofs_y = 1;
-        break;
-    case SouthEastGravity:
-        *ofs_x = 1;
-        *ofs_y = 1;
-        break;
-    }
-}
-
-
-
-void
-wClientConfigure(WWindow *wwin, XConfigureRequestEvent *xcre)
-{
-    XWindowChanges xwc;
-    int nx, ny, nwidth, nheight;
-    int ofs_x, ofs_y;
-
-    /*  printf("configure event: %d %d %d %d\n", xcre->x, xcre->y, xcre->width, xcre->height);*/
-
-    if (wwin==NULL) {
-        /*
-         * configure a window that was not mapped by us
-         */
-        xwc.x = xcre->x;
-        xwc.y = xcre->y;
-        xwc.width = xcre->width;
-        xwc.height = xcre->height;
-        xwc.border_width = xcre->border_width;
-        xwc.stack_mode = xcre->detail;
-        xwc.sibling = xcre->above;
-        XConfigureWindow(dpy, xcre->window, xcre->value_mask, &xwc);
-        return;
-    }
-#ifdef SHAPE
-    if (wShapeSupported) {
-        int junk;
-        unsigned int ujunk;
-        int b_shaped;
-
-        XShapeSelectInput(dpy, wwin->client_win, ShapeNotifyMask);
-        XShapeQueryExtents(dpy, wwin->client_win, &b_shaped, &junk, &junk,
-                           &ujunk, &ujunk, &junk, &junk, &junk, &ujunk,
-                           &ujunk);
-        wwin->flags.shaped = b_shaped;
-    }
-#endif
-    if (xcre->value_mask & CWStackMode) {
-        WObjDescriptor *desc;
-        WWindow *sibling;
-
-        if ((xcre->value_mask & CWSibling) &&
-            (XFindContext(dpy, xcre->above, wWinContext,
-                          (XPointer *)&desc) == XCSUCCESS)
-            && (desc->parent_type==WCLASS_WINDOW)) {
-            sibling=desc->parent;
-            xwc.sibling = sibling->frame->core->window;
-        } else {
-            xwc.sibling = xcre->above;
-        }
-        xwc.stack_mode = xcre->detail;
-        XConfigureWindow(dpy, wwin->frame->core->window,
-                         xcre->value_mask & (CWSibling | CWStackMode), &xwc);
-        /* fix stacking order */
-        RemakeStackList(wwin->screen_ptr);
-    }
-
-    wClientGetGravityOffsets(wwin, &ofs_x, &ofs_y);
-
-    if (xcre->value_mask & CWBorderWidth) {
-        wwin->old_border_width = xcre->border_width;
-    }
-
-    if (!wwin->flags.shaded) {
-        /* If the window is shaded, wrong height will be set for the window */
-        if (xcre->value_mask & CWX) {
-            nx = xcre->x;
-            /* Subtracting the border makes the window shift by 1 pixel -Dan */
-            /*if (HAS_BORDER(wwin)) {
-                nx -= FRAME_BORDER_WIDTH;
-            }*/
-        } else {
-            nx = wwin->frame_x;
-        }
-
-        if (xcre->value_mask & CWY) {
-            ny = xcre->y - ((ofs_y < 0) ? 0 : wwin->frame->top_width);
-            /* Subtracting the border makes the window shift by 1 pixel -Dan */
-            /*if (HAS_BORDER(wwin)) {
-                ny -= FRAME_BORDER_WIDTH;
-            }*/
-        } else {
-            ny = wwin->frame_y;
-        }
-
-        if (xcre->value_mask & CWWidth)
-            nwidth = xcre->width;
-        else
-            nwidth = wwin->frame->core->width;
-
-        if (xcre->value_mask & CWHeight)
-            nheight = xcre->height;
-        else
-            nheight = wwin->frame->core->height - wwin->frame->top_width - wwin->frame->bottom_width;
-
-        wWindowConfigure(wwin, nx, ny, nwidth, nheight);
-        wwin->old_geometry.x = nx;
-        wwin->old_geometry.y = ny;
-        wwin->old_geometry.width = nwidth;
-        wwin->old_geometry.height = nheight;
-    }
-}
-
-
-void
-wClientSendProtocol(WWindow *wwin, Atom protocol, Time time)
-{
-    XEvent event;
-
-    event.xclient.type = ClientMessage;
-    event.xclient.message_type = _XA_WM_PROTOCOLS;
-    event.xclient.format = 32;
-    event.xclient.display = dpy;
-    event.xclient.window = wwin->client_win;
-    event.xclient.data.l[0] = protocol;
-    event.xclient.data.l[1] = time;
-    event.xclient.data.l[2] = 0;
-    event.xclient.data.l[3] = 0;
-    XSendEvent(dpy, wwin->client_win, False, NoEventMask, &event);
-    XSync(dpy, False);
-}
-
-
-
-void
-wClientKill(WWindow *wwin)
-{
-    XKillClient(dpy, wwin->client_win);
-
-    XFlush(dpy);
-}
-
-
-
-/*
- *----------------------------------------------------------------------
- * wClientCheckProperty--
- *     Handles PropertyNotify'es, verifying which property was
- * changed and updating internal state according to that, like redrawing
- * the icon title when it is changed.
- *
- * Side effects:
- *     Depends on the changed property.
- *
- * TODO: _GNUSTEP_WM_ATTR
- *----------------------------------------------------------------------
- */
-void
-wClientCheckProperty(WWindow *wwin, XPropertyEvent *event)
-{
-    XWindowAttributes attribs;
-    XWMHints *new_hints;
-    int i, g1, g2;
-    char *tmp = NULL;
-
-    switch (event->atom) {
-    case XA_WM_NAME:
-        if (!wwin->flags.net_has_title)
-        {
-            /* window title was changed */
-            if (!wFetchName(dpy, wwin->client_win, &tmp)) {
-                wWindowUpdateName(wwin, NULL);
-            } else {
-                wWindowUpdateName(wwin, tmp);
-            }
-            if (tmp)
-              XFree(tmp);
-        }
-        break;
-
-    case XA_WM_ICON_NAME:
-        if (!wwin->flags.net_has_icon_title)
-        {
-            if (!wwin->icon)
-              break;
-            else {
-                char *new_title;
-                
-                /* icon title was changed */
-                wGetIconName(dpy, wwin->client_win, &new_title);
-                wIconChangeTitle(wwin->icon, new_title);
-            }
-        }
-        break;
-
-    case XA_WM_COMMAND:
-        if (wwin->main_window!=None) {
-            WApplication *wapp = wApplicationOf(wwin->main_window);
-            char *command;
-
-            if (!wapp || !wapp->app_icon || wapp->app_icon->docked)
-                break;
-
-            command = GetCommandForWindow(wwin->main_window);
-            if (command) {
-                if (wapp->app_icon->command)
-                    wfree(wapp->app_icon->command);
-                wapp->app_icon->command = command;
-            }
-        }
-        break;
-
-    case XA_WM_HINTS:
-        /* WM_HINTS */
-
-        new_hints = XGetWMHints(dpy, wwin->client_win);
-
-        /* group leader update
-         *
-         * This means that the window is setting the leader after
-         * it was mapped, changing leaders or removing the leader.
-         *
-         * Valid state transitions are:
-         *
-         *          _1            __2
-         *         / \           /  \
-         *         v |           v  |
-         *         (GC)         (GC')
-         *        /  ^          /   ^
-         *       3|  |4        5|   |6
-         *        |  |          |   |
-         *        v  /          v   /
-         *        (G'C)        (G'C')
-         *
-         * Where G is the window_group hint, C is CLIENT_LEADER property
-         * and ' indicates the hint is unset.
-         *
-         * 1,2 - change group leader to new value of window_group
-         * 3 - change leader to value of CLIENT_LEADER
-         * 4 - change leader to value of window_group
-         * 5 - destroy application
-         * 6 - create application
-         */
-        if (new_hints && (new_hints->flags & WindowGroupHint)
-            && new_hints->window_group!=None) {
-            g2 = 1;
-        } else {
-            g2 = 0;
-        }
-        if (wwin->wm_hints && (wwin->wm_hints->flags & WindowGroupHint)
-            && wwin->wm_hints->window_group!=None) {
-            g1 = 1;
-        } else {
-            g1 = 0;
-        }
-
-        if (wwin->client_leader) {
-            if (g1 && g2
-                && wwin->wm_hints->window_group!=new_hints->window_group) {
-                i = 1;
-            } else if (g1 && !g2) {
-                i = 3;
-            } else if (!g1 && g2) {
-                i = 4;
-            } else {
-                i = 0;
-            }
-        } else {
-            if (g1 && g2
-                && wwin->wm_hints->window_group!=new_hints->window_group) {
-                i = 2;
-            } else if (g1 && !g2) {
-                i = 5;
-            } else if (!g1 && g2) {
-                i = 6;
-            } else {
-                i = 0;
-            }
-        }
-
-        /* Handling this may require more work. -Dan */
-        if (wwin->fake_group!=NULL) {
-            i = 7;
-        }
-
-        if (wwin->wm_hints)
-            XFree(wwin->wm_hints);
-
-        wwin->wm_hints = new_hints;
-
-        /* do action according to state transition */
-        switch (i) {
-            /* 3 - change leader to value of CLIENT_LEADER */
-        case 3:
-            wApplicationDestroy(wApplicationOf(wwin->main_window));
-            wwin->main_window = wwin->client_leader;
-            wwin->group_id = None;
-            wApplicationCreate(wwin);
-            break;
-
-            /* 1,2,4 - change leader to new value of window_group */
-        case 1:
-        case 2:
-        case 4:
-            wApplicationDestroy(wApplicationOf(wwin->main_window));
-            wwin->main_window = new_hints->window_group;
-            wwin->group_id = wwin->main_window;
-            wApplicationCreate(wwin);
-            break;
-
-            /* 5 - destroy application */
-        case 5:
-            wApplicationDestroy(wApplicationOf(wwin->main_window));
-            wwin->main_window = None;
-            wwin->group_id = None;
-            break;
-
-            /* 6 - create application */
-        case 6:
-            wwin->main_window = new_hints->window_group;
-            wwin->group_id = wwin->main_window;
-            wApplicationCreate(wwin);
-            break;
-            /* 7 - we have a fake window group id, so just ignore anything else */
-        case 7:
-            break;
-        }
-#ifdef DEBUG
-        if (i) {
-            printf("window leader update caused state transition %i\n",i);
-        }
-#endif
-
-        if (wwin->wm_hints) {
-            /* update icon */
-            if ((wwin->wm_hints->flags & IconPixmapHint)
-                || (wwin->wm_hints->flags & IconWindowHint)) {
-                WApplication *wapp;
-
-                if (wwin->flags.miniaturized && wwin->icon) {
-                    wIconUpdate(wwin->icon);
-                }
-                wapp = wApplicationOf(wwin->main_window);
-                if (wapp && wapp->app_icon) {
-                    wIconUpdate(wapp->app_icon->icon);
-                }
-            }
-
-            if (wwin->wm_hints->flags & UrgencyHint)
-                wwin->flags.urgent = 1;
-            else
-                wwin->flags.urgent = 0;
-            /*} else if (wwin->fake_group!=NULL) {
-             wwin->group_id = wwin->fake_group->leader;*/
-        } else {
-            wwin->group_id = None;
-        }
-        break;
-
-    case XA_WM_NORMAL_HINTS:
-        /* normal (geometry) hints */
-        {
-            int foo;
-            unsigned bar;
-
-            XGetWindowAttributes(dpy, wwin->client_win, &attribs);
-            wClientGetNormalHints(wwin, &attribs, False, &foo, &foo,
-                                  &bar, &bar);
-            /* TODO: should we check for consistency of the current
-             * size against the new geometry hints? */
-        }
-        break;
-
-    case XA_WM_TRANSIENT_FOR:
-        {
-            Window new_owner;
-            WWindow *owner;
-
-            if (!XGetTransientForHint(dpy, wwin->client_win, &new_owner)) {
-                new_owner = None;
-            } else {
-                if (new_owner==0 || new_owner == wwin->client_win) {
-                    new_owner = wwin->screen_ptr->root_win;
-                }
-            }
-            if (new_owner!=wwin->transient_for) {
-                owner = wWindowFor(wwin->transient_for);
-                if (owner) {
-                    if (owner->flags.semi_focused) {
-                        owner->flags.semi_focused = 0;
-                        if ((owner->flags.mapped || owner->flags.shaded)
-                            && owner->frame)
-                            wFrameWindowPaint(owner->frame);
-                    }
-                }
-                owner = wWindowFor(new_owner);
-                if (owner) {
-                    if (!owner->flags.semi_focused) {
-                        owner->flags.semi_focused = 1;
-                        if ((owner->flags.mapped || owner->flags.shaded)
-                            && owner->frame)
-                            wFrameWindowPaint(owner->frame);
-                    }
-                }
-                wwin->transient_for = new_owner;
-                if (new_owner==None) {
-                    if (WFLAGP(wwin, no_miniaturizable)) {
-                        WSETUFLAG(wwin, no_miniaturizable, 0);
-                        WSETUFLAG(wwin, no_miniaturize_button, 0);
-                        if (wwin->frame)
-                            wWindowConfigureBorders(wwin);
-                    }
-                } else if (!WFLAGP(wwin, no_miniaturizable)) {
-                    WSETUFLAG(wwin, no_miniaturizable, 1);
-                    WSETUFLAG(wwin, no_miniaturize_button, 1);
-                    if (wwin->frame)
-                        wWindowConfigureBorders(wwin);
-                }
-            }
-        }
-        break;
-
-    default:
-        if (event->atom==_XA_WM_PROTOCOLS) {
-
-            PropGetProtocols(wwin->client_win, &wwin->protocols);
-
-            WSETUFLAG(wwin, kill_close, !wwin->protocols.DELETE_WINDOW);
-
-            if (wwin->frame)
-                wWindowUpdateButtonImages(wwin);
-
-        } else if (event->atom==_XA_WM_COLORMAP_WINDOWS) {
-
-            GetColormapWindows(wwin);
-            wColormapInstallForWindow(wwin->screen_ptr, wwin);
-
-        } else if (event->atom==_XA_WINDOWMAKER_MENU) {
-            WApplication *wapp;
-
-            wapp = wApplicationOf(wwin->main_window);
-            if (wapp) {
-                if (wapp->menu) {
-                    /* update menu */
-                    /* TODO: remake appmenu update */
-                    wAppMenuDestroy(wapp->menu);
-                }
-                if (wwin->fake_group) {
-                    extern WPreferences wPreferences;
-                    WScreen *scr = wwin->screen_ptr;
-                    WWindow *foo = scr->focused_window;
-                    WFakeGroupLeader *fPtr = wwin->fake_group;
-
-                    wApplicationDestroy(wapp);
-                    while (foo) {
-                        if (foo->fake_group && foo->fake_group==fPtr) {
-                            WSETUFLAG(foo, shared_appicon, 0);
-                            foo->fake_group = NULL;
-                            if (foo->group_id!=None)
-                                foo->main_window = foo->group_id;
-                            else if (foo->client_leader!=None)
-                                foo->main_window = foo->client_leader;
-                            else if (WFLAGP(foo, emulate_appicon))
-                                foo->main_window = foo->client_win;
-                            else
-                                foo->main_window = None;
-                            if (foo->main_window) {
-                                wapp = wApplicationCreate(foo);
-                            }
-                        }
-                        foo = foo->prev;
-                    }
-
-                    if (fPtr->leader!=None)
-                        XDestroyWindow(dpy, fPtr->leader);
-                    fPtr->retainCount = 0;
-                    fPtr->leader = None;
-                    fPtr->origLeader = None;
-
-                    wapp = wApplicationOf(wwin->main_window);
-                    if (wapp) {
-                        wapp->menu = wAppMenuGet(scr, wwin->main_window);
-                    }
-                    if (wPreferences.auto_arrange_icons) {
-                        wArrangeIcons(wwin->screen_ptr, True);
-                    }
-                } else {
-                    wapp->menu = wAppMenuGet(wwin->screen_ptr, wwin->main_window);
-                }
-                /* make the appmenu be mapped */
-                wSetFocusTo(wwin->screen_ptr, NULL);
-                wSetFocusTo(wwin->screen_ptr, wwin->screen_ptr->focused_window);
-            }
-        } else if (event->atom==_XA_GNUSTEP_WM_ATTR) {
-            GNUstepWMAttributes *attr;
-
-            PropGetGNUstepWMAttr(wwin->client_win, &attr);
-
-            wWindowUpdateGNUstepAttr(wwin, attr);
-
-            XFree(attr);
-        } else {
-#ifdef NETWM_HINTS
-            wNETWMCheckClientHintChange(wwin, event);
-#endif
-        }
-    }
-}
-
-
-/*
- *----------------------------------------------------------------------
- * wClientGetNormalHints--
- *     Get size (normal) hints and a default geometry for the client
- * window. The hints are also checked for inconsistency. If geometry is
- * True, the returned data will account for client specified initial
- * geometry.
- *
- * Side effects:
- *     normal_hints is filled with valid data.
- *----------------------------------------------------------------------
- */
-void
-wClientGetNormalHints(WWindow *wwin, XWindowAttributes *wattribs, Bool geometry,
-                      int *x, int *y, unsigned *width, unsigned *height)
-{
-    int pre_icccm = 0;                /* not used */
-
-    /* find a position for the window */
-    if (!wwin->normal_hints)
-        wwin->normal_hints = XAllocSizeHints();
-
-    if (!PropGetNormalHints(wwin->client_win, wwin->normal_hints, &pre_icccm)) {
-        wwin->normal_hints->flags = 0;
-    }
-    *x = wattribs->x;
-    *y = wattribs->y;
-
-    *width = wattribs->width;
-    *height = wattribs->height;
-
-    if (!(wwin->normal_hints->flags & PWinGravity)) {
-        wwin->normal_hints->win_gravity = NorthWestGravity;
-    }
-    if (!(wwin->normal_hints->flags & PMinSize)) {
-        wwin->normal_hints->min_width = MIN_WINDOW_SIZE;
-        wwin->normal_hints->min_height = MIN_WINDOW_SIZE;
-    }
-    if (!(wwin->normal_hints->flags & PBaseSize)) {
-        wwin->normal_hints->base_width = 0;
-        wwin->normal_hints->base_height = 0;
-    }
-    if (!(wwin->normal_hints->flags & PMaxSize)) {
-        wwin->normal_hints->max_width = wwin->screen_ptr->scr_width*2;
-        wwin->normal_hints->max_height = wwin->screen_ptr->scr_height*2;
-    }
-
-    /* some buggy apps set weird hints.. */
-    if (wwin->normal_hints->min_width <= 0)
-        wwin->normal_hints->min_width = MIN_WINDOW_SIZE;
-
-    if (wwin->normal_hints->min_height <= 0)
-        wwin->normal_hints->min_height = MIN_WINDOW_SIZE;
-
-
-    if (wwin->normal_hints->max_width < wwin->normal_hints->min_width)
-        wwin->normal_hints->max_width = wwin->normal_hints->min_width;
-
-    if (wwin->normal_hints->max_height < wwin->normal_hints->min_height)
-        wwin->normal_hints->max_height = wwin->normal_hints->min_height;
-
-    if (!(wwin->normal_hints->flags & PResizeInc)) {
-        wwin->normal_hints->width_inc = 1;
-        wwin->normal_hints->height_inc = 1;
-    } else {
-        if (wwin->normal_hints->width_inc <= 0)
-            wwin->normal_hints->width_inc = 1;
-        if (wwin->normal_hints->height_inc <= 0)
-            wwin->normal_hints->height_inc = 1;
-    }
-
-    if (wwin->normal_hints->flags & PAspect) {
-        if (wwin->normal_hints->min_aspect.x < 1)
-            wwin->normal_hints->min_aspect.x = 1;
-        if (wwin->normal_hints->min_aspect.y < 1)
-            wwin->normal_hints->min_aspect.y = 1;
-
-        if (wwin->normal_hints->max_aspect.x < 1)
-            wwin->normal_hints->max_aspect.x = 1;
-        if (wwin->normal_hints->max_aspect.y < 1)
-            wwin->normal_hints->max_aspect.y = 1;
-    }
-
-    if (wwin->normal_hints->min_height > wwin->normal_hints->max_height) {
-        wwin->normal_hints->min_height = wwin->normal_hints->max_height;
-    }
-    if (wwin->normal_hints->min_width > wwin->normal_hints->max_width) {
-        wwin->normal_hints->min_width = wwin->normal_hints->max_width;
-    }
-
-#ifdef IGNORE_PPOSITION
-    wwin->normal_hints->flags &= ~PPosition;
-#endif
-
-    if (pre_icccm && !wwin->screen_ptr->flags.startup && geometry) {
-        if (wwin->normal_hints->flags & (USPosition|PPosition)) {
-            *x = wwin->normal_hints->x;
-            *y = wwin->normal_hints->y;
-        }
-        if (wwin->normal_hints->flags & (USSize|PSize)) {
-            *width = wwin->normal_hints->width;
-            *height = wwin->normal_hints->height;
-        }
-    }
-}
-
-
-void
-GetColormapWindows(WWindow *wwin)
-{
-#ifndef NO_CRASHES
-    if (wwin->cmap_windows) {
-        XFree(wwin->cmap_windows);
-    }
-
-    wwin->cmap_windows = NULL;
-    wwin->cmap_window_no = 0;
-
-    if (!XGetWMColormapWindows(dpy, wwin->client_win, &(wwin->cmap_windows),
-                               &(wwin->cmap_window_no))
-        || !wwin->cmap_windows) {
-        wwin->cmap_window_no = 0;
-        wwin->cmap_windows = NULL;
-    }
-
-#endif
-}
+/*
+ *  Window Maker window manager
+ *
+ *  Copyright (c) 1997-2003 Alfredo K. Kojima
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ *  USA.
+ */
+#include "wconfig.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#ifdef SHAPE
+#include <X11/extensions/shape.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "WindowMaker.h"
+#include "wcore.h"
+#include "framewin.h"
+#include "window.h"
+#include "properties.h"
+#include "actions.h"
+#include "icon.h"
+#include "client.h"
+#include "funcs.h"
+#include "stacking.h"
+#include "appicon.h"
+#include "appmenu.h"
+#ifdef NETWM_HINTS
+# include "wmspec.h"
+#endif
+
+/****** Global Variables ******/
+
+/* contexts */
+extern XContext wWinContext;
+
+extern Atom _XA_WM_STATE;
+extern Atom _XA_WM_PROTOCOLS;
+extern Atom _XA_WM_COLORMAP_WINDOWS;
+
+extern Atom _XA_WINDOWMAKER_MENU;
+
+extern Atom _XA_GNUSTEP_WM_ATTR;
+extern Atom _XA_GNUSTEP_WM_RESIZEBAR;
+
+#ifdef SHAPE
+extern Bool wShapeSupported;
+#endif
+
+/*
+ *--------------------------------------------------------------------
+ * wClientRestore--
+ *     Reparent the window back to the root window.
+ *
+ *--------------------------------------------------------------------
+ */
+void wClientRestore(WWindow * wwin)
+{
+#if 0
+       int gx, gy;
+
+       wClientGetGravityOffsets(wwin, &gx, &gy);
+       /* set the positio of the frame on screen */
+       wwin->frame_x -= gx * FRAME_BORDER_WIDTH;
+       wwin->frame_y -= gy * FRAME_BORDER_WIDTH;
+       /* if gravity is to the south, account for the border sizes */
+       if (gy > 0)
+               wwin->frame_y += (wwin->frame->top_width + wwin->frame->bottom_width);
+#endif
+       XSetWindowBorderWidth(dpy, wwin->client_win, wwin->old_border_width);
+       XReparentWindow(dpy, wwin->client_win, wwin->screen_ptr->root_win, wwin->frame_x, wwin->frame_y);
+
+       /* don't let the window get iconified after restart */
+       /*
+          if (wwin->flags.shaded)
+          wClientSetState(wwin, NormalState, None);
+        */
+}
+
+/*
+ *----------------------------------------------------------------------
+ * wClientSetState--
+ *     Set the state of the client window to one of the window
+ * states defined in ICCCM (Iconic, Withdrawn, Normal)
+ *
+ * Side effects:
+ *     The WM_STATE property of the window is updated as well as the
+ * WWindow.state variable.
+ *----------------------------------------------------------------------
+ */
+void wClientSetState(WWindow * wwin, int state, Window icon_win)
+{
+       CARD32 data[2];
+
+       wwin->state = state;
+
+       data[0] = (unsigned long)state;
+       data[1] = (unsigned long)icon_win;
+
+       XChangeProperty(dpy, wwin->client_win, _XA_WM_STATE, _XA_WM_STATE, 32,
+                       PropModeReplace, (unsigned char *)data, 2);
+}
+
+void wClientGetGravityOffsets(WWindow * wwin, int *ofs_x, int *ofs_y)
+{
+       switch (wwin->normal_hints->win_gravity) {
+       case ForgetGravity:
+       case CenterGravity:
+       case StaticGravity:
+               *ofs_x = 0;
+               *ofs_y = 0;
+               break;
+       case NorthWestGravity:
+               *ofs_x = -1;
+               *ofs_y = -1;
+               break;
+       case NorthGravity:
+               *ofs_x = 0;
+               *ofs_y = -1;
+               break;
+       case NorthEastGravity:
+               *ofs_x = 1;
+               *ofs_y = -1;
+               break;
+       case WestGravity:
+               *ofs_x = -1;
+               *ofs_y = 0;
+               break;
+       case EastGravity:
+               *ofs_x = 1;
+               *ofs_y = 0;
+               break;
+       case SouthWestGravity:
+               *ofs_x = -1;
+               *ofs_y = 1;
+               break;
+       case SouthGravity:
+               *ofs_x = 0;
+               *ofs_y = 1;
+               break;
+       case SouthEastGravity:
+               *ofs_x = 1;
+               *ofs_y = 1;
+               break;
+       }
+}
+
+void wClientConfigure(WWindow * wwin, XConfigureRequestEvent * xcre)
+{
+       XWindowChanges xwc;
+       int nx, ny, nwidth, nheight;
+       int ofs_x, ofs_y;
+
+       /*  printf("configure event: %d %d %d %d\n", xcre->x, xcre->y, xcre->width, xcre->height); */
+
+       if (wwin == NULL) {
+               /*
+                * configure a window that was not mapped by us
+                */
+               xwc.x = xcre->x;
+               xwc.y = xcre->y;
+               xwc.width = xcre->width;
+               xwc.height = xcre->height;
+               xwc.border_width = xcre->border_width;
+               xwc.stack_mode = xcre->detail;
+               xwc.sibling = xcre->above;
+               XConfigureWindow(dpy, xcre->window, xcre->value_mask, &xwc);
+               return;
+       }
+#ifdef SHAPE
+       if (wShapeSupported) {
+               int junk;
+               unsigned int ujunk;
+               int b_shaped;
+
+               XShapeSelectInput(dpy, wwin->client_win, ShapeNotifyMask);
+               XShapeQueryExtents(dpy, wwin->client_win, &b_shaped, &junk, &junk,
+                                  &ujunk, &ujunk, &junk, &junk, &junk, &ujunk, &ujunk);
+               wwin->flags.shaped = b_shaped;
+       }
+#endif
+       if (xcre->value_mask & CWStackMode) {
+               WObjDescriptor *desc;
+               WWindow *sibling;
+
+               if ((xcre->value_mask & CWSibling) &&
+                   (XFindContext(dpy, xcre->above, wWinContext, (XPointer *) & desc) == XCSUCCESS)
+                   && (desc->parent_type == WCLASS_WINDOW)) {
+                       sibling = desc->parent;
+                       xwc.sibling = sibling->frame->core->window;
+               } else {
+                       xwc.sibling = xcre->above;
+               }
+               xwc.stack_mode = xcre->detail;
+               XConfigureWindow(dpy, wwin->frame->core->window,
+                                xcre->value_mask & (CWSibling | CWStackMode), &xwc);
+               /* fix stacking order */
+               RemakeStackList(wwin->screen_ptr);
+       }
+
+       wClientGetGravityOffsets(wwin, &ofs_x, &ofs_y);
+
+       if (xcre->value_mask & CWBorderWidth) {
+               wwin->old_border_width = xcre->border_width;
+       }
+
+       if (!wwin->flags.shaded) {
+               /* If the window is shaded, wrong height will be set for the window */
+               if (xcre->value_mask & CWX) {
+                       nx = xcre->x;
+                       /* Subtracting the border makes the window shift by 1 pixel -Dan */
+                       /*if (HAS_BORDER(wwin)) {
+                          nx -= FRAME_BORDER_WIDTH;
+                          } */
+               } else {
+                       nx = wwin->frame_x;
+               }
+
+               if (xcre->value_mask & CWY) {
+                       ny = xcre->y - ((ofs_y < 0) ? 0 : wwin->frame->top_width);
+                       /* Subtracting the border makes the window shift by 1 pixel -Dan */
+                       /*if (HAS_BORDER(wwin)) {
+                          ny -= FRAME_BORDER_WIDTH;
+                          } */
+               } else {
+                       ny = wwin->frame_y;
+               }
+
+               if (xcre->value_mask & CWWidth)
+                       nwidth = xcre->width;
+               else
+                       nwidth = wwin->frame->core->width;
+
+               if (xcre->value_mask & CWHeight)
+                       nheight = xcre->height;
+               else
+                       nheight = wwin->frame->core->height - wwin->frame->top_width - wwin->frame->bottom_width;
+
+               wWindowConfigure(wwin, nx, ny, nwidth, nheight);
+               wwin->old_geometry.x = nx;
+               wwin->old_geometry.y = ny;
+               wwin->old_geometry.width = nwidth;
+               wwin->old_geometry.height = nheight;
+       }
+}
+
+void wClientSendProtocol(WWindow * wwin, Atom protocol, Time time)
+{
+       XEvent event;
+
+       event.xclient.type = ClientMessage;
+       event.xclient.message_type = _XA_WM_PROTOCOLS;
+       event.xclient.format = 32;
+       event.xclient.display = dpy;
+       event.xclient.window = wwin->client_win;
+       event.xclient.data.l[0] = protocol;
+       event.xclient.data.l[1] = time;
+       event.xclient.data.l[2] = 0;
+       event.xclient.data.l[3] = 0;
+       XSendEvent(dpy, wwin->client_win, False, NoEventMask, &event);
+       XSync(dpy, False);
+}
+
+void wClientKill(WWindow * wwin)
+{
+       XKillClient(dpy, wwin->client_win);
+
+       XFlush(dpy);
+}
+
+/*
+ *----------------------------------------------------------------------
+ * wClientCheckProperty--
+ *     Handles PropertyNotify'es, verifying which property was
+ * changed and updating internal state according to that, like redrawing
+ * the icon title when it is changed.
+ *
+ * Side effects:
+ *     Depends on the changed property.
+ *
+ * TODO: _GNUSTEP_WM_ATTR
+ *----------------------------------------------------------------------
+ */
+void wClientCheckProperty(WWindow * wwin, XPropertyEvent * event)
+{
+       XWindowAttributes attribs;
+       XWMHints *new_hints;
+       int i, g1, g2;
+       char *tmp = NULL;
+
+       switch (event->atom) {
+       case XA_WM_NAME:
+               if (!wwin->flags.net_has_title) {
+                       /* window title was changed */
+                       if (!wFetchName(dpy, wwin->client_win, &tmp)) {
+                               wWindowUpdateName(wwin, NULL);
+                       } else {
+                               wWindowUpdateName(wwin, tmp);
+                       }
+                       if (tmp)
+                               XFree(tmp);
+               }
+               break;
+
+       case XA_WM_ICON_NAME:
+               if (!wwin->flags.net_has_icon_title) {
+                       if (!wwin->icon)
+                               break;
+                       else {
+                               char *new_title;
+
+                               /* icon title was changed */
+                               wGetIconName(dpy, wwin->client_win, &new_title);
+                               wIconChangeTitle(wwin->icon, new_title);
+                       }
+               }
+               break;
+
+       case XA_WM_COMMAND:
+               if (wwin->main_window != None) {
+                       WApplication *wapp = wApplicationOf(wwin->main_window);
+                       char *command;
+
+                       if (!wapp || !wapp->app_icon || wapp->app_icon->docked)
+                               break;
+
+                       command = GetCommandForWindow(wwin->main_window);
+                       if (command) {
+                               if (wapp->app_icon->command)
+                                       wfree(wapp->app_icon->command);
+                               wapp->app_icon->command = command;
+                       }
+               }
+               break;
+
+       case XA_WM_HINTS:
+               /* WM_HINTS */
+
+               new_hints = XGetWMHints(dpy, wwin->client_win);
+
+               /* group leader update
+                *
+                * This means that the window is setting the leader after
+                * it was mapped, changing leaders or removing the leader.
+                *
+                * Valid state transitions are:
+                *
+                *          _1            __2
+                *         / \           /  \
+                *         v |           v  |
+                *         (GC)         (GC')
+                *        /  ^          /   ^
+                *       3|  |4        5|   |6
+                *        |  |          |   |
+                *        v  /          v   /
+                *        (G'C)        (G'C')
+                *
+                * Where G is the window_group hint, C is CLIENT_LEADER property
+                * and ' indicates the hint is unset.
+                *
+                * 1,2 - change group leader to new value of window_group
+                * 3 - change leader to value of CLIENT_LEADER
+                * 4 - change leader to value of window_group
+                * 5 - destroy application
+                * 6 - create application
+                */
+               if (new_hints && (new_hints->flags & WindowGroupHint)
+                   && new_hints->window_group != None) {
+                       g2 = 1;
+               } else {
+                       g2 = 0;
+               }
+               if (wwin->wm_hints && (wwin->wm_hints->flags & WindowGroupHint)
+                   && wwin->wm_hints->window_group != None) {
+                       g1 = 1;
+               } else {
+                       g1 = 0;
+               }
+
+               if (wwin->client_leader) {
+                       if (g1 && g2 && wwin->wm_hints->window_group != new_hints->window_group) {
+                               i = 1;
+                       } else if (g1 && !g2) {
+                               i = 3;
+                       } else if (!g1 && g2) {
+                               i = 4;
+                       } else {
+                               i = 0;
+                       }
+               } else {
+                       if (g1 && g2 && wwin->wm_hints->window_group != new_hints->window_group) {
+                               i = 2;
+                       } else if (g1 && !g2) {
+                               i = 5;
+                       } else if (!g1 && g2) {
+                               i = 6;
+                       } else {
+                               i = 0;
+                       }
+               }
+
+               /* Handling this may require more work. -Dan */
+               if (wwin->fake_group != NULL) {
+                       i = 7;
+               }
+
+               if (wwin->wm_hints)
+                       XFree(wwin->wm_hints);
+
+               wwin->wm_hints = new_hints;
+
+               /* do action according to state transition */
+               switch (i) {
+                       /* 3 - change leader to value of CLIENT_LEADER */
+               case 3:
+                       wApplicationDestroy(wApplicationOf(wwin->main_window));
+                       wwin->main_window = wwin->client_leader;
+                       wwin->group_id = None;
+                       wApplicationCreate(wwin);
+                       break;
+
+                       /* 1,2,4 - change leader to new value of window_group */
+               case 1:
+               case 2:
+               case 4:
+                       wApplicationDestroy(wApplicationOf(wwin->main_window));
+                       wwin->main_window = new_hints->window_group;
+                       wwin->group_id = wwin->main_window;
+                       wApplicationCreate(wwin);
+                       break;
+
+                       /* 5 - destroy application */
+               case 5:
+                       wApplicationDestroy(wApplicationOf(wwin->main_window));
+                       wwin->main_window = None;
+                       wwin->group_id = None;
+                       break;
+
+                       /* 6 - create application */
+               case 6:
+                       wwin->main_window = new_hints->window_group;
+                       wwin->group_id = wwin->main_window;
+                       wApplicationCreate(wwin);
+                       break;
+                       /* 7 - we have a fake window group id, so just ignore anything else */
+               case 7:
+                       break;
+               }
+#ifdef DEBUG
+               if (i) {
+                       printf("window leader update caused state transition %i\n", i);
+               }
+#endif
+
+               if (wwin->wm_hints) {
+                       /* update icon */
+                       if ((wwin->wm_hints->flags & IconPixmapHint)
+                           || (wwin->wm_hints->flags & IconWindowHint)) {
+                               WApplication *wapp;
+
+                               if (wwin->flags.miniaturized && wwin->icon) {
+                                       wIconUpdate(wwin->icon);
+                               }
+                               wapp = wApplicationOf(wwin->main_window);
+                               if (wapp && wapp->app_icon) {
+                                       wIconUpdate(wapp->app_icon->icon);
+                               }
+                       }
+
+                       if (wwin->wm_hints->flags & UrgencyHint)
+                               wwin->flags.urgent = 1;
+                       else
+                               wwin->flags.urgent = 0;
+                       /*} else if (wwin->fake_group!=NULL) {
+                          wwin->group_id = wwin->fake_group->leader; */
+               } else {
+                       wwin->group_id = None;
+               }
+               break;
+
+       case XA_WM_NORMAL_HINTS:
+               /* normal (geometry) hints */
+               {
+                       int foo;
+                       unsigned bar;
+
+                       XGetWindowAttributes(dpy, wwin->client_win, &attribs);
+                       wClientGetNormalHints(wwin, &attribs, False, &foo, &foo, &bar, &bar);
+                       /* TODO: should we check for consistency of the current
+                        * size against the new geometry hints? */
+               }
+               break;
+
+       case XA_WM_TRANSIENT_FOR:
+               {
+                       Window new_owner;
+                       WWindow *owner;
+
+                       if (!XGetTransientForHint(dpy, wwin->client_win, &new_owner)) {
+                               new_owner = None;
+                       } else {
+                               if (new_owner == 0 || new_owner == wwin->client_win) {
+                                       new_owner = wwin->screen_ptr->root_win;
+                               }
+                       }
+                       if (new_owner != wwin->transient_for) {
+                               owner = wWindowFor(wwin->transient_for);
+                               if (owner) {
+                                       if (owner->flags.semi_focused) {
+                                               owner->flags.semi_focused = 0;
+                                               if ((owner->flags.mapped || owner->flags.shaded)
+                                                   && owner->frame)
+                                                       wFrameWindowPaint(owner->frame);
+                                       }
+                               }
+                               owner = wWindowFor(new_owner);
+                               if (owner) {
+                                       if (!owner->flags.semi_focused) {
+                                               owner->flags.semi_focused = 1;
+                                               if ((owner->flags.mapped || owner->flags.shaded)
+                                                   && owner->frame)
+                                                       wFrameWindowPaint(owner->frame);
+                                       }
+                               }
+                               wwin->transient_for = new_owner;
+                               if (new_owner == None) {
+                                       if (WFLAGP(wwin, no_miniaturizable)) {
+                                               WSETUFLAG(wwin, no_miniaturizable, 0);
+                                               WSETUFLAG(wwin, no_miniaturize_button, 0);
+                                               if (wwin->frame)
+                                                       wWindowConfigureBorders(wwin);
+                                       }
+                               } else if (!WFLAGP(wwin, no_miniaturizable)) {
+                                       WSETUFLAG(wwin, no_miniaturizable, 1);
+                                       WSETUFLAG(wwin, no_miniaturize_button, 1);
+                                       if (wwin->frame)
+                                               wWindowConfigureBorders(wwin);
+                               }
+                       }
+               }
+               break;
+
+       default:
+               if (event->atom == _XA_WM_PROTOCOLS) {
+
+                       PropGetProtocols(wwin->client_win, &wwin->protocols);
+
+                       WSETUFLAG(wwin, kill_close, !wwin->protocols.DELETE_WINDOW);
+
+                       if (wwin->frame)
+                               wWindowUpdateButtonImages(wwin);
+
+               } else if (event->atom == _XA_WM_COLORMAP_WINDOWS) {
+
+                       GetColormapWindows(wwin);
+                       wColormapInstallForWindow(wwin->screen_ptr, wwin);
+
+               } else if (event->atom == _XA_WINDOWMAKER_MENU) {
+                       WApplication *wapp;
+
+                       wapp = wApplicationOf(wwin->main_window);
+                       if (wapp) {
+                               if (wapp->menu) {
+                                       /* update menu */
+                                       /* TODO: remake appmenu update */
+                                       wAppMenuDestroy(wapp->menu);
+                               }
+                               if (wwin->fake_group) {
+                                       extern WPreferences wPreferences;
+                                       WScreen *scr = wwin->screen_ptr;
+                                       WWindow *foo = scr->focused_window;
+                                       WFakeGroupLeader *fPtr = wwin->fake_group;
+
+                                       wApplicationDestroy(wapp);
+                                       while (foo) {
+                                               if (foo->fake_group && foo->fake_group == fPtr) {
+                                                       WSETUFLAG(foo, shared_appicon, 0);
+                                                       foo->fake_group = NULL;
+                                                       if (foo->group_id != None)
+                                                               foo->main_window = foo->group_id;
+                                                       else if (foo->client_leader != None)
+                                                               foo->main_window = foo->client_leader;
+                                                       else if (WFLAGP(foo, emulate_appicon))
+                                                               foo->main_window = foo->client_win;
+                                                       else
+                                                               foo->main_window = None;
+                                                       if (foo->main_window) {
+                                                               wapp = wApplicationCreate(foo);
+                                                       }
+                                               }
+                                               foo = foo->prev;
+                                       }
+
+                                       if (fPtr->leader != None)
+                                               XDestroyWindow(dpy, fPtr->leader);
+                                       fPtr->retainCount = 0;
+                                       fPtr->leader = None;
+                                       fPtr->origLeader = None;
+
+                                       wapp = wApplicationOf(wwin->main_window);
+                                       if (wapp) {
+                                               wapp->menu = wAppMenuGet(scr, wwin->main_window);
+                                       }
+                                       if (wPreferences.auto_arrange_icons) {
+                                               wArrangeIcons(wwin->screen_ptr, True);
+                                       }
+                               } else {
+                                       wapp->menu = wAppMenuGet(wwin->screen_ptr, wwin->main_window);
+                               }
+                               /* make the appmenu be mapped */
+                               wSetFocusTo(wwin->screen_ptr, NULL);
+                               wSetFocusTo(wwin->screen_ptr, wwin->screen_ptr->focused_window);
+                       }
+               } else if (event->atom == _XA_GNUSTEP_WM_ATTR) {
+                       GNUstepWMAttributes *attr;
+
+                       PropGetGNUstepWMAttr(wwin->client_win, &attr);
+
+                       wWindowUpdateGNUstepAttr(wwin, attr);
+
+                       XFree(attr);
+               } else {
+#ifdef NETWM_HINTS
+                       wNETWMCheckClientHintChange(wwin, event);
+#endif
+               }
+       }
+}
+
+/*
+ *----------------------------------------------------------------------
+ * wClientGetNormalHints--
+ *     Get size (normal) hints and a default geometry for the client
+ * window. The hints are also checked for inconsistency. If geometry is
+ * True, the returned data will account for client specified initial
+ * geometry.
+ *
+ * Side effects:
+ *     normal_hints is filled with valid data.
+ *----------------------------------------------------------------------
+ */
+void
+wClientGetNormalHints(WWindow * wwin, XWindowAttributes * wattribs, Bool geometry,
+                     int *x, int *y, unsigned *width, unsigned *height)
+{
+       int pre_icccm = 0;      /* not used */
+
+       /* find a position for the window */
+       if (!wwin->normal_hints)
+               wwin->normal_hints = XAllocSizeHints();
+
+       if (!PropGetNormalHints(wwin->client_win, wwin->normal_hints, &pre_icccm)) {
+               wwin->normal_hints->flags = 0;
+       }
+       *x = wattribs->x;
+       *y = wattribs->y;
+
+       *width = wattribs->width;
+       *height = wattribs->height;
+
+       if (!(wwin->normal_hints->flags & PWinGravity)) {
+               wwin->normal_hints->win_gravity = NorthWestGravity;
+       }
+       if (!(wwin->normal_hints->flags & PMinSize)) {
+               wwin->normal_hints->min_width = MIN_WINDOW_SIZE;
+               wwin->normal_hints->min_height = MIN_WINDOW_SIZE;
+       }
+       if (!(wwin->normal_hints->flags & PBaseSize)) {
+               wwin->normal_hints->base_width = 0;
+               wwin->normal_hints->base_height = 0;
+       }
+       if (!(wwin->normal_hints->flags & PMaxSize)) {
+               wwin->normal_hints->max_width = wwin->screen_ptr->scr_width * 2;
+               wwin->normal_hints->max_height = wwin->screen_ptr->scr_height * 2;
+       }
+
+       /* some buggy apps set weird hints.. */
+       if (wwin->normal_hints->min_width <= 0)
+               wwin->normal_hints->min_width = MIN_WINDOW_SIZE;
+
+       if (wwin->normal_hints->min_height <= 0)
+               wwin->normal_hints->min_height = MIN_WINDOW_SIZE;
+
+       if (wwin->normal_hints->max_width < wwin->normal_hints->min_width)
+               wwin->normal_hints->max_width = wwin->normal_hints->min_width;
+
+       if (wwin->normal_hints->max_height < wwin->normal_hints->min_height)
+               wwin->normal_hints->max_height = wwin->normal_hints->min_height;
+
+       if (!(wwin->normal_hints->flags & PResizeInc)) {
+               wwin->normal_hints->width_inc = 1;
+               wwin->normal_hints->height_inc = 1;
+       } else {
+               if (wwin->normal_hints->width_inc <= 0)
+                       wwin->normal_hints->width_inc = 1;
+               if (wwin->normal_hints->height_inc <= 0)
+                       wwin->normal_hints->height_inc = 1;
+       }
+
+       if (wwin->normal_hints->flags & PAspect) {
+               if (wwin->normal_hints->min_aspect.x < 1)
+                       wwin->normal_hints->min_aspect.x = 1;
+               if (wwin->normal_hints->min_aspect.y < 1)
+                       wwin->normal_hints->min_aspect.y = 1;
+
+               if (wwin->normal_hints->max_aspect.x < 1)
+                       wwin->normal_hints->max_aspect.x = 1;
+               if (wwin->normal_hints->max_aspect.y < 1)
+                       wwin->normal_hints->max_aspect.y = 1;
+       }
+
+       if (wwin->normal_hints->min_height > wwin->normal_hints->max_height) {
+               wwin->normal_hints->min_height = wwin->normal_hints->max_height;
+       }
+       if (wwin->normal_hints->min_width > wwin->normal_hints->max_width) {
+               wwin->normal_hints->min_width = wwin->normal_hints->max_width;
+       }
+#ifdef IGNORE_PPOSITION
+       wwin->normal_hints->flags &= ~PPosition;
+#endif
+
+       if (pre_icccm && !wwin->screen_ptr->flags.startup && geometry) {
+               if (wwin->normal_hints->flags & (USPosition | PPosition)) {
+                       *x = wwin->normal_hints->x;
+                       *y = wwin->normal_hints->y;
+               }
+               if (wwin->normal_hints->flags & (USSize | PSize)) {
+                       *width = wwin->normal_hints->width;
+                       *height = wwin->normal_hints->height;
+               }
+       }
+}
+
+void GetColormapWindows(WWindow * wwin)
+{
+#ifndef NO_CRASHES
+       if (wwin->cmap_windows) {
+               XFree(wwin->cmap_windows);
+       }
+
+       wwin->cmap_windows = NULL;
+       wwin->cmap_window_no = 0;
+
+       if (!XGetWMColormapWindows(dpy, wwin->client_win, &(wwin->cmap_windows), &(wwin->cmap_window_no))
+           || !wwin->cmap_windows) {
+               wwin->cmap_window_no = 0;
+               wwin->cmap_windows = NULL;
+       }
+#endif
+}