Esempio n. 1
0
File: line.c Progetto: rbuj/emerald
void engine_draw_frame (decor_t * d, cairo_t * cr)
{
    frame_settings *fs = d->fs;
    private_fs *pfs = fs->engine_fs;
    window_settings *ws = fs->ws;

    double x1, y1, x2, y2;

    x1 = ws->left_space - ws->win_extents.left;
    y1 = ws->top_space - ws->win_extents.top;
    x2 = d->width  - ws->right_space  + ws->win_extents.right;
    y2 = d->height - ws->bottom_space + ws->win_extents.bottom;
	int top;
	top = ws->win_extents.top + ws->titlebar_height;

	double m1 = MIN(ws->win_extents.left, ws->win_extents.right);
	double m2 = MIN(ws->win_extents.top,  ws->win_extents.bottom);

	double border_width = MIN(m1, m2);
	double border_offset = border_width/2.0;

    cairo_set_line_width (cr, border_width);

	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);

    rounded_rectangle (cr,
            x1 + border_offset,
			y1 + top - border_offset,
            x2 - x1 - border_width,
			y2 - y1 - top,
            0, ws, 0);
	cairo_set_source_alpha_color(cr, &pfs->border);
	cairo_stroke (cr);

	/* title bar */
	if (pfs->title_bar.alpha != 0.0) {
		rounded_rectangle (cr,
				x1,
				y1,
				x2 - x1,
				top,
				0, ws, 0);
		cairo_set_source_alpha_color(cr, &pfs->title_bar);
		cairo_fill(cr);
	} else {
		cairo_save(cr);
		cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
		cairo_rectangle (cr, 0.0, 0.0, d->width, top + y1 - border_width);
		cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
		cairo_fill(cr);
		cairo_restore(cr);

/* FIXME => find a proper solution for this */
#ifdef SHADOW_FIX
		cairo_rectangle (cr, 0.0, 0.0, d->width, top + y1 - border_width);
		cairo_clip(cr);
		cairo_translate(cr, 0.0, ws->top_space + ws->win_extents.top);
		draw_shadow_background(d, cr);
		cairo_translate(cr, 0.0, -ws->top_space - ws->win_extents.top);
#endif
	}
}
Esempio n. 2
0
void
meta_draw_window_decoration (decor_t *d)
{
    Display	      *xdisplay =
	GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
    cairo_surface_t *surface;
    Picture	      src;
    MetaButtonState   button_states [META_BUTTON_TYPE_LAST];
    MetaButtonLayout  button_layout;
    MetaFrameGeometry fgeom;
    MetaFrameFlags    flags;
    MetaFrameType     frame_type;
    MetaTheme	      *theme;
    GtkStyleContext *context;
    cairo_t	      *cr;
    gint	      i;
    GdkRectangle      clip;
    Region	      top_region = NULL;
    Region	      bottom_region = NULL;
    Region	      left_region = NULL;
    Region	      right_region = NULL;
    gdouble	      meta_active_opacity, meta_inactive_opacity;
    gboolean	      meta_active_shade_opacity, meta_inactive_shade_opacity;

    g_object_get (settings, "metacity-active-opacity", &meta_active_opacity, NULL);
    g_object_get (settings, "metacity-inactive-opacity", &meta_inactive_opacity, NULL);
    g_object_get (settings, "metacity-active-shade-opacity", &meta_active_shade_opacity, NULL);
    g_object_get (settings, "metacity-inactive-shade-opacity", &meta_inactive_shade_opacity, NULL);

    double	      alpha = (d->active) ? meta_active_opacity : meta_inactive_opacity;
    gboolean	      shade_alpha = (d->active) ? meta_active_shade_opacity :
						  meta_inactive_shade_opacity;
    MetaFrameStyle    *frame_style;
    GtkWidget	      *style_window;
    GdkRGBA           bg_rgba;

    if (!d->surface || !d->picture)
	return;

    if (decoration_alpha == 1.0)
	alpha = 1.0;

    if (cairo_xlib_surface_get_depth (d->surface) == 32)
    {
	context = gtk_widget_get_style_context (d->frame->style_window_rgba);
	style_window = d->frame->style_window_rgba;
    }
    else
    {
	context = gtk_widget_get_style_context (d->frame->style_window_rgb);
	style_window = d->frame->style_window_rgb;
    }

    cr = cairo_create (d->buffer_surface ? d->buffer_surface : d->surface);

    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);

    theme = meta_theme_get_current ();

    frame_type = meta_frame_type_from_string (d->frame->type);

    if (frame_type == META_FRAME_TYPE_LAST)
	frame_type = META_FRAME_TYPE_NORMAL;

    meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
				  frame_type, &clip);

    if ((d->prop_xid || !d->buffer_surface) && !d->frame_window)
	draw_shadow_background (d, cr, d->shadow, d->context);

    for (i = 0; i < META_BUTTON_TYPE_LAST; ++i)
	button_states[i] = meta_button_state_for_button_type (d, i);

    frame_style = meta_theme_get_frame_style (theme,
					      frame_type,
					      flags);

    gtk_style_context_get_background_color (context, GTK_STATE_FLAG_NORMAL, &bg_rgba);
    bg_rgba.alpha = 1.0;

    if (frame_style->window_background_color)
    {
	meta_color_spec_render (frame_style->window_background_color,
				gtk_widget_get_style_context (style_window),
				&bg_rgba);

	bg_rgba.alpha = frame_style->window_background_alpha / 255.0;
    }

    /* Draw something that will be almost invisible to user. This is hacky way
     * to fix invisible decorations. */
    cairo_set_source_rgba (cr, 0, 0, 0, 0.01);
    cairo_rectangle (cr, 0, 0, 1, 1);
    cairo_fill (cr);
    /* ------------ */

    cairo_destroy (cr);

	if (d->frame_window)
	    surface = create_surface (clip.width, clip.height, d->frame->style_window_rgb);
	else
	    surface = create_surface (clip.width, clip.height, d->frame->style_window_rgba);

	cr = cairo_create (surface);
	gdk_cairo_set_source_rgba (cr, &bg_rgba);
	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);

	src = XRenderCreatePicture (xdisplay, cairo_xlib_surface_get_drawable (surface),
                                get_format_for_surface (d, surface), 0, NULL);

    cairo_paint (cr);
    meta_theme_draw_frame (theme,
                           style_window,
                           cr,
                           frame_type,
                           flags,
                           clip.width - fgeom.left_width - fgeom.right_width,
                           clip.height - fgeom.top_height - fgeom.bottom_height,
                           d->layout,
                           d->frame->text_height,
                           &button_layout,
                           button_states,
                           d->icon_pixbuf,
                           NULL);

    if (fgeom.top_height)
	{
	    top_region = meta_get_top_border_region (&fgeom, clip.width);

	    decor_blend_border_picture (xdisplay,
					d->context,
					src,
					0, 0,
					d->picture,
					&d->border_layout,
					BORDER_TOP,
					top_region,
					alpha * 0xffff,
					shade_alpha,
				        0);
	}

	if (fgeom.bottom_height)
	{
	    bottom_region = meta_get_bottom_border_region (&fgeom, clip.width);

	    decor_blend_border_picture (xdisplay,
					d->context,
					src,
					0, clip.height - fgeom.bottom_height,
					d->picture,
					&d->border_layout,
					BORDER_BOTTOM,
					bottom_region,
					alpha * 0xffff,
					shade_alpha,
					0);

	}

	if (fgeom.left_width)
	{
	    left_region = meta_get_left_border_region (&fgeom, clip.height);

	    decor_blend_border_picture (xdisplay,
					d->context,
					src,
					0, fgeom.top_height,
					d->picture,
					&d->border_layout,
					BORDER_LEFT,
					left_region,
					alpha * 0xffff,
					shade_alpha,
				        0);
	}

	if (fgeom.right_width)
	{
	    right_region = meta_get_right_border_region (&fgeom, clip.height);

	    decor_blend_border_picture (xdisplay,
					d->context,
					src,
					clip.width - fgeom.right_width, fgeom.top_height,
					d->picture,
					&d->border_layout,
					BORDER_RIGHT,
					right_region,
					alpha * 0xffff,
					shade_alpha,
				        0);
	}

	cairo_destroy (cr);
	cairo_surface_destroy (surface);
	XRenderFreePicture (xdisplay, src);

    copy_to_front_buffer (d);

    if (d->frame_window)
    {
	GdkWindow *gdk_frame_window = gtk_widget_get_window (d->decor_window);
	GdkPixbuf *pixbuf = gdk_pixbuf_get_from_surface (d->surface, 0, 0, d->width, d->height);

	gtk_image_set_from_pixbuf (GTK_IMAGE (d->decor_image), pixbuf);
	g_object_unref (pixbuf);

	gtk_window_resize (GTK_WINDOW (d->decor_window), d->width, d->height);
	gdk_window_move (gdk_frame_window,
			 d->context->left_corner_space - 1,
			 d->context->top_corner_space - 1);
	gdk_window_lower (gdk_frame_window);
    }

    if (d->prop_xid)
    {
	/* translate from frame to client window space */
	if (top_region)
	    XOffsetRegion (top_region, -fgeom.left_width, -fgeom.top_height);
	if (bottom_region)
	    XOffsetRegion (bottom_region, -fgeom.left_width, 0);
	if (left_region)
	    XOffsetRegion (left_region, -fgeom.left_width, 0);

	decor_update_meta_window_property (d, theme, flags,
					   top_region,
					   bottom_region,
					   left_region,
					   right_region);
	d->prop_xid = 0;
    }

    if (top_region)
	XDestroyRegion (top_region);
    if (bottom_region)
	XDestroyRegion (bottom_region);
    if (left_region)
	XDestroyRegion (left_region);
    if (right_region)
	XDestroyRegion (right_region);
}