void KWD::Decorator::updateShadow (void) { Display *xdisplay = QX11Info::display (); Screen *xscreen; decor_context_t context; xscreen = ScreenOfDisplay (xdisplay, QX11Info::appScreen ()); if (mNoBorderShadow) decor_shadow_destroy (xdisplay, mNoBorderShadow); mNoBorderShadow = decor_shadow_create (xdisplay, xscreen, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, &mActiveShadowOptions, &context, decor_draw_simple, 0); if (mNoBorderShadow) { decor_extents_t extents = { 0, 0, 0, 0 }; long *data; unsigned int n = 1, frame_type = 0, frame_state = 0, frame_actions = 0; decor_quad_t quads[N_QUADS_MAX]; int nQuad; decor_layout_t layout; decor_get_default_layout (&context, 1, 1, &layout); nQuad = decor_set_lSrStSbS_window_quads (quads, &context, &layout); data = decor_alloc_property (n, WINDOW_DECORATION_TYPE_PIXMAP); decor_quads_to_property (data, n - 1, mNoBorderShadow->pixmap, &extents, &extents, &extents, &extents, 0, 0, quads, nQuad, frame_type, frame_state, frame_actions); KWD::trapXError (); XChangeProperty (QX11Info::display (), QX11Info::appRootWindow (), Atoms::netWindowDecorBare, XA_INTEGER, 32, PropModeReplace, (unsigned char *) data, PROP_HEADER_SIZE + BASE_PROP_SIZE + QUAD_PROP_SIZE * N_QUADS_MAX); KWD::popXError (); free (data); } }
void KWD::Switcher::updateGeometry () { int x, y; unsigned int width, height, border, depth; XID root; XGetGeometry (QX11Info::display (), mId, &root, &x, &y, &width, &height, &border, &depth); mGeometry = QRect (x, y, width, height); KWD::readWindowProperty (mId, Atoms::switchSelectWindow, (long *)&mSelected); if (mX11Pixmap) XFreePixmap (QX11Info::display (), mX11Pixmap); if (mX11BackgroundPixmap) XFreePixmap (QX11Info::display (), mX11BackgroundPixmap); mX11Pixmap = XCreatePixmap (QX11Info::display (), QX11Info::appRootWindow (), width + mBorder.left + mBorder.right, height + mBorder.top + mBorder.bottom, 32); mX11BackgroundPixmap = XCreatePixmap (QX11Info::display (), QX11Info::appRootWindow (), width, height, 32); mPixmap = QPixmap::fromX11Pixmap (mX11Pixmap, QPixmap::ExplicitlyShared); mBackgroundPixmap = QPixmap::fromX11Pixmap (mX11BackgroundPixmap, QPixmap::ExplicitlyShared); redrawPixmap (); update (); decor_get_default_layout (&mContext, mGeometry.width (), mGeometry.height (), &mDecorLayout); updateWindowProperties (); }
/* * draw_border_shape * Returns: void * Description: Draws a slight border around the decoration */ static void draw_border_shape (Display *xdisplay, Pixmap pixmap, Picture picture, int width, int height, decor_context_t *c, void *closure) { static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; decor_t d; decor_shadow_info_t *info = (decor_shadow_info_t *) closure; double save_decoration_alpha; GdkScreen *screen; memset (&d, 0, sizeof (d)); if (info) { gwd_decor_frame_ref (info->frame); d.frame = info->frame; d.state = info->state; d.actions = info->active; } else { d.frame = gwd_get_decor_frame ("normal"); d.state = 0; d.active = TRUE; } screen = gdk_screen_get_default (); d.surface = cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (screen), pixmap, GDK_VISUAL_XVISUAL (gdk_screen_get_rgba_visual (screen)), width, height); d.width = width; d.height = height; d.active = TRUE; d.draw = theme_draw_window_decoration; d.picture = picture; d.context = c; /* we use closure argument if maximized */ if (info) d.state = info->state; else d.state = 0; decor_get_default_layout (c, 1, 1, &d.border_layout); /* create shadow from opaque decoration * FIXME: Should not modify settings value * like this */ save_decoration_alpha = decoration_alpha; decoration_alpha = 1.0; (*d.draw) (&d); decoration_alpha = save_decoration_alpha; XRenderFillRectangle (xdisplay, PictOpSrc, picture, &white, c->left_space, c->top_space, width - c->left_space - c->right_space, height - c->top_space - c->bottom_space); if (!info) gwd_decor_frame_unref (d.frame); cairo_surface_destroy (d.surface); }
/* * update_default_decorations * * Description: update the default decorations */ void update_default_decorations (GdkScreen *screen) { long *data; Window xroot; GdkDisplay *gdkdisplay = gdk_display_get_default (); Display *xdisplay = gdk_x11_display_get_xdisplay (gdkdisplay); Atom bareAtom, activeAtom; decor_frame_t *frame; decor_frame_t *bare_frame = gwd_get_decor_frame ("bare"); decor_extents_t extents; unsigned int i; xroot = RootWindowOfScreen (gdk_x11_screen_get_xscreen (screen)); bareAtom = XInternAtom (xdisplay, DECOR_BARE_ATOM_NAME, FALSE); activeAtom = XInternAtom (xdisplay, DECOR_ACTIVE_ATOM_NAME, FALSE); if (bare_frame->border_shadow_active) { decor_layout_t layout; unsigned int frame_type = 0; unsigned int frame_state = 0; unsigned int frame_actions = 0; unsigned int nQuad; decor_quad_t quads[N_QUADS_MAX]; long *data = decor_alloc_property (1, WINDOW_DECORATION_TYPE_PIXMAP); decor_get_default_layout (&bare_frame->window_context_active, 1, 1, &layout); nQuad = decor_set_lSrStSbS_window_quads (quads, &bare_frame->window_context_active, &layout); decor_quads_to_property (data, 0, bare_frame->border_shadow_active->pixmap, &bare_frame->win_extents, &bare_frame->win_extents, &bare_frame->win_extents, &bare_frame->win_extents, 0, 0, quads, nQuad, frame_type, frame_state, frame_actions); XChangeProperty (xdisplay, xroot, bareAtom, XA_INTEGER, 32, PropModeReplace, (guchar *) data, PROP_HEADER_SIZE + BASE_PROP_SIZE + QUAD_PROP_SIZE * N_QUADS_MAX); if (minimal) { XChangeProperty (xdisplay, xroot, activeAtom, XA_INTEGER, 32, PropModeReplace, (guchar *) data, PROP_HEADER_SIZE + BASE_PROP_SIZE + QUAD_PROP_SIZE * N_QUADS_MAX); } free (data); } else { XDeleteProperty (xdisplay, xroot, bareAtom); if (minimal) { XDeleteProperty (xdisplay, xroot, activeAtom); } } if (minimal) { gwd_decor_frame_unref (bare_frame); return; } XDeleteProperty (xdisplay, xroot, activeAtom); data = decor_alloc_property (WINDOW_TYPE_FRAMES_NUM * 2, WINDOW_DECORATION_TYPE_PIXMAP); /* All active states and all inactive states */ for (i = 0; i < WINDOW_TYPE_FRAMES_NUM * 2; ++i) { frame = gwd_get_decor_frame (default_frames[i].name); extents = frame->win_extents; if (default_frames[i].d) { if (default_frames[i].d->surface) cairo_surface_destroy (default_frames[i].d->surface); free (default_frames[i].d); } default_frames[i].d = calloc (1, sizeof (decor_t)); default_frames[i].d->context = i < WINDOW_TYPE_FRAMES_NUM ? &frame->window_context_active : &frame->window_context_inactive; default_frames[i].d->shadow = i < WINDOW_TYPE_FRAMES_NUM ? frame->border_shadow_active : frame->border_shadow_inactive; default_frames[i].d->layout = pango_layout_new (frame->pango_context); decor_get_default_layout (default_frames[i].d->context, 1, 1, &default_frames[i].d->border_layout); default_frames[i].d->width = default_frames[i].d->border_layout.width; default_frames[i].d->height = default_frames[i].d->border_layout.height; default_frames[i].d->frame = frame; default_frames[i].d->active = i < WINDOW_TYPE_FRAMES_NUM ? TRUE : FALSE; extents.top += frame->titlebar_height; default_frames[i].d->draw = theme_draw_window_decoration; default_frames[i].d->surface = create_native_surface_and_wrap (default_frames[i].d->width, default_frames[i].d->height, frame->style_window_rgba); unsigned int j, k; for (j = 0; j < 3; ++j) { for (k = 0; k < 3; k++) { default_frames[i].d->event_windows[j][k].window = None; } } for (j = 0; j < BUTTON_NUM; ++j) { default_frames[i].d->button_windows[j].window = None; default_frames[i].d->button_states[j] = 0; } if (default_frames[i].d->surface) { gint nQuad; unsigned int frame_type = populate_frame_type (default_frames[i].d); unsigned int frame_state = populate_frame_state (default_frames[i].d); unsigned int frame_actions = populate_frame_actions (default_frames[i].d); decor_quad_t quads[N_QUADS_MAX]; nQuad = decor_set_lSrStSbS_window_quads (quads, default_frames[i].d->context, &default_frames[i].d->border_layout); default_frames[i].d->picture = XRenderCreatePicture (xdisplay, cairo_xlib_surface_get_drawable (default_frames[i].d->surface), xformat_rgba, 0, NULL); (*default_frames[i].d->draw) (default_frames[i].d); decor_quads_to_property (data, i, cairo_xlib_surface_get_drawable (default_frames[i].d->surface), &extents, &extents, &extents, &extents, 0, 0, quads, nQuad, frame_type, frame_state, frame_actions); } gwd_decor_frame_unref (frame); } XChangeProperty (xdisplay, xroot, activeAtom, XA_INTEGER, 32, PropModeAppend, (guchar *) data, PROP_HEADER_SIZE + (WINDOW_TYPE_FRAMES_NUM * 2) * (BASE_PROP_SIZE + QUAD_PROP_SIZE * N_QUADS_MAX)); free (data); gwd_decor_frame_unref (bare_frame); }
gboolean meta_calc_decoration_size (decor_t *d, gint w, gint h, gint name_width, gint *width, gint *height) { decor_layout_t layout; decor_context_t *context; decor_shadow_t *shadow; if (!d->decorated) return FALSE; if ((d->state & META_MAXIMIZED) == META_MAXIMIZED) { if (!d->frame_window) { if (d->active) { context = &d->frame->max_window_context_active; shadow = d->frame->max_border_shadow_active; } else { context = &d->frame->max_window_context_inactive; shadow = d->frame->max_border_shadow_inactive; } } else { context = &d->frame->max_window_context_no_shadow; shadow = d->frame->max_border_no_shadow; } } else { if (!d->frame_window) { if (d->active) { context = &d->frame->window_context_active; shadow = d->frame->border_shadow_active; } else { context = &d->frame->window_context_inactive; shadow = d->frame->border_shadow_inactive; } } else { context = &d->frame->window_context_no_shadow; shadow = d->frame->border_no_shadow; } } if (!d->frame_window) { decor_get_best_layout (context, w, h, &layout); if (context != d->context || memcmp (&layout, &d->border_layout, sizeof (layout))) { *width = layout.width; *height = layout.height; d->border_layout = layout; d->context = context; d->shadow = shadow; meta_calc_button_size (d); return TRUE; } } else { if ((d->state & META_MAXIMIZED) == META_MAXIMIZED) decor_get_default_layout (context, d->client_width, d->client_height - d->frame->titlebar_height, &layout); else decor_get_default_layout (context, d->client_width, d->client_height, &layout); *width = layout.width; *height = layout.height; d->border_layout = layout; d->shadow = shadow; d->context = context; meta_calc_button_size (d); return TRUE; } return FALSE; }
/* * draw_border_shape * Returns: void * Description: Draws a slight border around the decoration */ static void draw_border_shape (Display *xdisplay, Pixmap pixmap, Picture picture, int width, int height, decor_context_t *c, void *closure) { static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; GdkColormap *colormap; decor_t d; decor_shadow_info_t *info = (decor_shadow_info_t *) closure; double save_decoration_alpha; memset (&d, 0, sizeof (d)); if (info) { gwd_decor_frame_ref (info->frame); d.frame = info->frame; d.state = info->state; d.actions = info->active; } else { d.frame = gwd_get_decor_frame ("normal"); d.state = 0; d.active = TRUE; } d.pixmap = gdk_pixmap_foreign_new_for_display (gdk_display_get_default (), pixmap); d.width = width; d.height = height; d.active = TRUE; d.draw = theme_draw_window_decoration; d.picture = picture; d.context = c; /* we use closure argument if maximized */ if (info) d.state = info->state; else d.state = 0; decor_get_default_layout (c, 1, 1, &d.border_layout); colormap = get_colormap_for_drawable (GDK_DRAWABLE (d.pixmap)); gdk_drawable_set_colormap (d.pixmap, colormap); /* create shadow from opaque decoration * FIXME: Should not modify settings value * like this */ save_decoration_alpha = decoration_alpha; decoration_alpha = 1.0; (*d.draw) (&d); decoration_alpha = save_decoration_alpha; XRenderFillRectangle (xdisplay, PictOpSrc, picture, &white, c->left_space, c->top_space, width - c->left_space - c->right_space, height - c->top_space - c->bottom_space); if (!info) gwd_decor_frame_unref (d.frame); g_object_unref (G_OBJECT (d.pixmap)); }