public void dispose() {
   getRGBPixelsMethodParam = null;
   Method method = getRGBPixelsMethod;
   try {
     if (method != null) {
       getRGBPixelsMethod = null;
       method.setAccessible(false);
     }
   } finally {
     try {
       Class<?>[] tailSig = new Class<?>[0];
       peer.getClass().getDeclaredMethod("dispose", tailSig).invoke(peer, (Object[]) tailSig);
     } catch (IllegalArgumentException e) {
       LLog.e(e);
     } catch (SecurityException e) {
       LLog.e(e);
     } catch (IllegalAccessException e) {
       LLog.e(e);
     } catch (InvocationTargetException e) {
       LLog.e(e);
     } catch (NoSuchMethodException e) {
       LLog.e(e);
     }
   }
 }
 public int[] getRGBPixels() {
   try {
     getPixelsSema.acquire();
   } catch (InterruptedException e) {
     LLog.e(e);
   }
   try {
     synchronized (pixelCache) {
       _getRGBPixels();
       return pixelCache[0];
     }
   } finally {
     getPixelsSema.release();
   }
 }
  public boolean getRGBPixels(int x, int y, int width, int height, int[] pixels) {
    try {
      getPixelsSema.acquire();
    } catch (InterruptedException e) {
      LLog.e(e);
    }
    try {
      synchronized (pixelCache) {
        boolean usedEfficientMethod;
        if (isDirty) {
          isDirty = false;
          usedEfficientMethod = _getRGBPixels();
        } else {
          usedEfficientMethod = true;
        }

        getRGBPixelSlice(pixelCache[0], this.width, this.height, x, y, width, height, pixels);

        return usedEfficientMethod;
      }
    } finally {
      getPixelsSema.release();
    }
  }
  public DirectRobot(GraphicsDevice device) throws AWTException {
    if (device == null) {
      device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    }
    robot = new Robot(device);

    ArrayList<Exception> exceptions = new ArrayList<Exception>();

    this.device = device;
    Toolkit toolkit = Toolkit.getDefaultToolkit();
    peer = ((ComponentFactory) toolkit).createRobot(null, device);
    Class<?> peerClass = peer.getClass();
    Method method = null;
    int methodType = -1;
    Object methodParam = null;
    try {
      method =
          peerClass.getDeclaredMethod(
              "getRGBPixels",
              new Class<?>[] {Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE, int[].class});
      methodType = 0;
    } catch (SecurityException e) {
      exceptions.add(e);
    } catch (NoSuchMethodException e) {
      exceptions.add(e);
    }
    if (methodType < 0) {
      try {
        method =
            peerClass.getDeclaredMethod(
                "getScreenPixels", new Class<?>[] {Rectangle.class, int[].class});
        methodType = 1;
      } catch (SecurityException e) {
        exceptions.add(e);
      } catch (NoSuchMethodException e) {
        exceptions.add(e);
      }
    }

    if (methodType < 0) {
      try {
        method =
            peerClass.getDeclaredMethod(
                "getScreenPixels", new Class<?>[] {Integer.TYPE, Rectangle.class, int[].class});
        methodType = 2;
        GraphicsDevice[] devices = getScreenDevices();
        int count = devices.length;
        for (int i = 0; i < count; i++) {
          if (device.equals(devices[i])) {
            methodParam = Integer.valueOf(i);
            break;
          }
        }

      } catch (SecurityException e) {
        exceptions.add(e);
      } catch (NoSuchMethodException e) {
        exceptions.add(e);
      }
    }

    if (methodType < 0) {
      try {
        boolean accessibleChanged = false;

        method =
            peerClass.getDeclaredMethod(
                "getRGBPixelsImpl",
                new Class<?>[] {
                  Class.forName("sun.awt.X11GraphicsConfig"),
                  Integer.TYPE,
                  Integer.TYPE,
                  Integer.TYPE,
                  Integer.TYPE,
                  int[].class
                });
        Field field = peerClass.getDeclaredField("xgc");
        try {
          if (!field.isAccessible()) {
            field.setAccessible(true);
            accessibleChanged = true;
          }
          methodParam = field.get(peer);
          methodType = 3;
        } catch (IllegalArgumentException e) {
          exceptions.add(e);
        } catch (IllegalAccessException e) {
          exceptions.add(e);
        } finally {
          if (accessibleChanged) {
            field.setAccessible(false);
          }
        }
      } catch (SecurityException e) {
        exceptions.add(e);
      } catch (NoSuchFieldException e) {
        exceptions.add(e);
      } catch (NoSuchMethodException e) {
        exceptions.add(e);
      } catch (ClassNotFoundException e) {
        exceptions.add(e);
      }
    }

    if (methodType >= 0 && method != null && (methodType <= 1 || methodParam != null)) {
      if (DEBUG) LLog.i(String.format("Method type = %d", methodType));
      getRGBPixelsMethod = method;
      getRGBPixelsMethodType = methodType;
      getRGBPixelsMethodParam = methodParam;
    } else {
      if (DEBUG) {
        for (Exception e : exceptions) {
          e.printStackTrace();
        }
      }
      exceptions.clear();
      exceptions = null;
      if (DEBUG) {
        LLog.w(
            String.format(
                "WARNING: Failed to acquire direct method for grabbing pixels, please post this on the main thread!\n\n%s\n\n",
                peer.getClass().getName()));
        try {
          Method[] methods = peer.getClass().getDeclaredMethods();
          for (Method method1 : methods) {
            LLog.w(method1 + "\n");
          }

          LLog.w("\n");
        } catch (Exception e) {
          LLog.e(e);
        }
      }
      throw new RuntimeException("No supported method for getting pixels");
    }
  }
  private boolean _getRGBPixels() {
    Rectangle r = getScreenBounds();
    int numPixels = r.width * r.height;
    int width = r.width;
    int height = r.height;
    this.width = width;
    this.height = height;
    if (pixelCache[0] == null || pixelCache[0].length != numPixels) {
      pixelCache[0] = new int[numPixels];
    }
    if (getRGBPixelsMethod != null) {
      try {
        methLock.lock();
        boolean makeAccessible = !getRGBPixelsMethod.isAccessible();
        synchronized (getRGBPixelsMethod) {
          if (makeAccessible) {
            getRGBPixelsMethod.setAccessible(true);
          }
          try {
            switch (getRGBPixelsMethodType) {
              case 0:
                getRGBPixelsMethod.invoke(
                    peer,
                    new Object[] {
                      Integer.valueOf(r.x),
                      Integer.valueOf(r.y),
                      Integer.valueOf(width),
                      Integer.valueOf(height),
                      pixelCache[0]
                    });
                break;
              case 1:
                getRGBPixelsMethod.invoke(
                    peer, new Object[] {new Rectangle(r.x, r.y, width, height), pixelCache[0]});
                break;
              case 2:
                getRGBPixelsMethod.invoke(
                    peer,
                    new Object[] {
                      getRGBPixelsMethodParam, new Rectangle(r.x, r.y, width, height), pixelCache[0]
                    });
                break;
              default:
                getRGBPixelsMethod.invoke(
                    peer,
                    new Object[] {
                      getRGBPixelsMethodParam,
                      Integer.valueOf(r.x),
                      Integer.valueOf(r.y),
                      Integer.valueOf(width),
                      Integer.valueOf(height),
                      pixelCache[0]
                    });
                break;
            }
          } finally {
            if (makeAccessible) {
              getRGBPixelsMethod.setAccessible(false);
            }
          }
        }

        return true;
      } catch (IllegalArgumentException e) {
        LLog.e(e);
      } catch (IllegalAccessException e) {
        LLog.e(e);
      } catch (InvocationTargetException e) {
        LLog.e(e);
      } finally {
        methLock.unlock();
      }
    }

    int[] tmp = getRGBPixels(r);
    System.arraycopy(tmp, 0, pixelCache[0], 0, numPixels);
    return false;
  }