示例#1
0
 // Set the clipping region to a single rectangle.
 public override void SetClipRect(int x, int y, int width, int height)
 {
     using (Xsharp.Region region = new Xsharp.Region(x, y, width, height))
     {
         graphics.SetClipRegion(region, 0, 0);
     }
 }
示例#2
0
 // Set the clipping region to a list of rectangles.
 public override void SetClipRects(System.Drawing.Rectangle[] rects)
 {
     using (Xsharp.Region region = rectsToRegion(rects))
     {
         graphics.SetClipRegion(region);
     }
 }
示例#3
0
 // Set the clipping region to empty.
 public override void SetClipEmpty()
 {
     using (Xsharp.Region region = new Xsharp.Region())
     {
         graphics.SetClipRegion(region, 0, 0);
     }
 }
示例#4
0
 // Set the clipping region to infinite (i.e. disable clipping).
 public override void SetClipInfinite()
 {
     using (Xsharp.Region region = new Xsharp.Region(short.MinValue, short.MinValue, ushort.MaxValue, ushort.MaxValue))
     {
         graphics.SetClipRegion(region, 0, 0);
     }
 }
示例#5
0
	/// <summary>
	/// <para>Construct a new <see cref="T:Xsharp.Region"/>
	/// instance that is initially set to the same area as another
	/// region object.</para>
	/// </summary>
	///
	/// <param name="r">
	/// <para>The other region object to copy.  If <paramref name="r"/>
	/// is <see langword="null"/> or has been disposed, the new region
	/// will be set to the empty region.</para>
	/// </param>
	public Region(Region r)
			{
				lock(typeof(Region))
				{
					region = Xlib.XCreateRegion();
					if(region == IntPtr.Zero)
					{
						Display.OutOfMemory();
					}
					Union(r);
				}
			}
示例#6
0
 // Convert an Xsharp.Region to System.Drawing.Region
 internal static System.Drawing.Region RegionToDrawingRegion
     (Xsharp.Region region)
 {
     Xsharp.Rectangle[]    rectangles = region.GetRectangles();
     System.Drawing.Region newRegion  = new System.Drawing.Region();
     newRegion.MakeEmpty();
     for (int i = 0; i < rectangles.Length; i++)
     {
         Xsharp.Rectangle rect = rectangles[i];
         newRegion.Union(new System.Drawing.Rectangle
                             (rect.x, rect.y, rect.width, rect.height));
     }
     return(newRegion);
 }
示例#7
0
 // Convert a System.Drawing.Region to Xsharp.Region
 private static Xsharp.Region rectsToRegion(System.Drawing.Rectangle[] rectangles)
 {
     Xsharp.Region newRegion = new Xsharp.Region();
     for (int i = 0; i < rectangles.Length; i++)
     {
         System.Drawing.Rectangle rect = rectangles[i];
         // This implementation has a region size restriction.
         int left   = RestrictXY(rect.Left);
         int top    = RestrictXY(rect.Top);
         int right  = RestrictXY(rect.Right);
         int bottom = RestrictXY(rect.Bottom);
         newRegion.Union(left, top, right - left, bottom - top);
     }
     return(newRegion);
 }
	// Set the clipping region to infinite (i.e. disable clipping).
	public override void SetClipInfinite()
			{
				using (Xsharp.Region region = new Xsharp.Region(short.MinValue, short.MinValue, ushort.MaxValue, ushort.MaxValue))
				{
					graphics.SetClipRegion( region, 0, 0);
				}
			}
	// Set the clipping region to empty.
	public override void SetClipEmpty()
			{
				using (Xsharp.Region region = new Xsharp.Region())
				{
					graphics.SetClipRegion( region, 0, 0);
				}
			}
	// Paint this widget in response to an "Expose" event.
	protected override void OnPaint(Graphics graphics)
			{
				// Draw the thick 3D border around the outside first.
				graphics.DrawEffect(0, 0, width, height, Effect.Raised);

				// Get the rectangle containing the caption area.
				Rectangle rect = new Rectangle
					(FrameBorderSize, FrameBorderSize,
					 width - FrameBorderSize * 2,
					 captionHeight - FrameBorderSize);

				// If the rectangle does not overlap the expose region,
				// then there is no point drawing the main caption area.
				if(!graphics.ExposeRegion.Overlaps(rect))
				{
					return;
				}

				// Get the colors to use for the foreground and background.
				Color foreground, background, endBackground;
				if((flags & CaptionFlags.Active) != 0)
				{
					foreground = new Color(StandardColor.HighlightForeground);
					background = new Color(StandardColor.HighlightBackground);
					endBackground =
						new Color(StandardColor.HighlightEndBackground);
				}
				else
				{
					foreground = new Color(StandardColor.Background);
					background = new Color(StandardColor.BottomShadow);
					endBackground = new Color(StandardColor.EndBackground);
				}

				// Create a gradient for the title bar, if necessary.
				if(gradient != null &&
				   (gradient.Width != rect.width ||
				    gradient.Height != rect.height))
				{
					// The size has changed and we need a new gradient.
					gradient.Dispose();
					gradient = null;
				}
				if(gradient == null && screen.DefaultDepth >= 15)
				{
					DotGNU.Images.Image image = CreateGradient
						(rect.width, rect.height, background, endBackground);
					gradient = new Xsharp.Image(screen, image.GetFrame(0));
					image.Dispose();
				}

				// Clear the caption background.
				if(gradient == null)
				{
					graphics.Foreground = background;
					graphics.SetFillSolid();
					graphics.FillRectangle(rect);
				}
				else
				{
					graphics.SetFillTiled(gradient.Pixmap, rect.x, rect.y);
					graphics.FillRectangle(rect);
					graphics.SetFillSolid();
				}

				// Draw the caption buttons and then subtract that
				// region off the caption rectangle so we don't get
				// bleed through when we draw the caption text.
				rect.width -= DrawCaptionButtons
					(graphics, rect, flags, (CaptionFlags)(~0));

				// Bail out if the rectangle is too small for the text.
				if(rect.width <= 2)
				{
					return;
				}

				// Position the caption text.
				Font font = GetCaptionFont();
				FontExtents extents = font.GetFontExtents(graphics);
				int textY = (rect.height - extents.Ascent) / 2;
				textY += rect.y + extents.Ascent;

				// Draw the caption text, clipped to the caption area
				// so that it won't overwrite the buttons on the right.
				using(Region region = new Region(graphics.ExposeRegion))
				{
					region.Intersect(rect);
					graphics.SetClipRegion(region);
					graphics.Foreground = foreground;
					graphics.DrawString(rect.x + 2, textY, child.Name, font);
				}
			}
	/*
	 * <summary><p>Invalidate the given region and flush the request</p></summary>
	 */		
	private void Invalidate(Region region)
	{
		if (drawBackground)
		{
			ClearRegion(region, XBool.True);
		}
		else
		{
			/* Don't flush to the X server cause we don't want it to draw
				the background */
			
			region.Intersect(0, 0, width, height);
			
			if (exposeRegion == null)
			{
				exposeRegion = region;
				
				dpy.AddPendingExpose(this);
			}
			else
			{
				exposeRegion.Union(region);
				
				region.Dispose();
			}
		}
	}
示例#12
0
	/// <summary>
	/// <para>Clone an instance of <see cref="T:Xsharp.Region"/>.</para>
	/// </summary>
	///
	/// <remarks>
	/// <para>This method implements the <see cref="T:System.ICloneable"/>
	/// interface.</para>
	/// </remarks>
	public Object Clone()
			{
				Region r = new Region();
				lock(typeof(Region))
				{
					if(region != IntPtr.Zero)
					{
						Xlib.XUnionRegion(region, r.region, r.region);
					}
				}
				return r;
			}
	// Place a minimized window rectangle.
	internal void PlaceMinimizedRectangle(ref Rectangle rect, Widget placed)
			{
				// Create a region that consists of all minimized areas.
				Region region = new Region();
				Widget current = TopChild;
				while(current != null)
				{
					if(current is CaptionWidget && current.IsMapped &&
					   ((CaptionWidget)current).Child.IsIconic)
					{
						if(current != placed)
						{
							region.Union
								(current.x, current.y,
								 current.width, current.height);
						}
					}
					current = current.NextBelow;
				}

				// Place the minimized rectangle.
				int yplace = height - rect.height;
				int xplace = 0;
				for(;;)
				{
					// Move up to the next line if we've overflowed this one.
					if((xplace + rect.width) > width && width >= rect.width)
					{
						yplace -= rect.height;
						xplace = 0;
					}

					// Determine if the rectangle overlaps the region.
					// If it doesn't, then we have found the best location.
					rect.x = xplace;
					rect.y = yplace;
					if(!region.Overlaps(rect))
					{
						region.Dispose();
						return;
					}

					// Move on to the next candidate.
					xplace += rect.width;
				}
			}
示例#14
0
	/// <summary>
	/// <para>Xor another region with this one.</para>
	/// </summary>
	///
	/// <param name="r">
	/// <para>The other region to xor with this one.  If
	/// <paramref name="r"/> is <see langword="null"/> or disposed,
	/// then it will be treated as the empty region.</para>
	/// </param>
	///
	/// <remarks>
	/// <para>If this region has been disposed, then it will be treated
	/// as empty prior to the xor operation.</para>
	/// </remarks>
	public void Xor(Region r)
			{
				lock(typeof(Region))
				{
					if(region == IntPtr.Zero)
					{
						region = Xlib.XCreateRegion();
						if(region == IntPtr.Zero)
						{
							Display.OutOfMemory();
						}
					}
					if(r == null || r.region == IntPtr.Zero)
					{
						// Xor of an empty and a non-empty region gives
						// the non-empty region as the result.
					}
					else if(r == this)
					{
						// Xor the region with itself: result is empty.
						Xlib.XDestroyRegion(region);
						region = Xlib.XCreateRegion();
						if(region == IntPtr.Zero)
						{
							Display.OutOfMemory();
						}
					}
					else
					{
						Xlib.XXorRegion(region, r.region, region);
					}
				}
			}
示例#15
0
	/// <summary>
	/// <para>Subtract another region from this one.</para>
	/// </summary>
	///
	/// <param name="r">
	/// <para>The other region to subtract from this one.  If
	/// <paramref name="r"/> is <see langword="null"/> or disposed,
	/// the method does nothing.</para>
	/// </param>
	///
	/// <remarks>
	/// <para>If this region has been disposed, then it will be re-created
	/// with its initial contents set to empty.</para>
	/// </remarks>
	public void Subtract(Region r)
			{
				lock(typeof(Region))
				{
					if(region == IntPtr.Zero)
					{
						region = Xlib.XCreateRegion();
						if(region == IntPtr.Zero)
						{
							Display.OutOfMemory();
						}
					}
					else if(r == null || r.region == IntPtr.Zero)
					{
						// Nothing to do here: subtracting an empty region.
					}
					else if(r == this)
					{
						// Subtract the region from itself: result is empty.
						Xlib.XDestroyRegion(region);
						region = Xlib.XCreateRegion();
						if(region == IntPtr.Zero)
						{
							Display.OutOfMemory();
						}
					}
					else
					{
						Xlib.XSubtractRegion(region, r.region, region);
					}
				}
			}
示例#16
0
	/// <summary>
	/// <para>Intersect another region with this one.</para>
	/// </summary>
	///
	/// <param name="r">
	/// <para>The other region to intersect with this one.  If
	/// <paramref name="r"/> is <see langword="null"/> or disposed,
	/// the method operates as an intersection with the empty region.</para>
	/// </param>
	///
	/// <remarks>
	/// <para>If this region has been disposed, then it will be re-created
	/// with its initial contents set to empty.</para>
	/// </remarks>
	public void Intersect(Region r)
			{
				lock(typeof(Region))
				{
					if(region == IntPtr.Zero)
					{
						region = Xlib.XCreateRegion();
						if(region == IntPtr.Zero)
						{
							Display.OutOfMemory();
						}
					}
					else if(r == null || r.region == IntPtr.Zero)
					{
						Xlib.XDestroyRegion(region);
						region = Xlib.XCreateRegion();
						if(region == IntPtr.Zero)
						{
							Display.OutOfMemory();
						}
					}
					else if(r != this)
					{
						Xlib.XIntersectRegion(r.region, region, region);
					}
				}
			}
示例#17
0
	/// <summary>
	/// <para>Union another region with this one.</para>
	/// </summary>
	///
	/// <param name="r">
	/// <para>The other region to union with this one.  If <paramref name="r"/>
	/// is <see langword="null"/>, the same as <see langword="this"/>, or
	/// disposed, then this method will do nothing.</para>
	/// </param>
	///
	/// <remarks>
	/// <para>If this region has been disposed, then it will be re-created
	/// with its initial contents set to a copy of <paramref name="r"/>.</para>
	/// </remarks>
	public void Union(Region r)
			{
				lock(typeof(Region))
				{
					if(r != null && r != this && r.region != IntPtr.Zero)
					{
						if(region == IntPtr.Zero)
						{
							region = Xlib.XCreateRegion();
							if(region == IntPtr.Zero)
							{
								Display.OutOfMemory();
							}
						}
						Xlib.XUnionRegion(region, r.region, region);
					}
				}
			}
	// Set the clipping region to a single rectangle.
	public override void SetClipRect(int x, int y, int width, int height)
			{
				using (Xsharp.Region region = new Xsharp.Region(x, y, width, height))
				{
					graphics.SetClipRegion( region, 0, 0);
				}
			}
	// Clear a region to the background and optionally queue expose events.
	private bool ClearRegion(Region region, XBool exposures)
			{
				// Intersect the region with the widget boundaries.
				region.Intersect(0, 0, width, height);

				// Remove areas that are occupied by mapped child widgets.
				Widget child = TopChild;
				while(child != null)
				{
					if(child.mapped)
					{
						region.Subtract(child.x, child.y,
										child.width, child.height);
					}
					child = child.NextBelow;
				}

				// Bail out if the region is now empty.
				if(region.IsEmpty())
				{
					return false;
				}

				// Lock down the display and send the "XClearArea" requests.
				try
				{
					IntPtr display = dpy.Lock();
					XWindow handle = GetWidgetHandle();
					IntPtr xregion = region.GetRegion();
					XRectangle xrect;
					int size, index;
					size = Xlib.XSharpGetRegionSize(xregion);
					for(index = 0; index < size; ++index)
					{
						Xlib.XSharpGetRegionRect(xregion, index, out xrect);
						Xlib.XClearArea(display, handle, xrect.x, xrect.y,
										xrect.width, xrect.height, exposures);
					}
				}
				finally
				{
					dpy.Unlock();
				}
				return true;
			}
	// Convert a System.Drawing.Region to Xsharp.Region
	private static Xsharp.Region rectsToRegion( System.Drawing.Rectangle[] rectangles)
		{
			Xsharp.Region newRegion =  new Xsharp.Region();
			for( int i = 0; i < rectangles.Length; i++)
			{
				System.Drawing.Rectangle rect = rectangles[i];
				// This implementation has a region size restriction.
				int left = RestrictXY(rect.Left);
				int top = RestrictXY(rect.Top);
				int right = RestrictXY(rect.Right);
				int bottom = RestrictXY(rect.Bottom);
				newRegion.Union( left, top, right - left, bottom - top);
			}
			return newRegion;
		}
	// Flush pending invalidates to the X server.
	internal void FlushInvalidates()
			{
				Region region = invalidateRegion;
				invalidateRegion = null;
				nextInvalidate = null;
				if(region != null)
				{
					// No point redrawing if we are unmapped.
					if(handle != XDrawable.Zero && mapped && AncestorsMapped)
					{
						Invalidate(region);
					}
				}
			}
	/// <summary>
	/// <para>Force a repaint on a section of this widget.</para>
	/// </summary>
	///
	/// <param name="x">
	/// <para>The X co-ordinate of the top-left corner of
	/// the section to repaint.</para>
	/// </param>
	///
	/// <param name="y">
	/// <para>The Y co-ordinate of the top-left corner of
	/// the section to repaint.</para>
	/// </param>
	///
	/// <param name="width">
	/// <para>The width of the section to repaint.</para>
	/// </param>
	///
	/// <param name="height">
	/// <para>The height of the section to repaint.</para>
	/// </param>
	///
	/// <exception cref="T:Xsharp.XException">
	/// <para>Raised if <paramref name="x"/>, <paramref name="y"/>,
	/// <paramref name="width"/>, or <paramref name="height"/> are
	/// out of range.</para>
	/// </exception>
	public void Repaint(int x, int y, int width, int height)
			{
				if(x < -32768 || x > 32767 ||
				   y < -32768 || y > 32767)
				{
					throw new XException(S._("X_InvalidPosition"));
				}
				if(width < 1 || width > 32767 ||
				   height < 1 || height > 32767)
				{
					throw new XException(S._("X_InvalidSize"));
				}
				try
				{
					IntPtr display = dpy.Lock();
					if(mapped && AncestorsMapped)
					{
						if(invalidateRegion == null)
						{
							// Create a new invalidate region for this widget.
							invalidateRegion = new Region(x, y, width, height);
							dpy.AddPendingInvalidate(this);
						}
						else
						{
							// Add the rectangle to the invalidate region.
							invalidateRegion.Union(x, y, width, height);
						}
					}
				}
				finally
				{
					dpy.Unlock();
				}
			}
示例#23
0
	/// <summary>
	/// <para>Determine if another region overlaps with this region.</para>
	/// </summary>
	///
	/// <param name="r">
	/// <para>The other region to test against this region.</para>
	/// </param>
	///
	/// <returns>
	/// <para>Returns <see langword="true"/> if <paramref name="r"/> overlaps
	/// with this region; <see langword="false"/> otherwise.</para>
	/// </returns>
	public bool Overlaps(Region r)
			{
				lock(typeof(Region))
				{
					if(region == IntPtr.Zero)
					{
						return false;
					}
					else if(r == null || r.region == IntPtr.Zero)
					{
						return false;
					}
					else if(r == this)
					{
						return true;
					}
					else
					{
						IntPtr reg = Xlib.XCreateRegion();
						if(reg == IntPtr.Zero)
						{
							Display.OutOfMemory();
						}
						Xlib.XIntersectRegion(region, r.region, reg);
						bool result = (Xlib.XEmptyRegion(reg) == 0);
						Xlib.XDestroyRegion(reg);
						return result;
					}
				}
			}
	/// <summary>
	/// <para>Update this widget by immediately redrawing invalidated
	/// regions.</para>
	/// </summary>
	///
	/// <param name="clear">
	/// <para>Setting clear to true clears the region to the background.
	/// </para>
	/// </param>
	public void Update(bool clear)
			{
				Region region = invalidateRegion;
				invalidateRegion = null;
				if(region != null)
				{
					// Remove the region from the pending list.
					dpy.RemovePendingInvalidate(this);

					// No point redrawing if we are unmapped or the
					// region to be drawn is empty.
					if(mapped && AncestorsMapped && (!clear ||
					   ClearRegion(region, XBool.False)))
					{
						// Paint the region as if we got a regular expose.
						Graphics graphics = new Graphics(this);
						graphics.exposeRegion = region;
						graphics.SetClipRegion(region);
						try
						{
							OnPaint(graphics);
						}
						finally
						{
							graphics.Dispose();
						}
					}
					// Dispose the region that we no longer require.
					region.Dispose();
				}
			}
	// Remove this widget from the pending expose list.
	internal void RemovePendingExpose()
			{
				dpy.RemovePendingExpose(this);
				if(exposeRegion != null)
				{
					exposeRegion.Dispose();
					exposeRegion = null;
				}
			}
	/*
	 * <summary><p>Invalidate the given region and flush the request</p></summary>
	 */
	private void Invalidate(int x, int y, int width, int height)
	{
		Region region = new Region();
		
		region.Union(x, y, width, height);
		
		Invalidate(region);
	}
示例#27
0
	/// <summary>
	/// <para>Set the clip area to a region object, with a
	/// specified origin.</para>
	/// </summary>
	///
	/// <param name="r">
	/// <para>The clipping region to set.</para>
	/// </param>
	///
	/// <param name="xorigin">
	/// <para>The X co-ordinate of the clipping origin.</para>
	/// </param>
	///
	/// <param name="yorigin">
	/// <para>The Y co-ordinate of the clipping origin.</para>
	/// </param>
	///
	/// <exception cref="T:System.ArgumentNullException">
	/// <para>The <paramref name="r"/> value is
	/// <see langword="null"/>.</para>
	/// </exception>
	///
	/// <exception cref="T:Xsharp.XException">
	/// <para>The <paramref name="xorigin"/> or <paramref name="yorigin"/>
	/// value is out of range.</para>
	/// </exception>
	public void SetClipRegion(Region r, int xorigin, int yorigin)
			{
				if(r == null)
				{
					throw new ArgumentNullException("r");
				}
				if(xorigin < -32768 || xorigin > 32767 ||
				   yorigin < -32768 || yorigin > 32767)
				{
					throw new XException(S._("X_PointCoordRange"));
				}
				try
				{
					IntPtr display = Lock();
					Xlib.XSetClipOrigin(display, gc, xorigin, yorigin);
					Xlib.XSetRegion(display, gc, r.GetRegion());
					if(clipRegion != r)
					{
						if(clipRegion != null)
							clipRegion.Dispose();
						clipRegion = new Region(r);
					}
				}
				finally
				{
					dpy.Unlock();
				}
			}
	// Dispatch an event to this widget.
	internal override void DispatchEvent(ref XEvent xevent)
			{
				switch((EventType)(xevent.xany.type__))
				{
					case EventType.Expose:
					case EventType.GraphicsExpose:
					{
						// Add the area to the expose region.
						if(exposeRegion == null)
						{
							// This is the first rectangle in an expose.
							exposeRegion = new Region
								((int)(xevent.xexpose.x__),
								 (int)(xevent.xexpose.y__),
								 (int)(xevent.xexpose.width__),
								 (int)(xevent.xexpose.height__));

							// Queue this widget for later repainting.
							// We don't do it now or the system will be
							// very slow during opaque window drags.
							dpy.AddPendingExpose(this);
						}
						else
						{
							// This is an extra rectangle in an expose.
							exposeRegion.Union
								((int)(xevent.xexpose.x__),
								 (int)(xevent.xexpose.y__),
								 (int)(xevent.xexpose.width__),
								 (int)(xevent.xexpose.height__));
						}
					}
					break;
					
					case Xsharp.Events.EventType.ClientMessage:
					{
						if(xevent.xclient.message_type == dpy.internalBeginInvoke)
						{
							OnBeginInvokeMessage((IntPtr)xevent.xclient.l(0));
						}
					}
					break;
				}
				base.DispatchEvent(ref xevent);
			}
示例#29
0
	/// <summary>
	/// <para>Dispose this graphics context object.</para>
	/// </summary>
	///
	/// <remarks>
	/// <para>This method implements the <see cref="T:System.IDisposable"/>
	/// interface.</para>
	/// </remarks>
	public void Dispose()
			{
				try
				{
					IntPtr display = dpy.Lock();
					if(gc != IntPtr.Zero)
					{
						// Flush the double buffer if necessary.
						if(drawable is DoubleBuffer)
						{
							((DoubleBuffer)drawable).End(this);
						}

						// Release the GC back to the screen's cache so
						// that we can reuse it the next time we need a GC.
						drawable.screen.ReleaseGC(gc, (drawable is Bitmap));
						gc = IntPtr.Zero;
					}
				}
				finally
				{
					dpy.Unlock();
				}
				if(exposeRegion != null)
				{
					exposeRegion.Dispose();
					exposeRegion = null;
				}
				if(clipRegion != null ) {
					clipRegion.Dispose();
					clipRegion = null;
				}
				isDisposed = true;
			}
	// Process pending exposures on this widget.
	internal void Expose()
			{
				Region region = exposeRegion;
				if(region != null)
				{
					exposeRegion = null;
					// sometimes it could be that Expose is called but the handle is destroyed.
					// so check here, if handle not null.
					if( handle != XDrawable.Zero ) {
						try {
							Graphics graphics = new Graphics(this);
							graphics.exposeRegion = region;
							graphics.SetClipRegion(region);
							OnPaint(graphics);
							graphics.Dispose();
							region.Dispose();
						}
						catch( XInvalidOperationException ) { // irgnore Widget disposed exception
						}
					}
				}
			}
示例#31
0
	/// <summary>
	/// <para>Set the clip area to a region object.</para>
	/// </summary>
	///
	/// <param name="r">
	/// <para>The clipping region to set.</para>
	/// </param>
	///
	/// <exception cref="T:System.ArgumentNullException">
	/// <para>The <paramref name="r"/> value is
	/// <see langword="null"/>.</para>
	/// </exception>
	public void SetClipRegion(Region r)
			{
				if(r == null)
				{
					throw new ArgumentNullException("r");
				}
				try
				{
					IntPtr display = Lock();
					Xlib.XSetClipOrigin(display, gc, 0, 0);
					Xlib.XSetRegion(display, gc, r.GetRegion());
					if(clipRegion != r)
					{
						if(clipRegion != null)
							clipRegion.Dispose();
						clipRegion = new Region(r);
					}
				}
				finally
				{
					dpy.Unlock();
				}
			}