/* ResyncFvwmStackRing - Rebuilds the stacking order ring of FVWM-managed windows. For use in cases where apps raise/lower their own windows in a way that makes it difficult to determine exactly where they ended up in the stacking order. - Based on code from Matthias Clasen. */ void ResyncFvwmStackRing (void) { Window root, parent, *children; unsigned int nchildren, i; FvwmWindow *t1, *t2; MyXGrabServer (dpy); if (!XQueryTree (dpy, Scr.Root, &root, &parent, &children, &nchildren)) { MyXUngrabServer (dpy); return; } t2 = &Scr.FvwmRoot; for (i = 0; i < nchildren; i++) { for (t1 = Scr.FvwmRoot.next; t1 != NULL; t1 = t1->next) { if (t1->flags & ICONIFIED && (!(t1->flags & SUPPRESSICON))) { if (t1->icon_w == children[i]) { break; } else if (t1->icon_pixmap_w == children[i]) { break; } } else { if (t1->frame == children[i]) { break; } } } if (t1 != NULL && t1 != t2) { /* Move the window to its new position, working from the bottom up (that's the way XQueryTree presents the list). */ t1->stack_prev->stack_next = t1->stack_next; /* Pluck from chain. */ t1->stack_next->stack_prev = t1->stack_prev; t1->stack_next = t2; /* Set new pointers. */ t1->stack_prev = t2->stack_prev; t2->stack_prev->stack_next = t1; /* Insert in new position. */ t2->stack_prev = t1; t2 = t1; } } MyXUngrabServer (dpy); XFree (children); }
static void __focus_grab_buttons(FvwmWindow *fw, Bool client_entered) { int i; Bool do_grab_window = False; int grab_buttons; if (fw == NULL || IS_SCHEDULED_FOR_DESTROY(fw) || !IS_MAPPED(fw)) { /* It is pointless to grab buttons on dieing windows. Buttons * can not be grabbed when the window is unmapped. */ return; } grab_buttons = Scr.buttons2grab; do_grab_window = focus_query_grab_buttons(fw, client_entered); if (do_grab_window == True) { grab_buttons |= FP_USE_MOUSE_BUTTONS(FW_FOCUS_POLICY(fw)); } if (grab_buttons != fw->grabbed_buttons) { MyXGrabServer(dpy); for (i = 0; i < NUMBER_OF_EXTENDED_MOUSE_BUTTONS; i++) { __focus_grab_one_button(fw, i, grab_buttons); } MyXUngrabServer (dpy); } return; }
void ExitPager(void) { if (is_transient) { XUngrabPointer(dpy,CurrentTime); MyXUngrabServer(dpy); XSync(dpy,0); } XUngrabKeyboard(dpy, CurrentTime); exit(0); }
/* This function is part of a hack to make focus handling work better with * applications that use the passive focus model but manage focus in their own * sub windows and should thus use the locally active focus model instead. * There are many examples like netscape or ddd. */ void focus_force_refresh_focus(const FvwmWindow *fw) { XWindowAttributes winattrs; MyXGrabServer(dpy); if (XGetWindowAttributes(dpy, FW_W(fw), &winattrs)) { XSelectInput( dpy, FW_W(fw), winattrs.your_event_mask & ~FocusChangeMask); FOCUS_SET(FW_W(fw), NULL /* we don't expect an event */); XSelectInput(dpy, FW_W(fw), winattrs.your_event_mask); } MyXUngrabServer(dpy); return; }
/* This function is part of a hack to make focus handling work better with * applications that use the passive focus model but manage focus in their own * sub windows and should thus use the locally active focus model instead. * There are many examples like netscape or ddd. */ void refresh_focus(FvwmWindow *fw) { Bool do_refresh = False; if (fw == NULL || fw != get_focus_window() || HAS_NEVER_FOCUS(fw)) { /* only refresh the focus on the currently focused window */ return; } /* only refresh the focus for windows with the passive focus model so that * we don't disturb focus handling more than necessary */ switch (fw->focus_model) { case FM_PASSIVE: do_refresh = True; break; case FM_NO_INPUT: case FM_GLOBALLY_ACTIVE: case FM_LOCALLY_ACTIVE: default: do_refresh = False; break; } if (do_refresh) { XWindowAttributes winattrs; MyXGrabServer(dpy); if (XGetWindowAttributes(dpy, fw->w, &winattrs)) { XSelectInput(dpy, fw->w, winattrs.your_event_mask & ~FocusChangeMask); FOCUS_SET(fw->w); XSelectInput(dpy, fw->w, winattrs.your_event_mask); } MyXUngrabServer(dpy); } return; }
/* create a pixmap suitable for plonking on the background of a part of a * window */ Pixmap CreateOffsetBackgroundPixmap( Display *dpy, Window win, int x, int y, int width, int height, colorset_t *colorset, unsigned int depth, GC gc, Bool is_shape_mask) { Pixmap pixmap = None; Pixmap cs_pixmap = None; XGCValues xgcv; static GC shape_gc = None; GC fill_gc = None; /* not static as dpy may change (FvwmBacker) */ int cs_width; int cs_height; Bool cs_keep_aspect; Bool cs_stretch_x; Bool cs_stretch_y; if (colorset->pixmap == ParentRelative && !is_shape_mask && colorset->tint_percent > 0) { FvwmRenderAttributes fra; fra.mask = FRAM_DEST_IS_A_WINDOW | FRAM_HAVE_TINT; fra.tint = colorset->tint; fra.tint_percent = colorset->tint_percent; MyXGrabServer(dpy); pixmap = PGraphicsCreateTransparency( dpy, win, &fra, gc, x, y, width, height, True); MyXUngrabServer(dpy); if (pixmap == None) { return ParentRelative; } return pixmap; } else if (colorset->pixmap == ParentRelative && !is_shape_mask) { return ParentRelative; } else if (CSETS_IS_TRANSPARENT_ROOT(colorset) && colorset->pixmap && !is_shape_mask) { int sx,sy; int h,w; XID dummy; cs_pixmap = colorset->pixmap; cs_width = colorset->width; cs_height = colorset->height; if (CSETS_IS_TRANSPARENT_ROOT_PURE(colorset)) { /* check if it is still here */ union { XID junk; unsigned int ui_junk; int i_junk; } XID_int; /* a priori we should grab the server, but this * cause PositiveWrite error when you move a * window with a transparent title bar */ if (!XGetGeometry( dpy, colorset->pixmap, &XID_int.junk, &XID_int.i_junk, &XID_int.i_junk, (unsigned int *)&w, (unsigned int *)&h, &XID_int.ui_junk, &XID_int.ui_junk) || w != cs_width || h != cs_height) { return None; } } XTranslateCoordinates( dpy, win, DefaultRootWindow(dpy), x, y, &sx, &sy, &dummy); pixmap = XCreatePixmap(dpy, win, width, height, Pdepth); if (!pixmap) { return None; } /* make sx and sy positif */ while (sx < 0) { sx = sx + cs_width; } while (sy < 0) { sy = sy + cs_height; } /* make sx and sy in (0,0,cs_width,cs_height) */ while (sx >= cs_width) { sx = sx - cs_width; } while (sy >= cs_height) { sy = sy - cs_height; } xgcv.fill_style = FillTiled; xgcv.tile = cs_pixmap; xgcv.ts_x_origin = cs_width-sx; xgcv.ts_y_origin = cs_height-sy; fill_gc = fvwmlib_XCreateGC( dpy, win, GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle, &xgcv); if (fill_gc == None) { XFreePixmap(dpy, pixmap); return None; } XSync(dpy, False); is_bad_gc = 0; ferror_set_temp_error_handler(BadGCErrorHandler); XFillRectangle(dpy, pixmap, fill_gc, 0, 0, width, height); if ( is_bad_gc == 0 && CSETS_IS_TRANSPARENT_ROOT_PURE(colorset) && colorset->tint_percent > 0) { FvwmRenderAttributes fra; fra.mask = FRAM_HAVE_TINT; fra.tint = colorset->tint; fra.tint_percent = colorset->tint_percent; PGraphicsRenderPixmaps( dpy, win, pixmap, None, None, Pdepth, &fra, pixmap, fill_gc, None, None, 0, 0, width, height, 0, 0, width, height, False); } XSync(dpy, False); ferror_reset_temp_error_handler(); if (is_bad_gc == 1) { is_bad_gc = 0; XFreePixmap(dpy, pixmap); pixmap = None; } XFreeGC(dpy,fill_gc); return pixmap; } if (!is_shape_mask) { cs_pixmap = colorset->pixmap; cs_width = colorset->width; cs_height = colorset->height; cs_keep_aspect = (colorset->pixmap_type == PIXMAP_STRETCH_ASPECT); cs_stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X) || (colorset->pixmap_type == PIXMAP_STRETCH); cs_stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y) || (colorset->pixmap_type == PIXMAP_STRETCH); } else { /* In spite of the name, win contains the pixmap */ cs_pixmap = colorset->shape_mask; win = colorset->shape_mask; if (shape_gc == None) { xgcv.foreground = 1; xgcv.background = 0; /* create a gc for 1 bit depth */ shape_gc = fvwmlib_XCreateGC( dpy, win, GCForeground|GCBackground, &xgcv); } gc = shape_gc; cs_width = colorset->shape_width; cs_height = colorset->shape_height; cs_keep_aspect = (colorset->shape_type == SHAPE_STRETCH_ASPECT); cs_stretch_x = !(colorset->shape_type == SHAPE_TILED); cs_stretch_y = !(colorset->shape_type == SHAPE_TILED); } if (cs_pixmap == None) { xgcv.foreground = colorset->bg; fill_gc = fvwmlib_XCreateGC(dpy, win, GCForeground, &xgcv); /* create a solid pixmap - not very useful most of the time */ pixmap = XCreatePixmap(dpy, win, 1, 1, depth); XFillRectangle(dpy, pixmap, fill_gc, 0, 0, 1, 1); XFreeGC(dpy,fill_gc); } else if (cs_keep_aspect) { Bool trim_side; int big_width, big_height; Pixmap big_pixmap; int x, y; /* make a pixmap big enough to cover the destination but with * the aspect ratio of the cs_pixmap */ trim_side = get_aspect_dimensions( &big_width, &big_height, width, height, cs_width, cs_height); big_pixmap = CreateStretchPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, big_width, big_height, gc); /* work out where to trim */ x = trim_side ? (big_width - width) / 2 : 0; y = trim_side ? 0 : (big_height - height) / 2; pixmap = XCreatePixmap(dpy, cs_pixmap, width, height, depth); if (pixmap && big_pixmap) { XCopyArea( dpy, big_pixmap, pixmap, gc, x, y, width, height, 0, 0); } if (big_pixmap) { XFreePixmap(dpy, big_pixmap); } } else if (!cs_stretch_x && !cs_stretch_y) { /* it's a tiled pixmap, create an unstretched one */ if (!is_shape_mask) { pixmap = XCreatePixmap( dpy, cs_pixmap, cs_width, cs_height, depth); if (pixmap) { XCopyArea( dpy, cs_pixmap, pixmap, gc, 0, 0, cs_width, cs_height, 0, 0); } } else { /* can't tile masks, create a tiled version of the * mask */ pixmap = CreateTiledPixmap( dpy, cs_pixmap, cs_width, cs_height, width, height, 1, gc); } } else if (!cs_stretch_x) { /* it's an HGradient */ pixmap = CreateStretchYPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, height, gc); } else if (!cs_stretch_y) { /* it's a VGradient */ pixmap = CreateStretchXPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, width, gc); } else { /* It's a full window pixmap */ pixmap = CreateStretchPixmap( dpy, cs_pixmap, cs_width, cs_height, depth, width, height, gc); } if (x != 0 || y != 0) { Pixmap p2; p2 = ScrollPixmap( dpy, pixmap, gc, x, y, width, height, depth); if (p2 != None && p2 != ParentRelative && p2 != pixmap) { XFreePixmap(dpy, pixmap); pixmap = p2; } } return pixmap; }
/* translate a colorset spec into a colorset structure */ void parse_colorset(int n, char *line) { int i; int w; int h; int tmp; int percent; colorset_t *cs; char *optstring; char *args; char *option; char *tmp_str; char *fg = NULL; char *bg = NULL; char *hi = NULL; char *sh = NULL; char *fgsh = NULL; char *tint = NULL; char *fg_tint = NULL; char *bg_tint = NULL; char *icon_tint = NULL; Bool have_pixels_changed = False; Bool has_icon_pixels_changed = False; Bool has_fg_changed = False; Bool has_bg_changed = False; Bool has_sh_changed = False; Bool has_hi_changed = False; Bool has_fgsh_changed = False; Bool has_fg_alpha_changed = False; Bool has_tint_changed = False; Bool has_fg_tint_changed = False; Bool has_bg_tint_changed = False; Bool has_icon_tint_changed = False; Bool has_pixmap_changed = False; Bool has_shape_changed = False; Bool has_image_alpha_changed = False; Bool pixmap_is_a_bitmap = False; Bool do_reload_pixmap = False; Bool is_server_grabbed = False; XColor color; XGCValues xgcv; static char *name = "parse_colorset"; Window win = Scr.NoFocusWin; static GC gc = None; /* initialize statics */ if (gc == None) { gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv); } /* make sure it exists and has sensible contents */ alloc_colorset(n); cs = &Colorset[n]; /*** Parse the options ***/ while (line && *line) { /* Read next option specification delimited by a comma or \0. */ line = GetQuotedString( line, &optstring, ",", NULL, NULL, NULL); if (!optstring) break; args = GetNextToken(optstring, &option); if (!option) { free(optstring); break; } switch((i = GetTokenIndex(option, csetopts, 0, NULL))) { case 0: /* Foreground */ case 1: /* Fore */ case 2: /* fg */ get_simple_color( args, &fg, cs, FG_SUPPLIED, FG_CONTRAST, "contrast"); has_fg_changed = True; break; case 3: /* Background */ case 4: /* Back */ case 5: /* bg */ get_simple_color( args, &bg, cs, BG_SUPPLIED, BG_AVERAGE, "average"); has_bg_changed = True; break; case 6: /* Hilight */ case 7: /* Hilite */ case 8: /* hi */ get_simple_color(args, &hi, cs, HI_SUPPLIED, 0, NULL); has_hi_changed = True; break; case 9: /* Shadow */ case 10: /* Shade */ case 11: /* sh */ get_simple_color(args, &sh, cs, SH_SUPPLIED, 0, NULL); has_sh_changed = True; break; case 12: /* fgsh */ get_simple_color( args, &fgsh, cs, FGSH_SUPPLIED, 0,NULL); has_fgsh_changed = True; break; case 13: /* fg_alpha */ case 14: /* fgAlpha */ if (GetIntegerArguments(args, NULL, &tmp, 1)) { if (tmp > 100) tmp = 100; else if (tmp < 0) tmp = 0; } else { tmp = 100; } if (tmp != cs->fg_alpha_percent) { cs->fg_alpha_percent = tmp; has_fg_alpha_changed = True; } break; case 15: /* TiledPixmap */ case 16: /* Pixmap */ case 17: /* AspectPixmap */ has_pixmap_changed = True; free_colorset_background(cs, True); tmp_str = PeekToken(args, &args); if (tmp_str) { CopyString(&cs->pixmap_args, tmp_str); do_reload_pixmap = True; cs->gradient_type = 0; /* set the flags */ if (csetopts[i][0] == 'T') { cs->pixmap_type = PIXMAP_TILED; } else if (csetopts[i][0] == 'A') { cs->pixmap_type = PIXMAP_STRETCH_ASPECT; } else { cs->pixmap_type = PIXMAP_STRETCH; } } /* the pixmap is build later */ break; case 18: /* Shape */ case 19: /* TiledShape */ case 20: /* AspectShape */ parse_shape(win, cs, i, args, &has_shape_changed); break; case 21: /* Plain */ has_pixmap_changed = True; free_colorset_background(cs, True); break; case 22: /* NoShape */ has_shape_changed = True; if (cs->shape_mask) { add_to_junk(cs->shape_mask); cs->shape_mask = None; } break; case 23: /* Transparent */ /* This is only allowable when the root depth == fvwm * visual depth otherwise bad match errors happen, * it may be even more restrictive but my tests (on * exceed 6.2) show that only == depth is necessary */ if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy)))) { fvwm_msg( ERR, name, "can't do Transparent " "when root_depth!=fvwm_depth"); break; } has_pixmap_changed = True; free_colorset_background(cs, True); cs->pixmap = ParentRelative; cs->pixmap_type = PIXMAP_STRETCH; break; case 24: /* RootTransparent */ if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy)))) { fvwm_msg( ERR, name, "can't do RootTransparent " "when root_depth!=fvwm_depth"); break; } free_colorset_background(cs, True); has_pixmap_changed = True; cs->pixmap_type = PIXMAP_ROOT_PIXMAP_PURE; do_reload_pixmap = True; tmp_str = PeekToken(args, &args); if (StrEquals(tmp_str, "buffer")) { cs->allows_buffered_transparency = True; } else { cs->allows_buffered_transparency = False; } cs->is_maybe_root_transparent = True; break; case 25: /* Tint */ case 26: /* PixmapTint */ case 27: /* ImageTint */ case 28: /* TintMask */ parse_simple_tint( cs, args, &tint, TINT_SUPPLIED, &has_tint_changed, &percent, "tint"); if (has_tint_changed) { cs->tint_percent = percent; } break; case 29: /* NoTint */ has_tint_changed = True; cs->tint_percent = 0; cs->color_flags &= ~TINT_SUPPLIED; break; case 30: /* fgTint */ parse_simple_tint( cs, args, &fg_tint, FG_TINT_SUPPLIED, &has_fg_tint_changed, &percent, "fgTint"); if (has_fg_tint_changed) { cs->fg_tint_percent = percent; } break; case 31: /* bgTint */ parse_simple_tint( cs, args, &bg_tint, BG_TINT_SUPPLIED, &has_bg_tint_changed, &percent, "bgTint"); if (has_bg_tint_changed) { cs->bg_tint_percent = percent; } break; case 32: /* dither */ if (cs->pixmap_args || cs->gradient_args) { has_pixmap_changed = True; do_reload_pixmap = True; } cs->dither = True; break; case 33: /* nodither */ if (cs->pixmap_args || cs->gradient_args) { has_pixmap_changed = True; do_reload_pixmap = True; } cs->dither = False; break; case 34: /* Alpha */ case 35: /* PixmapAlpha */ case 36: /* ImageAlpha */ if (GetIntegerArguments(args, NULL, &tmp, 1)) { if (tmp > 100) tmp = 100; else if (tmp < 0) tmp = 0; } else { tmp = 100; } if (tmp != cs->image_alpha_percent) { has_image_alpha_changed = True; cs->image_alpha_percent = tmp; } break; /* dither icon is not dynamic (yet) maybe a bad opt: default * to False ? */ case 37: /* ditherIcon */ cs->do_dither_icon = True; break; case 38: /* DoNotDitherIcon */ cs->do_dither_icon = False; break; case 39: /* IconTint */ parse_simple_tint( cs, args, &icon_tint, ICON_TINT_SUPPLIED, &has_icon_tint_changed, &percent, "IconTint"); if (has_icon_tint_changed) { cs->icon_tint_percent = percent; has_icon_pixels_changed = True; } break; case 40: /* NoIconTint */ has_icon_tint_changed = True; if (cs->icon_tint_percent != 0) { has_icon_pixels_changed = True; } cs->icon_tint_percent = 0; break; case 41: /* IconAlpha */ if (GetIntegerArguments(args, NULL, &tmp, 1)) { if (tmp > 100) tmp = 100; else if (tmp < 0) tmp = 0; } else { tmp = 100; } if (tmp != cs->icon_alpha_percent) { has_icon_pixels_changed = True; cs->icon_alpha_percent = tmp; } break; default: /* test for ?Gradient */ if (option[0] && StrEquals(&option[1], "Gradient")) { cs->gradient_type = toupper(option[0]); if (!IsGradientTypeSupported(cs->gradient_type)) break; has_pixmap_changed = True; free_colorset_background(cs, True); CopyString(&cs->gradient_args, args); do_reload_pixmap = True; if (cs->gradient_type == V_GRADIENT) { cs->pixmap_type = PIXMAP_STRETCH_Y; } else if (cs->gradient_type == H_GRADIENT) cs->pixmap_type = PIXMAP_STRETCH_X; else cs->pixmap_type = PIXMAP_STRETCH; } else { fvwm_msg( WARN, name, "bad colorset pixmap " "specifier %s %s", option, line); } break; } /* switch */ if (option) { free(option); option = NULL; } free(optstring); optstring = NULL; } /* while (line && *line) */ /* * ---------- change the "pixmap" tint colour ---------- */ if (has_tint_changed) { /* user specified colour */ if (tint != NULL) { Pixel old_tint = cs->tint; PictureFreeColors(dpy, Pcmap, &cs->tint, 1, 0, True); cs->tint = GetColor(tint); if (old_tint != cs->tint) { have_pixels_changed = True; } } else if (tint == NULL) { /* default */ Pixel old_tint = cs->tint; PictureFreeColors(dpy, Pcmap, &cs->tint, 1, 0, True); cs->tint = GetColor(black); if (old_tint != cs->tint) { have_pixels_changed = True; } } } /* * reload the gradient if the tint or the alpha have changed. * Do this too if we need to recompute the bg average and the * gradient is tinted (perforemence issue). */ if ((has_tint_changed || has_image_alpha_changed || (has_bg_changed && (cs->color_flags & BG_AVERAGE) && cs->tint_percent > 0)) && cs->gradient_args) { do_reload_pixmap = True; } /* * reset the pixmap if the tint or the alpha has changed */ if (!do_reload_pixmap && (has_tint_changed || has_image_alpha_changed || (has_bg_changed && cs->alpha_pixmap != None))) { if (cs->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE || cs->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN) { do_reload_pixmap = True; } else if (cs->picture != NULL && cs->pixmap) { XSetClipMask(dpy, gc, cs->picture->mask); reset_cs_pixmap(cs, gc); XSetClipMask(dpy, gc, None); has_pixmap_changed = True; } } /* * (re)build the pixmap or the gradient */ if (do_reload_pixmap) { free_colorset_background(cs, False); has_pixmap_changed = True; if (cs->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE || cs->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN) { cs->pixmap_type = 0; if (root_pic.pixmap) { cs->pixmap = root_pic.pixmap; cs->width = root_pic.width; cs->height = root_pic.height; cs->pixmap_type = PIXMAP_ROOT_PIXMAP_PURE; #if 0 fprintf(stderr,"Cset %i LoadRoot 0x%lx\n", n, cs->pixmap); #endif } } else if (cs->pixmap_args) { parse_pixmap(win, gc, cs, &pixmap_is_a_bitmap); } else if (cs->gradient_args) { cs->pixmap = CreateGradientPixmapFromString( dpy, win, gc, cs->gradient_type, cs->gradient_args, &w, &h, &cs->pixels, &cs->nalloc_pixels, cs->dither); cs->width = w; cs->height = h; } has_pixmap_changed = True; } if (cs->picture != NULL && cs->picture->depth != Pdepth) { pixmap_is_a_bitmap = True; } /* * ---------- change the background colour ---------- */ if (has_bg_changed || (has_pixmap_changed && (cs->color_flags & BG_AVERAGE) && cs->pixmap != None && cs->pixmap != ParentRelative && !pixmap_is_a_bitmap)) { Bool do_set_default_background = False; Pixmap average_pix = None; if (cs->color_flags & BG_AVERAGE) { if (cs->picture != NULL && cs->picture->picture != None) { average_pix = cs->picture->picture; } else if (cs->pixmap != ParentRelative) { average_pix = cs->pixmap; } if (average_pix == root_pic.pixmap) { int w; int h; XID dummy; MyXGrabServer(dpy); is_server_grabbed = True; if (!XGetGeometry( dpy, average_pix, &dummy, (int *)&dummy, (int *)&dummy, (unsigned int *)&w, (unsigned int *)&h, (unsigned int *)&dummy, (unsigned int *)&dummy)) { average_pix = None; } else { if (w != cs->width || h != cs->height) { average_pix = None; } } if (average_pix == None) { MyXUngrabServer(dpy); is_server_grabbed = False; } } } /* note: no average for bitmap */ if ((cs->color_flags & BG_AVERAGE) && average_pix) { /* calculate average background color */ XColor *colors; XImage *image; XImage *mask_image = None; unsigned int i, j, k = 0; unsigned long red = 0, blue = 0, green = 0; unsigned long tred, tblue, tgreen; double dred = 0.0, dblue = 0.0, dgreen = 0.0; has_bg_changed = True; /* create an array to store all the pixmap colors in */ /* Note: this may allocate a lot of memory: * cs->width * cs->height * 12 and then the rest of the * procedure can take a lot of times */ colors = (XColor *)safemalloc( cs->width * cs->height * sizeof(XColor)); /* get the pixmap and mask into an image */ image = XGetImage( dpy, average_pix, 0, 0, cs->width, cs->height, AllPlanes, ZPixmap); if (cs->mask != None) { mask_image = XGetImage( dpy, cs->mask, 0, 0, cs->width, cs->height, AllPlanes, ZPixmap); } if (is_server_grabbed == True) { MyXUngrabServer(dpy); } if (image != None && mask_image != None) { /* only fetch the pixels that are not masked * out */ for (i = 0; i < cs->width; i++) { for (j = 0; j < cs->height; j++) { if ( cs->mask == None || XGetPixel( mask_image, i, j) == 0) { colors[k++].pixel = XGetPixel( image, i, j); } } } } if (image != None) { XDestroyImage(image); } if (mask_image != None) { XDestroyImage(mask_image); } if (k == 0) { do_set_default_background = True; } else { /* look them all up, XQueryColors() can't * handle more than 256 */ for (i = 0; i < k; i += 256) { XQueryColors( dpy, Pcmap, &colors[i], min(k - i, 256)); } /* calculate average, add overflows in a double * .red is short, red is long */ for (i = 0; i < k; i++) { tred = red; red += colors[i].red; if (red < tred) { dred += (double)tred; red = colors[i].red; } tgreen = green; green += colors[i].green; if (green < tgreen) { dgreen += (double)tgreen; green = colors[i].green; } tblue = blue; blue += colors[i].blue; if (blue < tblue) { dblue += (double)tblue; blue = colors[i].blue; } } dred += red; dgreen += green; dblue += blue; /* get it */ color.red = dred / k; color.green = dgreen / k; color.blue = dblue / k; { Pixel old_bg = cs->bg; PictureFreeColors( dpy, Pcmap, &cs->bg, 1, 0, True); PictureAllocColor( dpy, Pcmap, &color, True); cs->bg = color.pixel; if (old_bg != cs->bg) { have_pixels_changed = True; } } } free(colors); } /* average */ else if ((cs->color_flags & BG_SUPPLIED) && bg != NULL) { /* user specified colour */ Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = GetColor(bg); if (old_bg != cs->bg) { have_pixels_changed = True; } } /* user specified */ else if (bg == NULL && has_bg_changed) { /* default */ do_set_default_background = True; } /* default */ if (do_set_default_background) { Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = GetColor(white); if (old_bg != cs->bg) { have_pixels_changed = True; } has_bg_changed = True; } if (has_bg_changed) { /* save the bg color for tinting */ cs->bg_saved = cs->bg; } } /* has_bg_changed */ /* * ---------- setup the bg tint colour ---------- */ if (has_bg_tint_changed && cs->bg_tint_percent > 0 && bg_tint != NULL) { PictureFreeColors(dpy, Pcmap, &cs->bg_tint, 1, 0, True); cs->bg_tint = GetColor(bg_tint); } /* * ---------- tint the bg colour ---------- */ if (has_bg_tint_changed || (has_bg_changed && cs->bg_tint_percent > 0)) { if (cs->bg_tint_percent == 0) { Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = cs->bg_saved; if (old_bg != cs->bg) { have_pixels_changed = True; has_bg_changed = True; } } else { Pixel old_bg = cs->bg; PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True); cs->bg = GetTintedPixel( cs->bg_saved, cs->bg_tint, cs->bg_tint_percent); if (old_bg != cs->bg) { have_pixels_changed = True; has_bg_changed = True; } } } /* * ---------- setup the fg tint colour ---------- */ if (has_fg_tint_changed && cs->fg_tint_percent > 0 && fg_tint != NULL) { PictureFreeColors(dpy, Pcmap, &cs->fg_tint, 1, 0, True); cs->fg_tint = GetColor(fg_tint); } /* * ---------- change the foreground colour ---------- */ if (has_fg_changed || (has_bg_changed && (cs->color_flags & FG_CONTRAST))) { if (cs->color_flags & FG_CONTRAST) { Pixel old_fg = cs->fg; /* calculate contrasting foreground color */ color.pixel = cs->bg; XQueryColor(dpy, Pcmap, &color); color.red = (color.red > 32767) ? 0 : 65535; color.green = (color.green > 32767) ? 0 : 65535; color.blue = (color.blue > 32767) ? 0 : 65535; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); PictureAllocColor(dpy, Pcmap, &color, True); cs->fg = color.pixel; if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } /* contrast */ else if ((cs->color_flags & FG_SUPPLIED) && fg != NULL) { /* user specified colour */ Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = GetColor(fg); if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } /* user specified */ else if (fg == NULL) { /* default */ Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = GetColor(black); if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } /* save the fg color for tinting */ cs->fg_saved = cs->fg; } /* has_fg_changed */ /* * ---------- tint the foreground colour ---------- */ if (has_fg_tint_changed || (has_fg_changed && cs->fg_tint_percent > 0)) { if (cs->fg_tint_percent == 0) { Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = cs->fg_saved; if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } else { Pixel old_fg = cs->fg; PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True); cs->fg = GetTintedPixel( cs->fg_saved, cs->fg_tint, cs->fg_tint_percent); if (old_fg != cs->fg) { have_pixels_changed = True; has_fg_changed = 1; } } } /* * ---------- change the hilight colour ---------- */ if (has_hi_changed || (has_bg_changed && !(cs->color_flags & HI_SUPPLIED))) { has_hi_changed = 1; if ((cs->color_flags & HI_SUPPLIED) && hi != NULL) { /* user specified colour */ Pixel old_hilite = cs->hilite; PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True); cs->hilite = GetColor(hi); if (old_hilite != cs->hilite) { have_pixels_changed = True; } } /* user specified */ else if (hi == NULL) { Pixel old_hilite = cs->hilite; PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True); cs->hilite = GetHilite(cs->bg); if (old_hilite != cs->hilite) { have_pixels_changed = True; } } } /* has_hi_changed */ /* * ---------- change the shadow colour ---------- */ if (has_sh_changed || (has_bg_changed && !(cs->color_flags & SH_SUPPLIED))) { has_sh_changed = 1; if ((cs->color_flags & SH_SUPPLIED) && sh != NULL) { /* user specified colour */ Pixel old_shadow = cs->shadow; PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True); cs->shadow = GetColor(sh); if (old_shadow != cs->shadow) { have_pixels_changed = True; } } /* user specified */ else if (sh == NULL) { Pixel old_shadow = cs->shadow; PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True); cs->shadow = GetShadow(cs->bg); if (old_shadow != cs->shadow) { have_pixels_changed = True; } } } /* has_sh_changed */ /* * ---------- change the shadow foreground colour ---------- */ if (has_fgsh_changed || ((has_fg_changed || has_bg_changed) && !(cs->color_flags & FGSH_SUPPLIED))) { has_fgsh_changed = 1; if ((cs->color_flags & FGSH_SUPPLIED) && fgsh != NULL) { /* user specified colour */ Pixel old_fgsh = cs->fgsh; PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True); cs->fgsh = GetColor(fgsh); if (old_fgsh != cs->fgsh) { have_pixels_changed = True; } } /* user specified */ else if (fgsh == NULL) { Pixel old_fgsh = cs->fgsh; PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True); cs->fgsh = GetForeShadow(cs->fg, cs->bg); if (old_fgsh != cs->fgsh) { have_pixels_changed = True; } } } /* has_fgsh_changed */ /* * ------- the pixmap is a bitmap: create here cs->pixmap ------- */ if (cs->picture != None && pixmap_is_a_bitmap && (has_pixmap_changed || has_bg_changed)) { cs->pixmap = XCreatePixmap( dpy, win, cs->width, cs->height, Pdepth); XSetBackground(dpy, gc, cs->bg); XSetForeground(dpy, gc, cs->fg); reset_cs_pixmap(cs, gc); } /* * ------- change the masked out parts of the background pixmap ------- */ if (cs->pixmap != None && cs->pixmap != ParentRelative && (!CSETS_IS_TRANSPARENT_ROOT(cs)|| cs->allows_buffered_transparency) && (cs->mask != None || cs->alpha_pixmap != None || cs->image_alpha_percent < 100 || cs->tint_percent > 0) && (has_pixmap_changed || has_bg_changed || has_image_alpha_changed || has_tint_changed)) { /* Now that we know the background colour we can update the * pixmap background. */ FvwmRenderAttributes fra; Pixmap temp, mask, alpha; memset(&fra, 0, sizeof(fra)); temp = XCreatePixmap(dpy, win, cs->width, cs->height, Pdepth); if (cs->picture != NULL) { mask = cs->picture->mask; alpha = cs->picture->alpha; } else { mask = None; alpha = None; } XSetForeground(dpy, gc, cs->bg); XFillRectangle( dpy, temp, gc, 0, 0, cs->width, cs->height); fra.mask = FRAM_HAVE_ADDED_ALPHA | FRAM_HAVE_TINT; fra.added_alpha_percent = cs->image_alpha_percent; fra.tint = cs->tint; fra.tint_percent = cs->tint_percent; PGraphicsRenderPixmaps( dpy, win, cs->pixmap, mask, alpha, Pdepth, &fra, temp, gc, Scr.MonoGC, Scr.AlphaGC, 0, 0, cs->width, cs->height, 0, 0, cs->width, cs->height, False); if (cs->pixmap != root_pic.pixmap) { add_to_junk(cs->pixmap); } cs->pixmap = temp; has_pixmap_changed = True; if (CSETS_IS_TRANSPARENT_ROOT(cs)) { cs->pixmap_type = PIXMAP_ROOT_PIXMAP_TRAN; } } /* has_pixmap_changed */ /* * ---------- change the icon tint colour ---------- */ if (has_icon_tint_changed) { /* user specified colour */ if (icon_tint != NULL) { Pixel old_tint = cs->icon_tint; PictureFreeColors( dpy, Pcmap, &cs->icon_tint, 1, 0, True); cs->icon_tint = GetColor(icon_tint); if (old_tint != cs->icon_tint) { has_icon_pixels_changed = True; } } else { /* default */ Pixel old_tint = cs->icon_tint; PictureFreeColors( dpy, Pcmap, &cs->icon_tint, 1, 0, True); cs->icon_tint = GetColor(black); if (old_tint != cs->icon_tint) { has_icon_pixels_changed = True; } } } /* * ---------- send new colorset to fvwm and clean up ---------- */ /* make sure the server has this to avoid races */ XSync(dpy, False); /* inform modules of the change */ if (have_pixels_changed || has_pixmap_changed || has_shape_changed || has_fg_alpha_changed || has_icon_pixels_changed) { BroadcastColorset(n); } if (fg) { free(fg); } if (bg) { free(bg); } if (hi) { free(hi); } if (sh) { free(sh); } if (fgsh) { free(fgsh); } if (tint) { free(tint); } if (fg_tint) { free(fg_tint); } if (bg_tint) { free(bg_tint); } if (icon_tint) { free(icon_tint); } return; }
/* * * Looks for an application supplied icon window * */ void GetIconWindow(struct icon_info *item) { int x, y; unsigned int bw; Window Junkroot; if (!XGetGeometry( dpy, item->wmhints->icon_window, &Junkroot, &x, &y, (unsigned int *)&item->icon_w, (unsigned int *)&item->icon_h, &bw, (unsigned int *)&item->icon_depth)) { #if 0 fprintf(stderr, "[%s][GetIconWindow] WARN -- '%s' has an " "invalid icon window hint\n", MyName, item->name); #endif /* disable the icon window hint */ item->icon_w = 0; item->icon_h = 0; item->wmhints->icon_window = None; item->wmhints->flags &= ~IconWindowHint; return; } item->icon_pixmap_w = item->wmhints->icon_window; if (FShapesSupported && (item->wmhints->flags & IconMaskHint)) { SET_ICON_SHAPED(item, True); item->icon_maskPixmap = item->wmhints->icon_mask; } item->icon_w = min(max_icon_width + icon_relief, item->icon_w); item->icon_h = min(max_icon_height + icon_relief, item->icon_h); MyXGrabServer(dpy); do_allow_bad_access = True; XReparentWindow(dpy, item->icon_pixmap_w, icon_win, 0, 0); XSetWindowBorderWidth(dpy, item->icon_pixmap_w, 0); XSelectInput(dpy, item->icon_pixmap_w, ICON_EVENTS); XSync(dpy, 0); do_allow_bad_access = False; if (was_bad_access) { /* give up */ #if 0 fprintf(stderr, "[%s][GetIconWindow] WARN -- BadAcces when " "reparenting %s icon window\n", MyName, item->name); #endif XSelectInput(dpy, item->icon_pixmap_w, NoEventMask); XUnmapWindow(dpy, item->icon_pixmap_w); XReparentWindow(dpy, item->icon_pixmap_w, Root, 0, 0); XUnmapWindow(dpy, item->icon_pixmap_w); MyXUngrabServer(dpy); item->icon_pixmap_w = item->wmhints->icon_window = None; item->wmhints->flags &= ~IconWindowHint; item->icon_maskPixmap = None; item->icon_w = 0; item->icon_h = 0; was_bad_access = False; return; } MyXUngrabServer(dpy); SET_ICON_OURS(item, False); SET_PIXMAP_OURS(item, False); }
void focus_grab_buttons(FvwmWindow *tmp_win, Bool is_focused) { int i; Bool accepts_input_focus; Bool do_grab_window = False; unsigned char grab_buttons = Scr.buttons2grab; if (!tmp_win || IS_SCHEDULED_FOR_DESTROY(tmp_win)) { /* It's pointless to grab buttons on dying windows */ return; } accepts_input_focus = do_accept_input_focus(tmp_win); if (HAS_SLOPPY_FOCUS(tmp_win) || HAS_MOUSE_FOCUS(tmp_win) || HAS_NEVER_FOCUS(tmp_win)) { if (DO_RAISE_MOUSE_FOCUS_CLICK(tmp_win) && (!is_focused || !is_on_top_of_layer(tmp_win))) { grab_buttons = ((1 << NUMBER_OF_MOUSE_BUTTONS) - 1); do_grab_window = True; } } else if (HAS_CLICK_FOCUS(tmp_win)) { if (is_focused && !is_on_top_of_layer(tmp_win) && DO_NOT_RAISE_CLICK_FOCUS_CLICK(tmp_win) && accepts_input_focus) { /* don't grab */ } else if ((!is_focused || !is_on_top_of_layer(tmp_win)) && (!DO_NOT_RAISE_CLICK_FOCUS_CLICK(tmp_win) || accepts_input_focus)) { grab_buttons = ((1 << NUMBER_OF_MOUSE_BUTTONS) - 1); do_grab_window = True; } } #if 0 /* RBW - If we've come here to grab and all buttons are already grabbed, or to ungrab and none is grabbed, then we've nothing to do. */ if ((!is_focused && grab_buttons == tmp_win->grabbed_buttons) || (is_focused && ((tmp_win->grabbed_buttons & grab_buttons) == 0))) { return; } #else if (grab_buttons != tmp_win->grabbed_buttons) #endif { Bool do_grab; MyXGrabServer(dpy); Scr.Ungrabbed = (do_grab_window) ? NULL : tmp_win; for (i = 0; i < NUMBER_OF_MOUSE_BUTTONS; i++) { #if 0 /* RBW - Set flag for grab or ungrab according to how we were called. */ if (!is_focused||1) { do_grab = !!(grab_buttons & (1 << i)); } else { do_grab = !(grab_buttons & (1 << i)); } #else if ((grab_buttons & (1 << i)) == (tmp_win->grabbed_buttons & (1 << i))) continue; do_grab = !!(grab_buttons & (1 << i)); #endif { register unsigned int mods; register unsigned int max = GetUnusedModifiers(); register unsigned int living_modifiers = ~max; /* handle all bindings for the dead modifiers */ for (mods = 0; mods <= max; mods++) { /* Since mods starts with 1 we don't need to test if mods * contains a dead modifier. Otherwise both, dead and living * modifiers would be zero ==> mods == 0 */ if (!(mods & living_modifiers)) { if (do_grab) { XGrabButton( dpy, i + 1, mods, tmp_win->Parent, True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None); /* Set each FvwmWindow flag accordingly, as we grab or ungrab. */ tmp_win->grabbed_buttons |= (1<<i); } else { XUngrabButton(dpy, (i+1), mods, tmp_win->Parent); tmp_win->grabbed_buttons &= ~(1<<i); } } } /* for */ } } /* for */ MyXUngrabServer (dpy); } return; }
/****************************************************************************** AdjustWindow - Resize the window according to maxwidth by number of buttons ******************************************************************************/ void AdjustWindow(void) { int new_width=0,new_height=0,tw,i,total,off_x,off_y; char *temp; Window frame; XWindowAttributes win_attr, frame_attr; total = ItemCountD(&windows ); if (!total) { if (WindowIsUp==1) { XUnmapWindow(dpy,win); WindowIsUp=2; } return; } for(i=0; i<total; i++) { temp=ItemName(&windows,i); if(temp != NULL) { tw=10+XTextWidth(ButtonFont,temp,strlen(temp)); tw+=XTextWidth(ButtonFont,"()",2); #ifdef MINI_ICONS tw+=14; /* for title icon */ /* Magic Number ? */ #endif new_width=max(new_width,tw); } } new_width=max(new_width, MinWidth); new_width=min(new_width, MaxWidth); new_height=(total*(fontheight+6+1)); if (WindowIsUp && (new_height!=win_height || new_width!=win_width)) { if (Anchor) { off_x = off_y = 0; MyXGrabServer(dpy); frame = find_frame_window(win, &off_x, &off_y); XGetWindowAttributes(dpy, frame, &frame_attr); XGetWindowAttributes(dpy, win, &win_attr); win_x = frame_attr.x + frame_attr.border_width + off_x; win_y = frame_attr.y + frame_attr.border_width + off_y; if (win_grav == SouthEastGravity || win_grav == NorthEastGravity) win_x += win_attr.width - new_width; if (win_grav == SouthEastGravity || win_grav == SouthWestGravity) win_y += win_attr.height - new_height; XMoveResizeWindow(dpy, win, win_x, win_y, new_width, new_height); MyXUngrabServer(dpy); } else XResizeWindow(dpy, win, new_width, new_height); } UpdateArray(&buttons,-1,-1,new_width,-1); if (new_height>0) win_height = new_height; if (new_width>0) win_width = new_width; if (WindowIsUp==2) { XMapWindow(dpy,win); WindowIsUp=1; WaitForExpose(); } }
/*********************************************************************** * * Procedure: * HandleUnmapNotify - UnmapNotify event handler * ************************************************************************/ void HandleUnmapNotify() { int dstx, dsty; Window dumwin; XEvent dummy; extern FvwmWindow *colormap_win; int weMustUnmap; DBUG("HandleUnmapNotify","Routine Entered"); /* * Don't ignore events as described below. */ if((Event.xunmap.event != Event.xunmap.window) && (Event.xunmap.event != Scr.Root || !Event.xunmap.send_event)) { return; } /* * The July 27, 1988 ICCCM spec states that a client wishing to switch * to WithdrawnState should send a synthetic UnmapNotify with the * event field set to (pseudo-)root, in case the window is already * unmapped (which is the case for fvwm for IconicState). Unfortunately, * we looked for the FvwmContext using that field, so try the window * field also. */ weMustUnmap = 0; if (!Tmp_win) { Event.xany.window = Event.xunmap.window; weMustUnmap = 1; if (XFindContext(dpy, Event.xany.window, FvwmContext, (caddr_t *)&Tmp_win) == XCNOENT) Tmp_win = NULL; } if(!Tmp_win) return; if(weMustUnmap) XUnmapWindow(dpy, Event.xunmap.window); if(Tmp_win == Scr.Hilite) Scr.Hilite = NULL; if(Scr.PreviousFocus == Tmp_win) Scr.PreviousFocus = NULL; if((Tmp_win == Scr.Focus)&&(Tmp_win->flags & ClickToFocus)) { if(Tmp_win->next) { HandleHardFocus(Tmp_win->next); } else SetFocus(Scr.NoFocusWin,NULL,1); } if(Scr.Focus == Tmp_win) SetFocus(Scr.NoFocusWin,NULL,1); if(Tmp_win == Scr.pushed_window) Scr.pushed_window = NULL; if(Tmp_win == colormap_win) colormap_win = NULL; if ((!(Tmp_win->flags & MAPPED)&&!(Tmp_win->flags&ICONIFIED))) { return; } MyXGrabServer(dpy); if(XCheckTypedWindowEvent (dpy, Event.xunmap.window, DestroyNotify,&dummy)) { Destroy(Tmp_win); MyXUngrabServer (dpy); return; } /* * The program may have unmapped the client window, from either * NormalState or IconicState. Handle the transition to WithdrawnState. * * We need to reparent the window back to the root (so that fvwm exiting * won't cause it to get mapped) and then throw away all state (pretend * that we've received a DestroyNotify). */ if (XTranslateCoordinates (dpy, Event.xunmap.window, Scr.Root, 0, 0, &dstx, &dsty, &dumwin)) { XEvent ev; Bool reparented; reparented = XCheckTypedWindowEvent (dpy, Event.xunmap.window, ReparentNotify, &ev); SetMapStateProp (Tmp_win, WithdrawnState); if (reparented) { if (Tmp_win->old_bw) XSetWindowBorderWidth (dpy, Event.xunmap.window, Tmp_win->old_bw); if((!(Tmp_win->flags & SUPPRESSICON))&& (Tmp_win->wmhints && (Tmp_win->wmhints->flags & IconWindowHint))) XUnmapWindow (dpy, Tmp_win->wmhints->icon_window); } else { RestoreWithdrawnLocation (Tmp_win,False); } XRemoveFromSaveSet (dpy, Event.xunmap.window); XSelectInput (dpy, Event.xunmap.window, NoEventMask); Destroy(Tmp_win); /* do not need to mash event before */ /* * Flush any pending events for the window. */ /* Bzzt! it could be about to re-map */ /* while(XCheckWindowEvent(dpy, Event.xunmap.window, StructureNotifyMask | PropertyChangeMask | ColormapChangeMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask, &dummy)); */ } /* else window no longer exists and we'll get a destroy notify */ MyXUngrabServer(dpy); XFlush (dpy); }
/*********************************************************************** * * Procedure: * HandleMapNotify - MapNotify event handler * ***********************************************************************/ void HandleMapNotify() { Boolean OnThisPage = False; DBUG("HandleMapNotify","Routine Entered"); if (!Tmp_win) { if((Event.xmap.override_redirect == True)&& (Event.xmap.window != Scr.NoFocusWin)) { XSelectInput(dpy,Event.xmap.window,FocusChangeMask); Scr.UnknownWinFocused = Event.xmap.window; } return; } /* Except for identifying over-ride redirect window mappings, we * don't need or want windows associated with the sunstructurenotifymask */ if(Event.xmap.event != Event.xmap.window) return; /* Make sure at least part of window is on this page before giving it focus... */ if ( (Tmp_win->Desk == Scr.CurrentDesk) && ( ((Tmp_win->frame_x + Tmp_win->frame_width) >= 0 && Tmp_win->frame_x < Scr.MyDisplayWidth) && ((Tmp_win->frame_y + Tmp_win->frame_height) >= 0 && Tmp_win->frame_y < Scr.MyDisplayHeight) ) ) { OnThisPage = True; } /* * Need to do the grab to avoid race condition of having server send * MapNotify to client before the frame gets mapped; this is bad because * the client would think that the window has a chance of being viewable * when it really isn't. */ MyXGrabServer (dpy); if (Tmp_win->icon_w) XUnmapWindow(dpy, Tmp_win->icon_w); if(Tmp_win->icon_pixmap_w != None) XUnmapWindow(dpy, Tmp_win->icon_pixmap_w); XMapSubwindows(dpy, Tmp_win->frame); if(Tmp_win->Desk == Scr.CurrentDesk) { XMapWindow(dpy, Tmp_win->frame); } if(Tmp_win->flags & ICONIFIED) BroadcastPacket(M_DEICONIFY, 3, Tmp_win->w, Tmp_win->frame, (unsigned long)Tmp_win); else BroadcastPacket(M_MAP, 3, Tmp_win->w,Tmp_win->frame, (unsigned long)Tmp_win); if((Tmp_win->flags & ClickToFocus)&& ((!Scr.Focus)||(Scr.Focus->flags & ClickToFocus))) { if (OnThisPage) { SetFocus(Tmp_win->w,Tmp_win,1); } } if((!(Tmp_win->flags &(BORDER|TITLE)))&&(Tmp_win->boundary_width <2)) { SetBorder(Tmp_win,False,True,True,Tmp_win->frame); } XSync(dpy,0); MyXUngrabServer (dpy); XFlush (dpy); Tmp_win->flags |= MAPPED; Tmp_win->flags &= ~MAP_PENDING; Tmp_win->flags &= ~ICONIFIED; Tmp_win->flags &= ~ICON_UNMAPPED; KeepOnTop(); }
void HandleMapRequestKeepRaised(Window KeepRaised) { extern long isIconicState; extern Boolean PPosOverride; Boolean OnThisPage = False; Event.xany.window = Event.xmaprequest.window; if(XFindContext(dpy, Event.xany.window, FvwmContext, (caddr_t *)&Tmp_win)==XCNOENT) Tmp_win = NULL; if(!PPosOverride) XFlush(dpy); /* If the window has never been mapped before ... */ if(!Tmp_win) { /* Add decorations. */ Tmp_win = AddWindow(Event.xany.window); if (Tmp_win == NULL) return; } /* Make sure at least part of window is on this page before giving it focus... */ if ( (Tmp_win->Desk == Scr.CurrentDesk) && ( ((Tmp_win->frame_x + Tmp_win->frame_width) >= 0 && Tmp_win->frame_x < Scr.MyDisplayWidth) && ((Tmp_win->frame_y + Tmp_win->frame_height) >= 0 && Tmp_win->frame_y < Scr.MyDisplayHeight) ) ) { OnThisPage = True; } if(KeepRaised != None) XRaiseWindow(dpy,KeepRaised); /* If it's not merely iconified, and we have hints, use them. */ if (!(Tmp_win->flags & ICONIFIED)) { int state; if(Tmp_win->wmhints && (Tmp_win->wmhints->flags & StateHint)) state = Tmp_win->wmhints->initial_state; else state = NormalState; if(Tmp_win->flags & STARTICONIC) state = IconicState; if(isIconicState != DontCareState) state = isIconicState; MyXGrabServer(dpy); switch (state) { case DontCareState: case NormalState: case InactiveState: default: if (Tmp_win->Desk == Scr.CurrentDesk) { XMapWindow(dpy, Tmp_win->w); XMapWindow(dpy, Tmp_win->frame); Tmp_win->flags |= MAP_PENDING; SetMapStateProp(Tmp_win, NormalState); if((Tmp_win->flags & ClickToFocus)&& ((!Scr.Focus)||(Scr.Focus->flags & ClickToFocus))) { if (OnThisPage) { SetFocus(Tmp_win->w,Tmp_win,1); } } } else { XMapWindow(dpy, Tmp_win->w); SetMapStateProp(Tmp_win, NormalState); } break; case IconicState: if (Tmp_win->wmhints) { Iconify(Tmp_win, Tmp_win->wmhints->icon_x, Tmp_win->wmhints->icon_y); } else { Iconify(Tmp_win, 0, 0); } break; } if(!PPosOverride) XSync(dpy,0); MyXUngrabServer(dpy); } /* If no hints, or currently an icon, just "deiconify" */ else { DeIconify(Tmp_win); } if(!PPosOverride) KeepOnTop(); }