/**************************************************************************** * This module is all original code * by Rob Nation * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation ****************************************************************************/ /*********************************************************************** * * fvwm window border drawing code * ***********************************************************************/ #include #include #include #include #include "fvwm.h" #include "menus.h" #include "misc.h" #include "parse.h" #include "screen.h" #include "module.h" #ifdef SHAPE #include #endif void DrawLinePattern(Window win, GC ReliefGC, GC ShadowGC, int num_coords, int *x_coord, int *y_coord, int *line_style, int th); /* macro to change window background color/pixmap */ #define ChangeWindowColor(window,color) {\ if (NewColor)\ {\ if (Scr.d_depth >= 2) attributes.background_pixel = color;\ XChangeWindowAttributes(dpy, window, valuemask, &attributes);\ XClearWindow(dpy,window);\ }\ } extern Window PressedW; XGCValues Globalgcv; unsigned long Globalgcm; /**************************************************************************** * * Redraws the windows borders * ****************************************************************************/ void SetBorder (FvwmWindow *t, Bool onoroff,Bool force,Bool Mapped, Window expose_win) { int i, x, y; Pixel BackColor, ForeColor, TitleBackColor, TitleTextColor; Pixmap BackPixmap, TextColor; GC ReliefGC, ShadowGC; Bool NewColor = False; XSetWindowAttributes attributes; unsigned long valuemask; static unsigned int corners[4]; Window w; corners[0] = TOP_HILITE | LEFT_HILITE; corners[1] = TOP_HILITE | RIGHT_HILITE; corners[2] = BOTTOM_HILITE | LEFT_HILITE; corners[3] = BOTTOM_HILITE | RIGHT_HILITE; if (!t) return; if (onoroff) { /* on */ /* don't re-draw just for kicks */ if ((!force) && (Scr.Hilite == t)) return; if (Scr.Hilite != t) NewColor = True; /* make sure that the previously highlighted window got unhighlighted */ if ((Scr.Hilite != t) && (Scr.Hilite != NULL)) SetBorder(Scr.Hilite, False, False, True, None); /* set the keyboard focus */ if ((Mapped) && (t->flags&MAPPED) && (Scr.Hilite != t)) w = t->w; else if ((t->flags & ICONIFIED) && (Scr.Hilite != t) && (!(t->flags & SUPPRESSICON))) w = t->icon_w; Scr.Hilite = t; BackPixmap = Scr.gray_pixmap; TitleBackColor = Scr.ActiveTitleColors.back; TitleTextColor = Scr.ActiveTitleColors.fore; } else { /* off */ /* don't re-draw just for kicks */ if ((!force) && (Scr.Hilite != t)) return; if(Scr.Hilite == t) { Scr.Hilite = NULL; NewColor = True; } if (t->flags & STICKY) { BackPixmap = Scr.sticky_gray_pixmap; TitleBackColor = Scr.StickyColors.back; TitleTextColor = Scr.StickyColors.fore; } else { BackPixmap = Scr.light_gray_pixmap; TitleBackColor = t->BackPixel; TitleTextColor = t->TextPixel; } } ReliefGC = Scr.WinReliefGC; ShadowGC = Scr.WinShadowGC; BackColor = Scr.WinColors.back; ForeColor = Scr.WinColors.fore; if (t->flags & ICONIFIED) { DrawIconWindow(t); return; } valuemask = CWBorderPixel; attributes.border_pixel = Scr.WinColors.shadow; if (Scr.d_depth < 2) { attributes.background_pixmap = BackPixmap; valuemask |= CWBackPixmap; } else { attributes.background_pixel = BackColor; valuemask |= CWBackPixel; } if(t->flags & (TITLE | BORDER)) { XSetWindowBorder(dpy, t->Parent, BackColor); XSetWindowBorder(dpy, t->frame, BackColor); } /* Area for optimization? */ if(t->flags & TITLE) { Window *win; /* fore color for selected window title bar */ ChangeWindowColor (t->title_w, TitleBackColor); for (i=0, win=t->left_w; ititle_icon)) /* title icon present? */ { XGCValues gcv; unsigned long gcm; gcm = GCClipMask|GCClipXOrigin|GCClipYOrigin; gcv.clip_mask = t->title_icon->mask; gcv.clip_x_origin = 0; gcv.clip_y_origin = 0; XChangeGC(dpy, Scr.ScratchGC3, gcm, &gcv); XCopyArea (dpy, t->title_icon->picture, *win, Scr.ScratchGC3, 0, 0, t->title_icon->width, t->title_icon->height, gcv.clip_x_origin, gcv.clip_y_origin); gcm = GCClipMask; gcv.clip_mask = None; XChangeGC(dpy, Scr.ScratchGC3, gcm, &gcv); } else { RelieveButton (t, *win, 0, 0, Scr.button_width, Scr.button_height, ReliefGC, ShadowGC, (PressedW == *win)); XCopyArea (dpy, Scr.button_pixmap[i<<1], *win, Scr.WinGC, 0, 0, Scr.button_width-3, Scr.button_height-3, (PressedW == *win) ? 2 : 1, (PressedW == *win) ? 2 : 1); } } } } for (i=0, win=t->right_w; iflags & MAXIMIZED)) { XCopyArea (dpy, Scr.button_pixmap[(i<<1)], *win, Scr.WinGC, 0, 0, Scr.button_width-3, Scr.button_height-3, (PressedW == *win) ? 2 : 1, (PressedW == *win) ? 2 : 1); } else { XCopyArea (dpy, Scr.button_pixmap[(i<<1)+1], *win, Scr.WinGC, 0, 0, Scr.button_width-3, Scr.button_height-3, (PressedW == *win) ? 2 : 1, (PressedW == *win) ? 2 : 1); } } } } SetTitleBar (t, onoroff, False); } if(t->flags & BORDER) { Window *side, *corner; /* draw relief lines */ y = t->frame_height - (t->corner_width << 1); x = t->frame_width - (t->corner_width << 1) + t->bw; for (i=0, side=t->sides, corner=t->corners; i<4; i++, side++, corner++) { ChangeWindowColor(*side, BackColor); if((flush_expose(*side)) || (expose_win == *side)|| (expose_win == None)) { /* index side * 0 TOP * 1 RIGHT * 2 BOTTOM * 3 LEFT */ RelieveWindow(t, *side, 0, 0, ((i & 1) ? t->boundary_width : x), ((i & 1) ? y : t->boundary_width), ReliefGC, ShadowGC, (0x0001 << i)); } ChangeWindowColor(*corner, BackColor); if((flush_expose(*corner)) || (expose_win == *corner)|| (expose_win == None)) { RelieveWindow(t, *corner, 0, 0, t->corner_width, ((i>>1) ? t->corner_width+t->bw : t->corner_width), ReliefGC, ShadowGC, corners[i]); } } } else /* no decorative border */ { /* for mono - put a black border on * for color, make it the color of the decoration background */ if(t->boundary_width < 2) { flush_expose (t->frame); if(Scr.d_depth < 2) { XSetWindowBorder (dpy, t->frame, ForeColor); XSetWindowBorder (dpy, t->Parent, ForeColor); XSetWindowBackgroundPixmap (dpy, t->frame, BackPixmap); XClearWindow (dpy, t->frame); XSetWindowBackgroundPixmap (dpy, t->Parent, BackPixmap); XClearWindow (dpy, t->Parent); } else { XSetWindowBackground (dpy, t->frame, BackColor); XSetWindowBorder (dpy, t->frame, Scr.WinColors.shadow); XClearWindow (dpy, t->frame); XSetWindowBackground (dpy, t->Parent, Scr.WinColors.shadow); XSetWindowBorder (dpy, t->Parent, Scr.WinColors.shadow); XClearWindow (dpy, t->Parent); XSetWindowBorder (dpy, t->w, Scr.WinColors.shadow); } } else { XSetWindowBorder (dpy, t->Parent, Scr.WinColors.shadow); XSetWindowBorder (dpy, t->frame, Scr.WinColors.shadow); ChangeWindowColor (t->frame, BackColor); if((flush_expose(t->frame)) || (expose_win == t->frame)|| (expose_win == None)) { if(t->boundary_width > 2) { RelieveWindow(t, t->frame, 0, 0, t->frame_width + t->bw, t->frame_height + t->bw, ReliefGC, ShadowGC, TOP_HILITE | LEFT_HILITE | RIGHT_HILITE | BOTTOM_HILITE); } else { RelieveWindow(t, t->frame, 0, 0, t->frame_width + t->bw, t->frame_height + t->bw, ReliefGC, ShadowGC, TOP_HILITE | LEFT_HILITE | RIGHT_HILITE | BOTTOM_HILITE); } } else { XSetWindowBackground(dpy, t->Parent, Scr.WinColors.shadow); } } } /* Sync to make the border-color change look fast! */ XSync(dpy, 0); } /**************************************************************************** * * Redraws just the title bar * ****************************************************************************/ void SetTitleBar (FvwmWindow *t, Bool onoroff, Bool NewTitle) { int x, y, w, i; Pixel Forecolor, BackColor; if (!t) return; if (!(t->flags & TITLE)) return; if (onoroff) { Forecolor = Scr.ActiveTitleColors.fore; BackColor = Scr.ActiveTitleColors.back; } else { Forecolor = t->TextPixel; BackColor = t->BackPixel; } flush_expose(t->title_w); if(t->name != (char *)NULL) { w = XTextWidth(Scr.WindowFont.font,t->name,strlen(t->name)); if (w > t->title_width-12) w = t->title_width-4; if (w < 0) w = 0; } else { w = 0; } x = Scr.button_width*t->nr_left_buttons + 6; y = ((Scr.WindowFont.y + t->title_height) >> 1) - 1; NewFontAndColor(Scr.WindowFont.font->fid, Forecolor, BackColor); if (NewTitle) XClearWindow (dpy, t->title_w); #ifdef I18N #undef FONTSET #define FONTSET Scr.WindowFont.fontset #endif /* I18N */ /* for mono, we clear an area in the title bar where the window * title goes, so that its more legible. For color, no need */ if(Scr.d_depth<2) { XFillRectangle(dpy,t->title_w, Scr.BlackGC, x - 2, 0, w+4, t->title_height); if(t->name != (char *)NULL) XDrawString (dpy, t->title_w,Scr.ScratchGC3, x, y, t->name, strlen(t->name)); } else { if(t->name != (char *)NULL) XDrawString (dpy, t->title_w, Scr.ScratchGC3, x, y, t->name, strlen(t->name)); } XFlush(dpy); } /**************************************************************************** * * Draws the relief pattern around a window (win95) * ****************************************************************************/ inline void RelieveWindow(FvwmWindow *t, Window win, int x, int y, int w, int h, GC ReliefGC, GC ShadowGC, int hilite) { XSegment seg[4]; int i; int edge; edge = 0; if ((win == t->sides[0]) || (win == t->sides[1])|| (win == t->sides[2]) || (win == t->sides[3])) edge = -1; else if (win == t->corners[0]) edge = 1; else if (win == t->corners[1]) edge = 2; else if (win == t->corners[2]) edge = 3; else if (win == t->corners[3]) edge = 4; /* window sides */ if (edge == -1) { switch (hilite) { case LEFT_HILITE: i = 0; seg[i].x1 = x+1; seg[i].y1 = y; seg[i].x2 = x+1; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, ReliefGC, seg, i); break; case TOP_HILITE: i = 0; seg[i].x1 = x; seg[i].y1 = y+1; seg[i].x2 = w+x-1; seg[i++].y2 = y+1; XDrawSegments(dpy, win, ReliefGC, seg, i); break; case RIGHT_HILITE: i = 0; seg[i].x1 = w+x-1; seg[i].y1 = y; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, Scr.BlackGC, seg, i); i = 0; seg[i].x1 = w+x-2; seg[i].y1 = y; seg[i].x2 = w+x-2; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, ShadowGC, seg, i); break; case BOTTOM_HILITE: i = 0; seg[i].x1 = x; seg[i].y1 = h+y-1; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, Scr.BlackGC, seg, i); i = 0; seg[i].x1 = x; seg[i].y1 = h+y-2; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-2; XDrawSegments(dpy, win, ShadowGC, seg, i); break; } return; } /* corners */ if (edge >= 1 && edge <= 4) { switch (edge) { case 1: i = 0; seg[i].x1 = x+1; seg[i].y1 = y+1; seg[i].x2 = x+1; seg[i++].y2 = h+y-1; seg[i].x1 = x+1; seg[i].y1 = y+1; seg[i].x2 = w+x-1; seg[i++].y2 = y+1; XDrawSegments(dpy, win, ReliefGC, seg, i); break; case 2: i = 0; seg[i].x1 = x; seg[i].y1 = y+1; seg[i].x2 = w+x-2; seg[i++].y2 = y+1; XDrawSegments(dpy, win, ReliefGC, seg, i); i = 0; seg[i].x1 = w+x-1; seg[i].y1 = y; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, Scr.BlackGC, seg, i); i = 0; seg[i].x1 = w+x-2; seg[i].y1 = y+1; seg[i].x2 = w+x-2; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, ShadowGC, seg, i); break; case 3: i = 0; seg[i].x1 = x+1; seg[i].y1 = y; seg[i].x2 = x+1; seg[i++].y2 = h+y-2; XDrawSegments(dpy, win, ReliefGC, seg, i); i = 0; seg[i].x1 = x; seg[i].y1 = h+y-1; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, Scr.BlackGC, seg, i); i = 0; seg[i].x1 = x+1; seg[i].y1 = h+y-2; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-2; XDrawSegments(dpy, win, ShadowGC, seg, i); break; case 4: i = 0; seg[i].x1 = w+x-1; seg[i].y1 = y; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; seg[i].x1 = x; seg[i].y1 = h+y-1; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, Scr.BlackGC, seg, i); i = 0; seg[i].x1 = w+x-2; seg[i].y1 = y; seg[i].x2 = w+x-2; seg[i++].y2 = h+y-2; seg[i].x1 = x; seg[i].y1 = h+y-2; seg[i].x2 = w+x-2; seg[i++].y2 = h+y-2; XDrawSegments(dpy, win, ShadowGC, seg, i); break; } return; } /* any other rectangular window */ if (edge == 0) { i = 0; seg[i].x1 = x+1; seg[i].y1 = y+1; seg[i].x2 = w+x-2; seg[i++].y2 = y+1; seg[i].x1 = x+1; seg[i].y1 = y+1; seg[i].x2 = x+1; seg[i++].y2 = h+y-2; XDrawSegments(dpy, win, ReliefGC, seg, i); i = 0; seg[i].x1 = x+1; seg[i].y1 = h+y-2; seg[i].x2 = w+x-2; seg[i++].y2 = h+y-2; seg[i].x1 = w+x-2; seg[i].y1 = y+1; seg[i].x2 = w+x-2; seg[i++].y2 = h+y-2; XDrawSegments(dpy, win, ShadowGC, seg, i); i = 0; seg[i].x1 = x; seg[i].y1 = h+y-1; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; seg[i].x1 = w+x-1; seg[i].y1 = y; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, Scr.BlackGC, seg, i); return; } } void RelieveButton (FvwmWindow *t, Window win, int x, int y, int w, int h, GC ReliefGC, GC ShadowGC, int state) { int i; XSegment seg[4]; if (state) /* 1 = pressed */ { i = 0; seg[i].x1 = x; seg[i].y1 = y; seg[i].x2 = w+x-1; seg[i++].y2 = y; seg[i].x1 = x; seg[i].y1 = y; seg[i].x2 = x; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, Scr.BlackGC, seg, i); i = 0; seg[i].x1 = x+1; seg[i].y1 = y+1; seg[i].x2 = w+x-2; seg[i++].y2 = y+1; seg[i].x1 = x+1; seg[i].y1 = y+1; seg[i].x2 = x+1; seg[i++].y2 = h+y-2; XDrawSegments(dpy, win, ShadowGC, seg, i); i = 0; seg[i].x1 = x+1; seg[i].y1 = h+y-1; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; seg[i].x1 = w+x-1; seg[i].y1 = y+1; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, ReliefGC, seg, i); } else { i = 0; seg[i].x1 = x; seg[i].y1 = y; seg[i].x2 = w+x-2; seg[i++].y2 = y; seg[i].x1 = x; seg[i].y1 = y; seg[i].x2 = x; seg[i++].y2 = h+y-2; XDrawSegments(dpy, win, ReliefGC, seg, i); i = 0; seg[i].x1 = x+1; seg[i].y1 = h+y-2; seg[i].x2 = w+x-2; seg[i++].y2 = h+y-2; seg[i].x1 = w+x-2; seg[i].y1 = y+1; seg[i].x2 = w+x-2; seg[i++].y2 = h+y-2; XDrawSegments(dpy, win, ShadowGC, seg, i); i = 0; seg[i].x1 = x; seg[i].y1 = h+y-1; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; seg[i].x1 = w+x-1; seg[i].y1 = y; seg[i].x2 = w+x-1; seg[i++].y2 = h+y-1; XDrawSegments(dpy, win, Scr.BlackGC, seg, i); } } /*********************************************************************** * * Procedure: * Setupframe - set window sizes, this was called from either * AddWindow, EndResize, or HandleConfigureNotify. * * Inputs: * tmp_win - the FvwmWindow pointer * x - the x coordinate of the upper-left outer corner of the frame * y - the y coordinate of the upper-left outer corner of the frame * w - the width of the frame window w/o border * h - the height of the frame window w/o border * * Special Considerations: * This routine will check to make sure the window is not completely * off the display, if it is, it'll bring some of it back on. * * The tmp_win->frame_XXX variables should NOT be updated with the * values of x,y,w,h prior to calling this routine, since the new * values are compared against the old to see whether a synthetic * ConfigureNotify event should be sent. (It should be sent if the * window was moved but not resized.) * ************************************************************************/ void SetupFrame(FvwmWindow *tmp_win, int x, int y, int w, int h, Bool sendEvent) { XEvent client_event; XWindowChanges frame_wc, xwc; unsigned long frame_mask, xwcm; int cx, cy, i; Bool Resized = False; int xwidth, ywidth; Window *win; /* if windows is not being maximized, save size in case of maximization */ if (!(tmp_win->flags & MAXIMIZED)) { tmp_win->orig_x = x; tmp_win->orig_y = y; tmp_win->orig_wd = w; tmp_win->orig_ht = h; } /* This screws up the Taskbar's AutoHide mode when the southern and eastern most pages are selected. Is this really necessary anyway? Will removing this break anything else? */ /* if (x >= Scr.MyDisplayWidth + Scr.VxMax - Scr.Vx - 16) x = Scr.MyDisplayWidth + Scr.VxMax - Scr.Vx - 16; if (y >= Scr.MyDisplayHeight + Scr.VyMax - Scr.Vy - 16) y = Scr.MyDisplayHeight + Scr.VyMax - Scr.Vy - 16; */ /* * According to the July 27, 1988 ICCCM draft, we should send a * "synthetic" ConfigureNotify event to the client if the window * was moved but not resized. */ if ((x != tmp_win->frame_x || y != tmp_win->frame_y) && (w == tmp_win->frame_width && h == tmp_win->frame_height)) sendEvent = TRUE; if((w != tmp_win->frame_width) || (h != tmp_win->frame_height)) Resized = True; xwcm = CWX | CWY | CWWidth | CWHeight; if(Resized) { if (tmp_win->flags & TITLE) tmp_win->title_height = Scr.TitleHeight + tmp_win->bw; tmp_win->title_width = w - (tmp_win->boundary_width << 1) + tmp_win->bw; if(tmp_win->title_width < 1) tmp_win->title_width = 1; if (tmp_win->flags & TITLE) { /* setup titlebar window */ tmp_win->title_x = tmp_win->boundary_width; if(tmp_win->title_x >= w - tmp_win->boundary_width) tmp_win->title_x = -10; tmp_win->title_y = tmp_win->boundary_width; xwc.width = tmp_win->title_width; xwc.height = tmp_win->title_height; xwc.x = tmp_win->title_x; xwc.y = tmp_win->title_y; XConfigureWindow(dpy, tmp_win->title_w, xwcm, &xwc); /* setup left button windows */ /* mini-icon first */ if (tmp_win->title_icon) { xwc.height = tmp_win->title_icon->height; xwc.width = tmp_win->title_icon->width; } else { xwc.height = Scr.button_height; xwc.width = Scr.button_width; } xwc.y = tmp_win->boundary_width + ((tmp_win->title_height - xwc.height) >> 1) +1; xwc.x = tmp_win->boundary_width +3; win = tmp_win->left_w; if (*win != None) { if(xwc.x + xwc.width >= w-tmp_win->boundary_width) xwc.x = -xwc.width; XConfigureWindow(dpy, *win, xwcm, &xwc); xwc.x += xwc.width +2; } win++; xwc.height = Scr.button_height; xwc.width = Scr.button_width; xwc.y = tmp_win->boundary_width + ((tmp_win->title_height - xwc.height) >> 1) +1; for(i=1; i= w-tmp_win->boundary_width) xwc.x = -Scr.button_width; XConfigureWindow(dpy, *win, xwcm, &xwc); xwc.x += Scr.button_width +2; } } /* setup right button windows */ xwc.x = w-tmp_win->boundary_width + tmp_win->bw -2; for(i=0, win=tmp_win->right_w; iboundary_width) xwc.x = -Scr.button_width; XConfigureWindow(dpy, *win, xwcm, &xwc); if (i == 0) xwc.x -= 2; } } } if(tmp_win->flags & BORDER) { /* setup side windows */ tmp_win->corner_width = Scr.TitleHeight + tmp_win->bw + tmp_win->boundary_width; if (w < (tmp_win->corner_width << 1)) tmp_win->corner_width = w/3; if (h < (tmp_win->corner_width << 1)) tmp_win->corner_width = h/3; xwidth = w - (tmp_win->corner_width << 1) + tmp_win->bw; ywidth = h - (tmp_win->corner_width << 1); if (xwidth < 2) xwidth = 2; if (ywidth < 2) ywidth = 2; for(i=0, win=tmp_win->sides; i<4; i++, win++) { if (i == 0) { xwc.x = tmp_win->corner_width; xwc.y = 0; xwc.height = tmp_win->boundary_width; xwc.width = xwidth; } else if (i == 1) { xwc.x = w - tmp_win->boundary_width + tmp_win->bw; xwc.y = tmp_win->corner_width; xwc.width = tmp_win->boundary_width; xwc.height = ywidth; } else if (i == 2) { xwc.x = tmp_win->corner_width; xwc.y = h - tmp_win->boundary_width + tmp_win->bw; xwc.height = tmp_win->boundary_width + tmp_win->bw; xwc.width = xwidth; } else { xwc.x = 0; xwc.y = tmp_win->corner_width; xwc.width = tmp_win->boundary_width; xwc.height = ywidth; } XConfigureWindow(dpy, *win, xwcm, &xwc); } /* setup corner windows */ xwc.width = tmp_win->corner_width; xwc.height = tmp_win->corner_width; for(i=0, win=tmp_win->corners; i<4; i++, win++) { if(i & 1) xwc.x = w - tmp_win->corner_width + tmp_win->bw; else xwc.x = 0; if(i >> 1) xwc.y = h - tmp_win->corner_width; else xwc.y = 0; XConfigureWindow(dpy, *win, xwcm, &xwc); } } } tmp_win->attr.width = w - (tmp_win->boundary_width << 1); tmp_win->attr.height = h - tmp_win->title_height - (tmp_win->boundary_width << 1); cx = tmp_win->boundary_width - tmp_win->bw; cy = tmp_win->title_height + tmp_win->boundary_width - tmp_win->bw; XResizeWindow(dpy, tmp_win->w, tmp_win->attr.width, tmp_win->attr.height); XMoveResizeWindow(dpy, tmp_win->Parent, cx,cy, tmp_win->attr.width, tmp_win->attr.height); /* * fix up frame and assign size/location values in tmp_win */ frame_wc.x = tmp_win->frame_x = x; frame_wc.y = tmp_win->frame_y = y; frame_wc.width = tmp_win->frame_width = w; frame_wc.height = tmp_win->frame_height = h; frame_mask = (CWX | CWY | CWWidth | CWHeight); XConfigureWindow (dpy, tmp_win->frame, frame_mask, &frame_wc); #ifdef SHAPE if (ShapesSupported) if ((Resized) && (tmp_win->wShaped)) SetShape (tmp_win, w); #endif /* SHAPE */ XSync (dpy, 0); if (sendEvent) { client_event.type = ConfigureNotify; client_event.xconfigure.display = dpy; client_event.xconfigure.event = tmp_win->w; client_event.xconfigure.window = tmp_win->w; client_event.xconfigure.x = x + tmp_win->boundary_width; client_event.xconfigure.y = y + tmp_win->title_height + tmp_win->boundary_width; client_event.xconfigure.width = w - (tmp_win->boundary_width << 1); client_event.xconfigure.height = h - (tmp_win->boundary_width << 1) - tmp_win->title_height; client_event.xconfigure.border_width = tmp_win->bw; /* Real ConfigureNotify events say we're above title window, so ... */ /* what if we don't have a title ????? */ client_event.xconfigure.above = tmp_win->frame; client_event.xconfigure.override_redirect = False; XSendEvent(dpy, tmp_win->w, False, StructureNotifyMask, &client_event); } BroadcastConfig (M_CONFIGURE_WINDOW, tmp_win); } /**************************************************************************** * * Sets up the shaped window borders * ****************************************************************************/ void SetShape(FvwmWindow *tmp_win, int w) { #ifdef SHAPE if (ShapesSupported) { XRectangle rect; XShapeCombineShape (dpy, tmp_win->frame, ShapeBounding, tmp_win->boundary_width, tmp_win->title_height + tmp_win->boundary_width, tmp_win->w, ShapeBounding, ShapeSet); if (tmp_win->title_w) { /* windows w/ titles */ rect.x = tmp_win->boundary_width; rect.y = tmp_win->title_y; rect.width = w - (tmp_win->boundary_width << 1) + tmp_win->bw; rect.height = tmp_win->title_height; XShapeCombineRectangles(dpy, tmp_win->frame, ShapeBounding, 0, 0, &rect, 1, ShapeUnion, Unsorted); } } #endif }