Esempio n. 1
0
static void clonePreparePaintScreen(CompScreen * s, int msSinceLastPaint)
{
	int i;

	CLONE_SCREEN(s);

	if (cs->grab) {
		if (cs->grabIndex) {
			cs->offset -= msSinceLastPaint * 0.005f;
			if (cs->offset < 0.0f)
				cs->offset = 0.0f;
		} else {
			cs->offset += msSinceLastPaint * 0.005f;
			if (cs->offset >= 1.0f)
				cs->offset = 1.0f;
		}
	}

	UNWRAP(cs, s, preparePaintScreen);
	(*s->preparePaintScreen) (s, msSinceLastPaint);
	WRAP(cs, s, preparePaintScreen, clonePreparePaintScreen);

	for (i = 0; i < cs->nClone; i++) {
		CompOutput *src = &s->outputDev[cs->clone[i].src];
		CompOutput *dst = &s->outputDev[cs->clone[i].dst];
		int dx, dy;

		dx = dst->region.extents.x1 - src->region.extents.x1;
		dy = dst->region.extents.y1 - src->region.extents.y1;

		if (s->damageMask & COMP_SCREEN_DAMAGE_REGION_MASK) {
			if (src->width != dst->width
			    || src->height != dst->height) {
				XSubtractRegion(&dst->region, &emptyRegion,
						cs->clone[i].region);
				XUnionRegion(s->damage, cs->clone[i].region,
					     s->damage);
				XSubtractRegion(&src->region, &emptyRegion,
						cs->clone[i].region);
			} else {
				XSubtractRegion(s->damage, &dst->region,
						cs->clone[i].region);
				XOffsetRegion(cs->clone[i].region, dx, dy);
				XUnionRegion(s->damage, cs->clone[i].region,
					     s->damage);
				XSubtractRegion(s->damage, &src->region,
						cs->clone[i].region);
				XOffsetRegion(cs->clone[i].region, -dx, -dy);
			}
		} else {
			XSubtractRegion(&src->region, &emptyRegion,
					cs->clone[i].region);
		}
	}
}
Esempio n. 2
0
static void
minSetShade (CompWindow *w,
             int        shade)
{
	REGION rect;
	int    h = w->attrib.height + w->attrib.border_width * 2;

	MIN_WINDOW (w);

	EMPTY_REGION (w->region);

	rect.rects = &rect.extents;
	rect.numRects = rect.size = 1;

	w->height = shade;

	rect.extents.x1 = 0;
	rect.extents.y1 = h - shade;
	rect.extents.x2 = w->width;
	rect.extents.y2 = h;

	XIntersectRegion (mw->region, &rect, w->region);
	XOffsetRegion (w->region, w->attrib.x, w->attrib.y - (h - shade));

	w->matrix = w->texture->matrix;
	w->matrix.x0 -= (w->attrib.x * w->matrix.xx);
	w->matrix.y0 -= ((w->attrib.y - (h - shade)) * w->matrix.yy);

	(*w->screen->windowResizeNotify) (w, 0, 0, 0, 0);
}
Esempio n. 3
0
Bool
apc_region_combine( Handle self, Handle other_region, int rgnop)
{
	PRegionSysData r2;
	int d;
	Bool ok = true;

	r2 = GET_REGION(other_region);

	if ( rgnop == rgnopCopy ) {
		if ( REGION ) XDestroyRegion( REGION );
		REGION = XCreateRegion();
		XUnionRegion( REGION, r2->region, REGION);
		HEIGHT = r2-> height;
		return true;
	}

	d = HEIGHT - r2-> height;
	if ( d > 0 )
		XOffsetRegion( r2-> region, 0, d);
	else
		XOffsetRegion( REGION, 0, -d);

	switch (rgnop) {
	case rgnopIntersect:
		XIntersectRegion( REGION, r2->region, REGION);
		break;
	case rgnopUnion:
		XUnionRegion( REGION, r2->region, REGION);
		break;
	case rgnopXor:
		XXorRegion( REGION, r2->region, REGION);
		break;
	case rgnopDiff:
		XSubtractRegion( REGION, r2->region, REGION);
		break;
	default:
		ok = false;
	}
	if ( d > 0 )
		XOffsetRegion( r2-> region, 0, -d);
	else
		HEIGHT = r2-> height;

	return ok;
}
Esempio n. 4
0
// Offset region by dx,dy
FXRegion& FXRegion::offset(FXint dx,FXint dy){
#ifdef WIN32
  OffsetRgn((HRGN)region,dx,dy);
#else
  XOffsetRegion((Region)region,dx,dy);
#endif
  return *this;
  }
Esempio n. 5
0
Bool
apc_gp_set_region( Handle self, Handle rgn)
{
	DEFXX;
	Region region;
	PRegionSysData r;

	if ( PObject( self)-> options. optInDrawInfo) return false;
	if ( !XF_IN_PAINT(XX)) return false;

	if (rgn == nilHandle) {
		Rect r;
		r. left   = 0;
		r. bottom = 0;
		r. right  = XX-> size. x - 1;
		r. top	  = XX-> size. y - 1;
		return apc_gp_set_clip_rect( self, r);
	}

	r = GET_REGION(rgn);

	XClipBox( r-> region, &XX-> clip_rect);
	XX-> clip_rect. y += XX-> size. y - r-> height;
	XX-> clip_mask_extent. x = XX-> clip_rect. width;
	XX-> clip_mask_extent. y = XX-> clip_rect. height;
	if ( XX-> clip_rect. width == 0 || XX-> clip_rect. height == 0) {
		Rect r;
		r. left   = -1;
		r. bottom = -1;
		r. right  = -1;
		r. top	  = -1;
		return apc_gp_set_clip_rect( self, r);
	}

	region = XCreateRegion();
	XUnionRegion( region, r-> region, region);
	/* offset region if drawable is buffered */
	XOffsetRegion( region, XX-> btransform. x, XX-> size.y - r-> height - XX-> btransform. y);
	/* otherwise ( and only otherwise ), and if there's a
		X11 clipping, intersect the region with it. X11 clipping
		must not mix with the buffer clipping */
	if (( !XX-> udrawable || XX-> udrawable == XX-> gdrawable) &&
		XX-> paint_region)
		XIntersectRegion( region, XX-> paint_region, region);
	XSetRegion( DISP, XX-> gc, region);
	if ( XX-> flags. kill_current_region)
		XDestroyRegion( XX-> current_region);
	XX-> flags. kill_current_region = 1;
	XX-> current_region = region;
	XX-> flags. xft_clip = 0;
#ifdef USE_XFT
	if ( XX-> xft_drawable) prima_xft_update_region( self);
#endif
#ifdef HAVE_X11_EXTENSIONS_XRENDER_H
	if ( XX-> argb_picture ) XRenderSetPictureClipRegion(DISP, XX->argb_picture, region);
#endif
	return true;
}
Esempio n. 6
0
bool wxRegion::DoOffset( wxCoord x, wxCoord y )
{
    wxCHECK_MSG( m_refData, false, wxS("invalid region") );

    AllocExclusive();

    XOffsetRegion( M_REGIONDATA->m_region, x, y );

    return true;
}
Esempio n. 7
0
static PyObject *
region_OffsetRegion(PaxRegionObject *self, PyObject *args)
{
    int dx, dy;
    if (!PyArg_ParseTuple(args, "ii", &dx, &dy))
	return NULL;
    XOffsetRegion(self->region, dx, dy);
    Py_INCREF(Py_None);
    return Py_None;
}
Esempio n. 8
0
EAPI void
ecore_x_xregion_translate(Ecore_X_XRegion *region, int x, int y)
{
   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   if (!region)
      return;

   /* return value not used */
   XOffsetRegion((Region)region, x, y);
} /* ecore_x_xregion_translate */
Esempio n. 9
0
/* lpStruct - pointer to POINT */
DWORD
DrvRegionsOffSetRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct)
{
	LPPOINT lppt;
	
	if (!(lppt = (LPPOINT)lpStruct))
		return (DWORD)ERROR;
	XOffsetRegion((Region)dwParm1, lppt->x, lppt->y);
	return (DWORD)COMPLEXREGION;
}
Esempio n. 10
0
bool wxRegion::DoOffset( wxCoord x, wxCoord y )
{
    if (!m_refData)
        return false;

    AllocExclusive();

    XOffsetRegion( M_REGIONDATA->m_region, x, y );

    return true;
}
Esempio n. 11
0
bool wxRegion::Offset( wxCoord x, wxCoord y )
{
#if 0
    if (!m_refData)
        return FALSE;

    AllocExclusive();

    XOffsetRegion( M_REGIONDATA->m_region, x, y );
#endif
    return TRUE;
}
Esempio n. 12
0
void X11Graphics::drawGraphics( const OSGraphics &rGraphics, int xSrc,
                                int ySrc, int xDest, int yDest, int width,
                                int height )
{
    const X11Graphics& rGraph = (X11Graphics&)rGraphics;

    // check and adapt to source if needed
    if( !checkBoundaries( 0, 0, rGraph.getWidth(), rGraph.getHeight(),
                          xSrc, ySrc, width, height ) )
    {
        msg_Err( getIntf(), "nothing to draw from graphics source" );
        return;
    }

    // check destination
    if( !checkBoundaries( 0, 0, m_width, m_height,
                          xDest, yDest, width, height ) )
    {
        msg_Err( getIntf(), "out of reach destination! pls, debug your skin" );
        return;
    }

    // Source drawable
    Drawable src = rGraph.getDrawable();

    // Create the mask for transparency
    Region voidMask = XCreateRegion();
    XRectangle rect;
    rect.x = xSrc;
    rect.y = ySrc;
    rect.width = width;
    rect.height = height;
    Region clipMask = XCreateRegion();
    XUnionRectWithRegion( &rect, voidMask, clipMask );
    Region mask = XCreateRegion();
    XIntersectRegion( rGraph.getMask(), clipMask, mask );
    XDestroyRegion( clipMask );
    XDestroyRegion( voidMask );
    XOffsetRegion( mask, xDest - xSrc, yDest - ySrc );

    // Copy the pixmap
    XSetRegion( XDISPLAY, m_gc, mask );
    XCopyArea( XDISPLAY, src, m_pixmap, m_gc, xSrc, ySrc, width, height,
               xDest, yDest );

    // Add the source mask to the mask of the graphics
    Region newMask = XCreateRegion();
    XUnionRegion( m_mask, mask, newMask );
    XDestroyRegion( mask );
    XDestroyRegion( m_mask );
    m_mask = newMask;
}
Esempio n. 13
0
/*
 * Kreslení
 */
static void expose(XExposeEvent *event)
{
    Region region, region1, region2;
    XRectangle rect;
    
    if(event->count > 0)
	return; /* Kreslit jen po poslední události v øadì */
  
    XDrawArc(display, topwin, my_gc, 20, 20, topwin_w - 40, topwin_h - 40,
	     0, 360 * 64);
    
    region = XCreateRegion();
    region1 = XCreateRegion();
    region2 = XCreateRegion();
    rect.x = rect.y = 0;
    rect.width = 100;
    rect.height = topwin_w - 60;
    XUnionRectWithRegion(&rect, region, region1);
    rect.width = 20;
    rect.height = 10;
    XUnionRectWithRegion(&rect, region2, region);
    XOffsetRegion(region, 50, 100);
    XSubtractRegion(region1, region, region2);
    XDestroyRegion(region);
    region = XCreateRegion();
    rect.width = 100;
    rect.height = 30;
    XUnionRectWithRegion(&rect, region, region1);
    XOffsetRegion(region1, (int)topwin_w - 120, -30 + ((int)topwin_h - 40) / 2);
    XUnionRegion(region1, region2, region);
    XSetRegion(display, my_gc, region);
    XDestroyRegion(region);
    XDestroyRegion(region1);
    XDestroyRegion(region2);
    XSetClipOrigin(display, my_gc, 20, 20);
    XFillArc(display, topwin, my_gc, 20, 20, topwin_w - 40, topwin_h - 40,
	     0, 360 * 64);
    XSetClipMask(display, my_gc, None); /* Zru¹it oøezávání */
}
Esempio n. 14
0
void X11Graphics::drawGraphics( const OSGraphics &rGraphics, int xSrc,
                                int ySrc, int xDest, int yDest, int width,
                                int height )
{
    if( width == -1 )
    {
        width = rGraphics.getWidth();
    }
    if( height == -1 )
    {
        height = rGraphics.getHeight();
    }

    // Source drawable
    Drawable src = ((X11Graphics&)rGraphics).getDrawable();

    // Create the mask for transparency
    Region voidMask = XCreateRegion();
    XRectangle rect;
    rect.x = xSrc;
    rect.y = ySrc;
    rect.width = width;
    rect.height = height;
    Region clipMask = XCreateRegion();
    XUnionRectWithRegion( &rect, voidMask, clipMask );
    Region mask = XCreateRegion();
    XIntersectRegion( ((X11Graphics&)rGraphics).getMask(), clipMask, mask );
    XDestroyRegion( clipMask );
    XDestroyRegion( voidMask );
    XOffsetRegion( mask, xDest - xSrc, yDest - ySrc );

    // Copy the pixmap
    XSetRegion( XDISPLAY, m_gc, mask );
    XCopyArea( XDISPLAY, src, m_pixmap, m_gc, xSrc, ySrc, width, height,
               xDest, yDest );

    // Add the source mask to the mask of the graphics
    Region newMask = XCreateRegion();
    XUnionRegion( m_mask, mask, newMask );
    XDestroyRegion( mask );
    XDestroyRegion( m_mask );
    m_mask = newMask;
}
Esempio n. 15
0
Bool
apc_gp_set_clip_rect( Handle self, Rect clipRect)
{
	DEFXX;
	Region region;
	XRectangle r;

	if ( !XF_IN_PAINT(XX))
		return false;

	SORT( clipRect. left, clipRect. right);
	SORT( clipRect. bottom, clipRect. top);
	r. x = clipRect. left;
	r. y = REVERT( clipRect. top);
	r. width = clipRect. right - clipRect. left+1;
	r. height = clipRect. top - clipRect. bottom+1;
	XX-> clip_rect = r;
	XX-> clip_mask_extent. x = r. width;
	XX-> clip_mask_extent. y = r. height;
	region = XCreateRegion();
	XUnionRectWithRegion( &r, region, region);
	if ( XX-> paint_region)
		XIntersectRegion( region, XX-> paint_region, region);
	if ( XX-> btransform. x != 0 || XX-> btransform. y != 0) {
		XOffsetRegion( region, XX-> btransform. x, -XX-> btransform. y);
	}
	XSetRegion( DISP, XX-> gc, region);
	if ( XX-> flags. kill_current_region)
		XDestroyRegion( XX-> current_region);
	XX-> flags. kill_current_region = 1;
	XX-> current_region = region;
	XX-> flags. xft_clip = 0;
#ifdef USE_XFT
	if ( XX-> xft_drawable) prima_xft_update_region( self);
#endif
#ifdef HAVE_X11_EXTENSIONS_XRENDER_H
	if ( XX-> argb_picture ) XRenderSetPictureClipRegion(DISP, XX->argb_picture, region);
#endif
	return true;
}
Esempio n. 16
0
Bool
apc_gp_get_region( Handle self, Handle rgn)
{
	DEFXX;
	GC gc;
	XGCValues gcv;
	int w, h;
	Pixmap pixmap;
	XImage * i;
	Image pi;
	Region rgn2;

	if ( !XF_IN_PAINT(XX)) return false;

	if ( !rgn)
		return XX-> clip_mask_extent. x != 0 && XX-> clip_mask_extent. y != 0;

	if ( XX-> clip_mask_extent. x == 0 || XX-> clip_mask_extent. y == 0)
		return false;

	w = XX-> clip_mask_extent. x;
	h = XX-> clip_mask_extent. y;

	pixmap = XCreatePixmap( DISP, guts.root, w, h,
		XF_LAYERED(XX) ? guts. argb_depth :
		( XT_IS_BITMAP(XX) ? 1 : guts. depth )
	);
	XCHECKPOINT;

	gcv. graphics_exposures = false;
	gcv. fill_style = FillSolid;
	gcv. foreground = 0;
	gcv. clip_y_origin = -XX-> clip_rect. y + XX-> btransform. y;
	gcv. clip_x_origin = -XX-> clip_rect. x - XX-> btransform. x;
	XCHECKPOINT;
	gc = XCreateGC( DISP, pixmap, GCGraphicsExposures|GCFillStyle|GCForeground|GCClipXOrigin|GCClipYOrigin, &gcv);
	XFillRectangle( DISP, pixmap, gc, 0, 0, w, h);
	XSetForeground( DISP, gc, 1 );
	XCopyGC( DISP, XX->gc, GCClipMask, gc);
	XFillRectangle( DISP, pixmap, gc, 0, 0, w, h);
	XFreeGC( DISP, gc);
	XCHECKPOINT;

	i = XGetImage( DISP, pixmap, 0, 0, w, h, 1, XYPixmap);
	XFreePixmap( DISP, pixmap);
	if ( !i ) {
		warn("Cannot query image");
		return false;
	}

	img_fill_dummy( &pi, w, h, imBW | imGrayScale, NULL, NULL);
	if ( !( pi.data = malloc(pi.lineSize * h))) {
		XDestroyImage( i);
		warn("Not enough memory");
		return false;
	}

	prima_copy_xybitmap( pi.data, (Byte*)i-> data, w, h, pi.lineSize, i-> bytes_per_line);
	XDestroyImage( i);

	rgn2 = prima_region_create((Handle) &pi);
	free(pi.data);

	if ( GET_REGION(rgn)-> region )
		XDestroyRegion(  GET_REGION(rgn)-> region );
	if ( rgn2 ) {
		XOffsetRegion( rgn2, XX-> clip_rect.x, 0);
		GET_REGION(rgn)-> height = XX-> size.y - XX-> clip_rect.y;
		GET_REGION(rgn)-> region = rgn2;
	} else {
		GET_REGION(rgn)-> height = 0;
		GET_REGION(rgn)-> region = XCreateRegion();
	}
	return true;
}
Esempio n. 17
0
void X11Graphics::drawBitmap( const GenericBitmap &rBitmap, int xSrc,
                              int ySrc, int xDest, int yDest, int width,
                              int height, bool blend )
{
    // Get the bitmap size if necessary
    if( width == -1 )
    {
        width = rBitmap.getWidth();
    }
    else if( width > rBitmap.getWidth() )
    {
        msg_Dbg( getIntf(), "bitmap width too small (%i)", rBitmap.getWidth() );
        width = rBitmap.getWidth();
    }
    if( height == -1 )
    {
        height = rBitmap.getHeight();
    }
    else if( height > rBitmap.getHeight() )
    {
        msg_Dbg( getIntf(), "bitmap height too small (%i)", rBitmap.getHeight()
                                 );
        height = rBitmap.getHeight();
    }

    // Nothing to draw if width or height is null
    if( width == 0 || height == 0 )
    {
        return;
    }

    // Safety check for debugging purpose
    if( xDest + width > m_width || yDest + height > m_height )
    {
        msg_Dbg( getIntf(), "bitmap too large" );
        return;
    }

    // Get a buffer on the image data
    uint8_t *pBmpData = rBitmap.getData();
    if( pBmpData == NULL )
    {
        // Nothing to draw
        return;
    }

    // Get the image from the pixmap
    XImage *pImage = XGetImage( XDISPLAY, m_pixmap, xDest, yDest, width,
                                height, AllPlanes, ZPixmap );
    if( pImage == NULL )
    {
        msg_Dbg( getIntf(), "XGetImage returned NULL" );
        return;
    }
    char *pData = pImage->data;

    // Get the padding of this image
    int pad = pImage->bitmap_pad >> 3;
    int shift = ( pad - ( (width * XPIXELSIZE) % pad ) ) % pad;

    // Mask for transparency
    Region mask = XCreateRegion();

    // Get a pointer on the right X11Display::makePixel method
    X11Display::MakePixelFunc_t makePixelFunc = ( blend ?
        m_rDisplay.getBlendPixel() : m_rDisplay.getPutPixel() );

    // Skip the first lines of the image
    pBmpData += 4 * ySrc * rBitmap.getWidth();

    // Copy the bitmap on the image and compute the mask
    for( int y = 0; y < height; y++ )
    {
        // Skip uninteresting bytes at the beginning of the line
        pBmpData += 4 * xSrc;
        // Flag to say whether the previous pixel on the line was visible
        bool wasVisible = false;
        // Beginning of the current visible segment on the line
        int visibleSegmentStart = 0;
        for( int x = 0; x < width; x++ )
        {
            uint8_t b = *(pBmpData++);
            uint8_t g = *(pBmpData++);
            uint8_t r = *(pBmpData++);
            uint8_t a = *(pBmpData++);
            // Draw the pixel
            (m_rDisplay.*makePixelFunc)( (uint8_t*)pData, r, g, b, a );
            pData += XPIXELSIZE;
            if( a > 0 )
            {
                // Pixel is visible
                if( ! wasVisible )
                {
                    // Beginning of a visible segment
                    visibleSegmentStart = x;
                }
                wasVisible = true;
            }
            else
            {
                // Pixel is transparent
                if( wasVisible )
                {
                    // End of a visible segment: add it to the mask
                    addHSegmentInRegion( mask, visibleSegmentStart, x, y );
                }
                wasVisible = false;
            }
        }
        if( wasVisible )
        {
            // End of a visible segment: add it to the mask
            addHSegmentInRegion( mask, visibleSegmentStart, width, y );
        }
        pData += shift;
        // Skip uninteresting bytes at the end of the line
        pBmpData += 4 * (rBitmap.getWidth() - width - xSrc);
    }

    // Apply the mask to the graphics context
    XOffsetRegion( mask, xDest, yDest );
    XSetRegion( XDISPLAY, m_gc, mask );
    // Copy the image on the pixmap
    XPutImage( XDISPLAY, m_pixmap, m_gc, pImage, 0, 0, xDest, yDest, width,
               height);
    XDestroyImage( pImage );

    // Add the bitmap mask to the global graphics mask
    Region newMask = XCreateRegion();
    XUnionRegion( mask, m_mask, newMask );
    XDestroyRegion( m_mask );
    m_mask = newMask;

    XDestroyRegion( mask );
}
Esempio n. 18
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);
}
Esempio n. 19
0
/*
 * groupHandleButtonReleaseEvent
 *
 */
static void
groupHandleButtonReleaseEvent (CompScreen *s,
                               XEvent     *event)
{
	GroupSelection *group;
	int vx, vy;
	Region newRegion;
	Bool inserted = FALSE;
	Bool wasInTabBar = FALSE;

	GROUP_SCREEN (s);

	if (event->xbutton.button != 1)
		return;

	if (!gs->draggedSlot)
		return;

	if (!gs->dragged)
	{
		groupChangeTab (gs->draggedSlot, RotateUncertain);
		gs->draggedSlot = NULL;

		if (gs->grabState == ScreenGrabTabDrag)
			groupGrabScreen (s, ScreenGrabNone);

		return;
	}

	GROUP_WINDOW (gs->draggedSlot->window);

	newRegion = XCreateRegion ();
	if (!newRegion)
		return;

	XUnionRegion (newRegion, gs->draggedSlot->region, newRegion);

	groupGetDrawOffsetForSlot (gs->draggedSlot, &vx, &vy);
	XOffsetRegion (newRegion, vx, vy);

	for (group = gs->groups; group; group = group->next)
	{
		Bool inTabBar;
		Region clip, buf;
		GroupTabBarSlot *slot;

		if (!group->tabBar || !HAS_TOP_WIN (group))
			continue;

		/* create clipping region */
		clip = groupGetClippingRegion (TOP_TAB (group));
		if (!clip)
			continue;

		buf = XCreateRegion ();
		if (!buf)
		{
			XDestroyRegion (clip);
			continue;
		}

		XIntersectRegion (newRegion, group->tabBar->region, buf);
		XSubtractRegion (buf, clip, buf);
		XDestroyRegion (clip);

		inTabBar = !XEmptyRegion (buf);
		XDestroyRegion (buf);

		if (!inTabBar)
			continue;

		wasInTabBar = TRUE;

		for (slot = group->tabBar->slots; slot; slot = slot->next)
		{
			GroupTabBarSlot *tmpDraggedSlot;
			GroupSelection  *tmpGroup;
			Region slotRegion, buf;
			XRectangle rect;
			Bool inSlot;

			if (slot == gs->draggedSlot)
				continue;

			slotRegion = XCreateRegion ();
			if (!slotRegion)
				continue;

			if (slot->prev && slot->prev != gs->draggedSlot)
			{
				rect.x = slot->prev->region->extents.x2;
			}
			else if (slot->prev && slot->prev == gs->draggedSlot &&
			         gs->draggedSlot->prev)
			{
				rect.x = gs->draggedSlot->prev->region->extents.x2;
			}
			else
				rect.x = group->tabBar->region->extents.x1;

			rect.y = slot->region->extents.y1;

			if (slot->next && slot->next != gs->draggedSlot)
			{
				rect.width = slot->next->region->extents.x1 - rect.x;
			}
			else if (slot->next && slot->next == gs->draggedSlot &&
			         gs->draggedSlot->next)
			{
				rect.width = gs->draggedSlot->next->region->extents.x1 - rect.x;
			}
			else
				rect.width = group->tabBar->region->extents.x2;

			rect.height = slot->region->extents.y2 - slot->region->extents.y1;

			XUnionRectWithRegion (&rect, slotRegion, slotRegion);

			buf = XCreateRegion ();
			if (!buf)
				continue;

			XIntersectRegion (newRegion, slotRegion, buf);
			inSlot = !XEmptyRegion (buf);

			XDestroyRegion (buf);
			XDestroyRegion (slotRegion);

			if (!inSlot)
				continue;

			tmpDraggedSlot = gs->draggedSlot;

			if (group != gw->group)
			{
				CompWindow     *w = gs->draggedSlot->window;
				GroupSelection *tmpGroup = gw->group;
				int oldPosX = WIN_CENTER_X (w);
				int oldPosY = WIN_CENTER_Y (w);

				/* if the dragged window is not the top tab,
				   move it onscreen */
				if (tmpGroup->topTab && !IS_TOP_TAB (w, tmpGroup))
				{
					CompWindow *tw = TOP_TAB (tmpGroup);

					oldPosX = WIN_CENTER_X (tw) + gw->mainTabOffset.x;
					oldPosY = WIN_CENTER_Y (tw) + gw->mainTabOffset.y;

					groupSetWindowVisibility (w, TRUE);
				}

				/* Change the group. */
				groupDeleteGroupWindow (gs->draggedSlot->window);
				groupAddWindowToGroup (gs->draggedSlot->window, group, 0);

				/* we saved the original center position in oldPosX/Y before -
				   now we should apply that to the new main tab offset */
				if (HAS_TOP_WIN (group))
				{
					CompWindow *tw = TOP_TAB (group);
					gw->mainTabOffset.x = oldPosX - WIN_CENTER_X (tw);
					gw->mainTabOffset.y = oldPosY - WIN_CENTER_Y (tw);
				}
			}
			else
				groupUnhookTabBarSlot (group->tabBar, gs->draggedSlot, TRUE);

			gs->draggedSlot = NULL;
			gs->dragged = FALSE;
			inserted = TRUE;

			if ((tmpDraggedSlot->region->extents.x1 +
			     tmpDraggedSlot->region->extents.x2 + (2 * vx)) / 2 >
			    (slot->region->extents.x1 + slot->region->extents.x2) / 2)
			{
				groupInsertTabBarSlotAfter (group->tabBar,
				                            tmpDraggedSlot, slot);
			}
			else
				groupInsertTabBarSlotBefore (group->tabBar,
				                             tmpDraggedSlot, slot);

			groupDamageTabBarRegion (group);

			/* Hide tab-bars. */
			for (tmpGroup = gs->groups; tmpGroup; tmpGroup = tmpGroup->next)
			{
				if (group == tmpGroup)
					groupTabSetVisibility (tmpGroup, TRUE, 0);
				else
					groupTabSetVisibility (tmpGroup, FALSE, PERMANENT);
			}

			break;
		}

		if (inserted)
			break;
	}

	XDestroyRegion (newRegion);

	if (!inserted)
	{
		CompWindow     *draggedSlotWindow = gs->draggedSlot->window;
		GroupSelection *tmpGroup;

		for (tmpGroup = gs->groups; tmpGroup; tmpGroup = tmpGroup->next)
			groupTabSetVisibility (tmpGroup, FALSE, PERMANENT);

		gs->draggedSlot = NULL;
		gs->dragged = FALSE;

		const BananaValue *
		option_dnd_ungroup_window = bananaGetOption (bananaIndex,
		                                             "dnd_ungroup_window",
		                                             s->screenNum);

		if (option_dnd_ungroup_window->b && !wasInTabBar)
		{
			groupRemoveWindowFromGroup (draggedSlotWindow);
		}
		else if (gw->group && gw->group->topTab)
		{
			groupRecalcTabBarPos (gw->group,
			                      (gw->group->tabBar->region->extents.x1 +
			                       gw->group->tabBar->region->extents.x2) / 2,
			                      gw->group->tabBar->region->extents.x1,
			                      gw->group->tabBar->region->extents.x2);
		}

		/* to remove the painted slot */
		damageScreen (s);
	}

	if (gs->grabState == ScreenGrabTabDrag)
		groupGrabScreen (s, ScreenGrabNone);

	if (gs->dragHoverTimeoutHandle)
	{
		compRemoveTimeout (gs->dragHoverTimeoutHandle);
		gs->dragHoverTimeoutHandle = 0;
	}
}
Esempio n. 20
0
static void
groupHandleMotionEvent (CompScreen *s,
                        int        xRoot,
                        int        yRoot)
{
	GROUP_SCREEN (s);

	if (gs->grabState == ScreenGrabTabDrag)
	{
		int dx, dy;
		int vx, vy;
		REGION reg;
		Region draggedRegion = gs->draggedSlot->region;

		reg.rects = &reg.extents;
		reg.numRects = 1;

		dx = xRoot - gs->prevX;
		dy = yRoot - gs->prevY;

		if (gs->dragged || abs (dx) > RADIUS || abs (dy) > RADIUS)
		{
			gs->prevX = xRoot;
			gs->prevY = yRoot;

			if (!gs->dragged)
			{
				GroupSelection *group;
				BoxRec         *box;

				GROUP_WINDOW (gs->draggedSlot->window);

				gs->dragged = TRUE;

				for (group = gs->groups; group; group = group->next)
					groupTabSetVisibility (group, TRUE, PERMANENT);

				box = &gw->group->tabBar->region->extents;
				groupRecalcTabBarPos (gw->group, (box->x1 + box->x2) / 2,
				                      box->x1, box->x2);
			}

			groupGetDrawOffsetForSlot (gs->draggedSlot, &vx, &vy);

			reg.extents.x1 = draggedRegion->extents.x1 + vx;
			reg.extents.y1 = draggedRegion->extents.y1 + vy;
			reg.extents.x2 = draggedRegion->extents.x2 + vx;
			reg.extents.y2 = draggedRegion->extents.y2 + vy;
			damageScreenRegion (s, &reg);

			XOffsetRegion (gs->draggedSlot->region, dx, dy);
			gs->draggedSlot->springX =
			        (gs->draggedSlot->region->extents.x1 +
			         gs->draggedSlot->region->extents.x2) / 2;

			reg.extents.x1 = draggedRegion->extents.x1 + vx;
			reg.extents.y1 = draggedRegion->extents.y1 + vy;
			reg.extents.x2 = draggedRegion->extents.x2 + vx;
			reg.extents.y2 = draggedRegion->extents.y2 + vy;
			damageScreenRegion (s, &reg);
		}
	}
	else if (gs->grabState == ScreenGrabSelect)
	{
		groupDamageSelectionRect (s, xRoot, yRoot);
	}
}
Esempio n. 21
0
/*
 * groupWindowMoveNotify
 *
 */
void
groupWindowMoveNotify (CompWindow *w,
                       int        dx,
                       int        dy,
                       Bool       immediate)
{
	CompScreen *s = w->screen;
	Bool viewportChange;
	int i;

	GROUP_SCREEN (s);
	GROUP_DISPLAY (&display);
	GROUP_WINDOW (w);

	UNWRAP (gs, s, windowMoveNotify);
	(*s->windowMoveNotify)(w, dx, dy, immediate);
	WRAP (gs, s, windowMoveNotify, groupWindowMoveNotify);

	if (gw->glowQuads)
		groupComputeGlowQuads (w, &gs->glowTexture.matrix);

	if (!gw->group || gs->queued)
		return;

	/* FIXME: we need a reliable, 100% safe way to detect window
	   moves caused by viewport changes here */
	viewportChange = ((dx && !(dx % w->screen->width)) ||
	                  (dy && !(dy % w->screen->height)));

	if (viewportChange && (gw->animateState & IS_ANIMATED))
	{
		gw->destination.x += dx;
		gw->destination.y += dy;
	}

	if (gw->group->tabBar && IS_TOP_TAB (w, gw->group))
	{
		GroupTabBarSlot *slot;
		GroupTabBar     *bar = gw->group->tabBar;

		bar->rightSpringX += dx;
		bar->leftSpringX += dx;

		groupMoveTabBarRegion (gw->group, dx, dy, TRUE);

		for (slot = bar->slots; slot; slot = slot->next)
		{
			XOffsetRegion (slot->region, dx, dy);
			slot->springX += dx;
		}
	}

	const BananaValue *
	option_move_all = bananaGetOption (bananaIndex,
	                                   "move_all",
	                                   s->screenNum);

	if (!option_move_all->b || gd->ignoreMode ||
	    (gw->group->tabbingState != NoTabbing) ||
	    (gw->group->grabWindow != w->id) ||
	    !(gw->group->grabMask & CompWindowGrabMoveMask))
	{
		return;
	}

	for (i = 0; i < gw->group->nWins; i++)
	{
		CompWindow *cw = gw->group->windows[i];
		if (!cw)
			continue;

		if (cw->id == w->id)
			continue;

		GROUP_WINDOW (cw);

		if (cw->state & MAXIMIZE_STATE)
		{
			if (viewportChange)
				groupEnqueueMoveNotify (cw, -dx, -dy, immediate, TRUE);
		}
		else if (!viewportChange)
		{
			gw->needsPosSync = TRUE;
			groupEnqueueMoveNotify (cw, dx, dy, immediate, FALSE);
		}
	}
}
Esempio n. 22
0
Bool
groupDamageWindowRect (CompWindow *w,
                       Bool       initial,
                       BoxPtr     rect)
{
	Bool status;
	CompScreen *s = w->screen;

	GROUP_SCREEN (s);
	GROUP_WINDOW (w);

	UNWRAP (gs, s, damageWindowRect);
	status = (*s->damageWindowRect)(w, initial, rect);
	WRAP (gs, s, damageWindowRect, groupDamageWindowRect);

	if (initial)
	{
		const BananaValue *
		option_autotab_create = bananaGetOption (bananaIndex,
		                                         "autotab_create",
		                                         s->screenNum);

		if (option_autotab_create->b && groupIsGroupWindow (w))
		{
			if (!gw->group && (gw->windowState == WindowNormal))
			{
				/* First check if this window should be added to an
				 * existing group */
				GroupSelection *g = NULL;
				int i;
				for (i = 0; i <= gs->autotabCount - 1; i++)
				{
					if (matchEval (&gs->autotab[i], w))
					{
						Bool foundGroup = FALSE;
						GroupSelection *tg;

						for (tg = gs->groups; tg; tg = tg->next)
						{
							int i;
							for (i = 0; i <= tg->nWins - 1; i++)
							{
								if (matchEval (&gs->autotab[i], tg->windows[i]))
								{
									foundGroup = TRUE;
									g = tg;
									break;
								}
							}

							if (foundGroup)
								break;
						}

						if (foundGroup)
							break;
					}
				}

				if (g)
				{
					groupAddWindowToGroup (w, g, 0);
					//groupTabGroup (w);
				}
				else
				{
					groupAddWindowToGroup (w, NULL, 0);
					//groupTabGroup (w);
				}
			}
		}

		if (gw->group)
		{
			if (gw->windowState == WindowMinimized)
			{
				const BananaValue *
				option_minimize_all = bananaGetOption (bananaIndex,
				                                       "minimize_all",
				                                       s->screenNum);

				if (option_minimize_all->b)
					groupMinimizeWindows (w, gw->group, FALSE);
			}
			else if (gw->windowState == WindowShaded)
			{
				const BananaValue *
				option_shade_all = bananaGetOption (bananaIndex,
				                                    "shade_all",
				                                    s->screenNum);

				if (option_shade_all->b)
					groupShadeWindows (w, gw->group, FALSE);
			}
		}

		gw->windowState = WindowNormal;
	}

	if (gw->resizeGeometry)
	{
		BoxRec box;

		groupGetStretchRectangle (w, &box, NULL, NULL);
		groupDamagePaintRectangle (s, &box);
	}

	if (gw->slot)
	{
		int vx, vy;
		Region reg;

		groupGetDrawOffsetForSlot (gw->slot, &vx, &vy);
		if (vx || vy)
		{
			reg = XCreateRegion ();
			XUnionRegion (reg, gw->slot->region, reg);
			XOffsetRegion (reg, vx, vy);
		}
		else
			reg = gw->slot->region;

		damageScreenRegion (s, reg);

		if (vx || vy)
			XDestroyRegion (reg);
	}

	return status;
}
Esempio n. 23
0
Bool
apc_region_offset( Handle self, int dx, int dy)
{
	XOffsetRegion(REGION, dx, -dy);
	return true;
}
Esempio n. 24
0
static Bool
minDamageWindowRect (CompWindow *w,
                     Bool       initial,
                     BoxPtr     rect)
{
	Bool status = FALSE;

	MIN_SCREEN (w->screen);
	MIN_WINDOW (w);

	if (mw->ignoreDamage)
		return TRUE;

	if (initial)
	{
		if (mw->state == IconicState)
		{
			mw->state = NormalState;

			if (!w->invisible      &&
			    w->iconGeometrySet &&
			    matchEval (&ms->match, w))
			{
				if (!mw->adjust)
				{
					mw->adjust     = TRUE;
					ms->moreAdjust = TRUE;

					mw->tx     = w->iconGeometry.x - w->serverX;
					mw->ty     = w->iconGeometry.y - w->serverY;
					mw->xScale = (float) w->iconGeometry.width  / w->width;
					mw->yScale = (float) w->iconGeometry.height / w->height;

					addWindowDamage (w);
				}
			}
		}
		else if (mw->region && mw->shade < w->height)
		{
			if (ms->shadeStep && !w->invisible)
			{
				XSubtractRegion (w->region, &emptyRegion, mw->region);
				XOffsetRegion (mw->region, -w->attrib.x, -w->attrib.y);

				/* bind pixmap here so we have something to unshade with */
				if (!w->texture->pixmap && !w->bindFailed)
					bindWindow (w);

				ms->moreAdjust = TRUE;
			}
			else
			{
				mw->shade = MAXSHORT;
			}
		}

		mw->newState = NormalState;
	}
	else if (mw->adjust)
	{
		damageTransformedWindowRect (w,
		                         mw->xScale,
		                         mw->yScale,
		                         mw->tx,
		                         mw->ty,
		                         rect);

		status = TRUE;
	}

	UNWRAP (ms, w->screen, damageWindowRect);
	status |= (*w->screen->damageWindowRect) (w, initial, rect);
	WRAP (ms, w->screen, damageWindowRect, minDamageWindowRect);

	return status;
}
Esempio n. 25
0
static void
minHandleEvent (XEvent      *event)
{
	CompWindow *w;

	MIN_DISPLAY (&display);

	switch (event->type) {
	case MapNotify:
		w = findWindowAtDisplay (event->xmap.window);
		if (w)
		{
			MIN_WINDOW (w);

			if (mw->adjust)
				mw->state = mw->newState;

			if (mw->region)
				w->height = 0;

			mw->ignoreDamage = TRUE;
			while (mw->unmapCnt)
			{
				unmapWindow (w);
				mw->unmapCnt--;
			}
			mw->ignoreDamage = FALSE;
		}
		break;
	case UnmapNotify:
		w = findWindowAtDisplay (event->xunmap.window);
		if (w)
		{
			MIN_SCREEN (w->screen);

			if (w->pendingUnmaps && onCurrentDesktop (w)) /* Normal -> Iconic */
			{
				MIN_WINDOW (w);

				if (w->shaded)
				{
					if (!mw->region)
						mw->region = XCreateRegion ();

					if (mw->region && ms->shadeStep)
					{
						XSubtractRegion (w->region, &emptyRegion, mw->region);
						XOffsetRegion (mw->region, -w->attrib.x,
						           w->attrib.height +
						           w->attrib.border_width * 2 -
						           w->height - w->attrib.y);

						mw->shade = w->height;

						mw->adjust     = FALSE;
						ms->moreAdjust = TRUE;

						mw->unmapCnt++;
						w->unmapRefCnt++;

						addWindowDamage (w);
					}
				}
				else if (!w->invisible && matchEval (&ms->match, w))
				{
					if (w->iconGeometrySet)
					{
						mw->newState = IconicState;

						mw->xScale = w->paint.xScale;
						mw->yScale = w->paint.yScale;
						mw->tx     = w->attrib.x - w->serverX;
						mw->ty     = w->attrib.y - w->serverY;

						if (mw->region)
						{
							XDestroyRegion (mw->region);
							mw->region = NULL;
						}

						mw->shade = MAXSHORT;

						mw->adjust     = TRUE;
						ms->moreAdjust = TRUE;

						mw->unmapCnt++;
						w->unmapRefCnt++;

						addWindowDamage (w);
					}
				}
			}
			else  /* X -> Withdrawn */
			{
				MIN_WINDOW (w);

				if (mw->adjust)
				{
					mw->adjust = FALSE;
					mw->xScale = mw->yScale = 1.0f;
					mw->tx = mw->ty = 0.0f;
					mw->xVelocity = mw->yVelocity = 0.0f;
					mw->xScaleVelocity = mw->yScaleVelocity = 1.0f;
					mw->shade = MAXSHORT;

					if (mw->region)
					{
						XDestroyRegion (mw->region);
						mw->region = NULL;
					}
				}

				mw->state = NormalState;
			}
		}
	default:
		break;
	}

	UNWRAP (md, &display, handleEvent);
	(*display.handleEvent) (event);
	WRAP (md, &display, handleEvent, minHandleEvent);

	switch (event->type) {
	case MapRequest:
		w = findWindowAtDisplay (event->xmaprequest.window);
		if (w && w->hints && w->hints->initial_state == IconicState)
		{
			MIN_WINDOW (w);
			mw->newState = mw->state = IconicState;
		}
		break;
	default:
		break;
	}
}
Esempio n. 26
0
void
CompRegion::translate (int dx, int dy)
{
    priv->makeReal ();
    XOffsetRegion (handle (), dx, dy);
}
Esempio n. 27
0
/* This function currently always performs occlusion detection to
   minimize paint regions. OpenGL precision requirements are no good
   enough to guarantee that the results from using occlusion detection
   is the same as without. It's likely not possible to see any
   difference with most hardware but occlusion detection in the
   transformed screen case should be made optional for those who do
   see a difference. */
static void
paintOutputRegion (CompScreen	       *screen,
		   const CompTransform *transform,
		   Region	       region,
		   CompOutput	       *output,
		   unsigned int	       mask)
{
    static Region tmpRegion = NULL;
    CompWindow    *w;
    CompCursor	  *c;
    int		  count, windowMask, odMask, i;
    CompWindow	  *fullscreenWindow = NULL;
    CompWalker    walk;
    Bool          status;
    Bool          withOffset = FALSE;
    CompTransform vTransform;
    int           offX, offY;
    Region        clip = region;
    int           dontcare;

    if (!tmpRegion)
    {
	tmpRegion = XCreateRegion ();
	if (!tmpRegion)
	    return;
    }

    if (mask & PAINT_SCREEN_TRANSFORMED_MASK)
    {
	windowMask     = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
	count	       = 1;
    }
    else
    {
	windowMask     = 0;
	count	       = 0;
    }

    XSubtractRegion (region, &emptyRegion, tmpRegion);

    (*screen->initWindowWalker) (screen, &walk);

    if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
    {
	/* detect occlusions */
	for (w = (*walk.last) (screen); w; w = (*walk.prev) (w))
	{
	    if (w->destroyed)
		continue;

	    if (!w->shaded)
	    {
		if (w->attrib.map_state != IsViewable || !w->damaged)
		    continue;
	    }

	    /* copy region */
	    XSubtractRegion (tmpRegion, &emptyRegion, w->clip);

	    odMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK;
		
	    if ((screen->windowOffsetX != 0 || screen->windowOffsetY != 0) &&
		!windowOnAllViewports (w))
	    {
		withOffset = TRUE;

		getWindowMovementForOffset (w, screen->windowOffsetX,
					    screen->windowOffsetY,
					    &offX, &offY);

		vTransform = *transform;
		matrixTranslate (&vTransform, offX, offY, 0);

		XOffsetRegion (w->clip, -offX, -offY);

		odMask |= PAINT_WINDOW_WITH_OFFSET_MASK;
		status = (*screen->paintWindow) (w, &w->paint, &vTransform,
						 tmpRegion, odMask);
	    }
	    else
	    {
		withOffset = FALSE;
		status = (*screen->paintWindow) (w, &w->paint, transform, tmpRegion,
						 odMask);
	    }

	    if (status)
	    {
		if (withOffset)
		{
		    XOffsetRegion (w->region, offX, offY);
		    XSubtractRegion (tmpRegion, w->region, tmpRegion);
		    XOffsetRegion (w->region, -offX, -offY);
		}
		else
		    XSubtractRegion (tmpRegion, w->region, tmpRegion);

		/* unredirect top most fullscreen windows. */
		/* if the fullscreen window is mate-screensaver and we're
		   on nvidia we want to always unredirect even if this
		   option is disabled to work around LP #160264 */
		if (count == 0 &&
		    (screen->opt[COMP_SCREEN_OPTION_UNREDIRECT_FS].value.b ||
		    (w->resName && !strcmp(w->resName, "mate-screensaver") &&
		    XQueryExtension (screen->display->display, "NV-GLX",
				     &dontcare, &dontcare, &dontcare))))
		{
		    if (XEqualRegion (w->region, &screen->region) &&
			!REGION_NOT_EMPTY (tmpRegion))
		    {
			fullscreenWindow = w;
		    }
		    else
		    {
			for (i = 0; i < screen->nOutputDev; i++)
			    if (XEqualRegion (w->region,
					      &screen->outputDev[i].region))
				fullscreenWindow = w;
		    }
		}
	    }

	    if (!w->invisible)
		count++;
	}
    }

    if (fullscreenWindow)
	unredirectWindow (fullscreenWindow);

    if (!(mask & PAINT_SCREEN_NO_BACKGROUND_MASK))
	paintBackground (screen, tmpRegion,
			 (mask & PAINT_SCREEN_TRANSFORMED_MASK));

    /* paint all windows from bottom to top */
    for (w = (*walk.first) (screen); w; w = (*walk.next) (w))
    {
	if (w->destroyed)
	    continue;

	if (w == fullscreenWindow)
	    continue;

	if (!w->shaded)
	{
	    if (w->attrib.map_state != IsViewable || !w->damaged)
		continue;
	}

	if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
	    clip = w->clip;

	if ((screen->windowOffsetX != 0 || screen->windowOffsetY != 0) &&
	    !windowOnAllViewports (w))
	{
	    getWindowMovementForOffset (w, screen->windowOffsetX,
					screen->windowOffsetY, &offX, &offY);

	    vTransform = *transform;
	    matrixTranslate (&vTransform, offX, offY, 0);
	    (*screen->paintWindow) (w, &w->paint, &vTransform, clip,
				    windowMask | PAINT_WINDOW_WITH_OFFSET_MASK);
	}
	else
	{
	    (*screen->paintWindow) (w, &w->paint, transform, clip,
				    windowMask);
	}
    }

    if (walk.fini)
	(*walk.fini) (screen, &walk);

    /* paint cursors */
    for (c = screen->cursors; c; c = c->next)
	(*screen->paintCursor) (c, transform, tmpRegion, 0);
}
Esempio n. 28
0
void X11Graphics::drawBitmap( const GenericBitmap &rBitmap, int xSrc,
                              int ySrc, int xDest, int yDest, int width,
                              int height, bool blend )
{
    // check and adapt to source if needed
    if( !checkBoundaries( 0, 0, rBitmap.getWidth(), rBitmap.getHeight(),
                          xSrc, ySrc, width, height ) )
    {
        msg_Err( getIntf(), "empty source! pls, debug your skin" );
        return;
    }

    // check destination
    if( !checkBoundaries( 0, 0, m_width, m_height,
                          xDest, yDest, width, height ) )
    {
        msg_Err( getIntf(), "out of reach destination! pls, debug your skin" );
        return;
    }

    // Get a buffer on the image data
    uint8_t *pBmpData = rBitmap.getData();
    if( pBmpData == NULL )
    {
        // Nothing to draw
        return;
    }

    // Force pending XCopyArea to be sent to the X Server
    // before issuing an XGetImage.
    XSync( XDISPLAY, False );

    // Get the image from the pixmap
    XImage *pImage = XGetImage( XDISPLAY, m_pixmap, xDest, yDest, width,
                                height, AllPlanes, ZPixmap );
    if( pImage == NULL )
    {
        msg_Dbg( getIntf(), "XGetImage returned NULL" );
        return;
    }
    char *pData = pImage->data;

    // Get the padding of this image
    int pad = pImage->bitmap_pad >> 3;
    int shift = ( pad - ( (width * XPIXELSIZE) % pad ) ) % pad;

    // Mask for transparency
    Region mask = XCreateRegion();

    // Get a pointer on the right X11Display::makePixel method
    X11Display::MakePixelFunc_t makePixelFunc = ( blend ?
        m_rDisplay.getBlendPixel() : m_rDisplay.getPutPixel() );

    // Skip the first lines of the image
    pBmpData += 4 * ySrc * rBitmap.getWidth();

    // Copy the bitmap on the image and compute the mask
    for( int y = 0; y < height; y++ )
    {
        // Skip uninteresting bytes at the beginning of the line
        pBmpData += 4 * xSrc;
        // Flag to say whether the previous pixel on the line was visible
        bool wasVisible = false;
        // Beginning of the current visible segment on the line
        int visibleSegmentStart = 0;
        for( int x = 0; x < width; x++ )
        {
            uint8_t b = *(pBmpData++);
            uint8_t g = *(pBmpData++);
            uint8_t r = *(pBmpData++);
            uint8_t a = *(pBmpData++);
            // Draw the pixel
            (m_rDisplay.*makePixelFunc)( (uint8_t*)pData, r, g, b, a );
            pData += XPIXELSIZE;
            if( a > 0 )
            {
                // Pixel is visible
                if( ! wasVisible )
                {
                    // Beginning of a visible segment
                    visibleSegmentStart = x;
                }
                wasVisible = true;
            }
            else
            {
                // Pixel is transparent
                if( wasVisible )
                {
                    // End of a visible segment: add it to the mask
                    addHSegmentInRegion( mask, visibleSegmentStart, x, y );
                }
                wasVisible = false;
            }
        }
        if( wasVisible )
        {
            // End of a visible segment: add it to the mask
            addHSegmentInRegion( mask, visibleSegmentStart, width, y );
        }
        pData += shift;
        // Skip uninteresting bytes at the end of the line
        pBmpData += 4 * (rBitmap.getWidth() - width - xSrc);
    }

    // Apply the mask to the graphics context
    XOffsetRegion( mask, xDest, yDest );
    XSetRegion( XDISPLAY, m_gc, mask );
    // Copy the image on the pixmap
    XPutImage( XDISPLAY, m_pixmap, m_gc, pImage, 0, 0, xDest, yDest, width,
               height);
    XDestroyImage( pImage );

    // Add the bitmap mask to the global graphics mask
    Region newMask = XCreateRegion();
    XUnionRegion( mask, m_mask, newMask );
    XDestroyRegion( m_mask );
    m_mask = newMask;

    XDestroyRegion( mask );
}