Source for gnu.gcj.xlib.Drawable

   1: /* Copyright (C) 1999, 2000  Free Software Foundation
   2: 
   3:    This file is part of libgcj.
   4: 
   5: This software is copyrighted work licensed under the terms of the
   6: Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
   7: details.  */
   8: 
   9: package gnu.gcj.xlib;
  10: 
  11: import java.awt.Rectangle;
  12: 
  13: /** An X11 drawable.
  14:  *
  15:  * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
  16:  */
  17: public class Drawable extends XID
  18: {
  19:   private GC[] gcCache = new GC[10];
  20:   private int gcCachedCount = 0;
  21: 
  22:   public Drawable(Display display, int xid)
  23:   {
  24:     super(display, xid);
  25:   }
  26: 
  27:   /**
  28:    * Gets as much as possible of the image data within the requested
  29:    * region. Data from obscured parts of windows may not be
  30:    * retrievable.
  31:    *  
  32:    * @param dest where to place the image data.
  33:    * 
  34:    * @return the actual region of image data that was retrieved.
  35:    */
  36:   public Rectangle copyIntoXImage(XImage dest, Rectangle bounds,
  37:                   int destX, int destY)
  38:   {
  39:     Rectangle newBounds = null;
  40:     int tries = 5;
  41:     while (!bounds.isEmpty())
  42:       {
  43:     if (copyIntoXImageImpl(dest, bounds.x, bounds.y,
  44:                    bounds.width, bounds.height,
  45:                    destX, destY))
  46:       return bounds;
  47:         
  48:     // failed, likely due to wrong bounds...
  49:     
  50:     newBounds = getBounds(newBounds);
  51:     
  52:     bounds = newBounds.intersection(bounds);
  53:     
  54:     tries--;
  55:     
  56:     if (tries < 0)
  57:     throw new RuntimeException("copyIntoXImage is buggy");
  58:     
  59:       }
  60:     
  61:     return bounds; // always empty
  62:   }
  63: 
  64: 
  65: 
  66:   /**
  67:    * Performs an XGetSubImage. This method will fail if the X server
  68:    * does not possess the requested image data. This might occur when
  69:    * requesting the image date of a window that is partially obscured.
  70:    *
  71:    * @param desitantionImage where to place the image data
  72:    *
  73:    * @return false if method was unable to read the requested region.
  74:    */
  75:   private native boolean copyIntoXImageImpl(XImage destinationImage,
  76:                         int x, int y,
  77:                         int width, int height,
  78:                         int destX, int destY);
  79: 
  80:   public native Rectangle getBounds(Rectangle rv);
  81:   
  82:   public native int getDepth ();
  83:   
  84:   private static final String MSG_XGETSUBIMAGE_FAILED =
  85:     "XGetSubImage() failed.";
  86: 
  87:   protected void finalize() throws Throwable
  88:   {
  89:     // Dispose all the cached GCs, to reduce X server resource usage
  90:     for (int i=0; i<gcCachedCount; i++)
  91:       gcCache[i].disposeImpl ();
  92:     gcCachedCount = 0;
  93:     super.finalize();
  94:   }
  95: 
  96:   /** Put a GC in the cache for this drawable, so it can be retrieved later.
  97:    * @param gc The GC to put
  98:    */
  99:   void putGCInCache (GC gc)
 100:   {
 101:     if (gcCachedCount >= gcCache.length)
 102:     {
 103:       // List full - extend it to double its present size
 104:       GC[] oldList = gcCache;
 105:       gcCache = new GC[oldList.length*2];
 106:       System.arraycopy (oldList,0,gcCache,0,oldList.length);
 107:     }
 108:     gcCache[gcCachedCount++] = gc;
 109:   }
 110: 
 111:   /** Get a GC from the cache, if available
 112:    * @return A GC from the cache, or null if the cache is empty
 113:    */
 114:   GC getGCFromCache ()
 115:   {
 116:     return (gcCachedCount>0) ? gcCache[--gcCachedCount] : null;
 117:   }
 118: }