Example #1
0
JNIEXPORT void JNICALL
Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
                             jclass cls,
                             jobject xgc,
                             jint x,
                             jint y,
                             jint width,
                             jint height,
                             jintArray pixelArray) {

    XImage *image;
    jint *ary;               /* Array of jints for sending pixel values back
                              * to parent process.
                              */
    Window rootWindow;
    AwtGraphicsConfigDataPtr adata;

    DTRACE_PRINTLN6("RobotPeer: getRGBPixelsImpl(%lx, %d, %d, %d, %d, %x)", xgc, x, y, width, height, pixelArray);

    AWT_LOCK();

    /* avoid a lot of work for empty rectangles */
    if ((width * height) == 0) {
        AWT_UNLOCK();
        return;
    }
    DASSERT(width * height > 0); /* only allow positive size */

    adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, xgc, x11GraphicsConfigIDs.aData);
    DASSERT(adata != NULL);

    rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);
    image = getWindowImage(awt_display, rootWindow, x, y, width, height);

    /* Array to use to crunch around the pixel values */
    ary = (jint *) malloc(width * height * sizeof (jint));
    if (ary == NULL) {
        JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
        XDestroyImage(image);
        AWT_UNLOCK();
        return;
    }
    /* convert to Java ARGB pixels */
    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            jint pixel = (jint) XGetPixel(image, x, y); /* Note ignore upper
                                                         * 32-bits on 64-bit
                                                         * OSes.
                                                         */

            pixel |= 0xff000000; /* alpha - full opacity */

            ary[(y * width) + x] = pixel;
        }
    }
    (*env)->SetIntArrayRegion(env, pixelArray, 0, height * width, ary);
    free(ary);

    XDestroyImage(image);

    AWT_UNLOCK();
}
Example #2
0
JNIEXPORT void JNICALL
Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
                             jclass cls,
                             jobject xgc,
                             jint jx,
                             jint jy,
                             jint jwidth,
                             jint jheight,
                             jint scale,
                             jintArray pixelArray,
                             jboolean useGtk) {
    XImage *image;
    jint *ary;               /* Array of jints for sending pixel values back
                              * to parent process.
                              */
    Window rootWindow;
    XWindowAttributes attr;
    AwtGraphicsConfigDataPtr adata;

    DTRACE_PRINTLN6("RobotPeer: getRGBPixelsImpl(%lx, %d, %d, %d, %d, %x)", xgc, jx, jy, jwidth, jheight, pixelArray);

    if (jwidth <= 0 || jheight <= 0) {
        return;
    }

    adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, xgc, x11GraphicsConfigIDs.aData);
    DASSERT(adata != NULL);

    AWT_LOCK();

    jint sx = jx * scale;
    jint sy = jy * scale;
    jint swidth = jwidth * scale;
    jint sheight = jheight * scale;

    rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);

    if (!useGtk) {
        if (hasXCompositeOverlayExtension(awt_display) &&
            isXCompositeDisplay(awt_display, adata->awt_visInfo.screen))
        {
            rootWindow = compositeGetOverlayWindow(awt_display, rootWindow);
        }
    }

    if (!XGetWindowAttributes(awt_display, rootWindow, &attr)
            || sx + swidth <= attr.x
            || attr.x + attr.width <= sx
            || sy + sheight <= attr.y
            || attr.y + attr.height <= sy) {

        AWT_UNLOCK();
        return; // Does not intersect with root window
    }

    gboolean gtk_failed = TRUE;
    jint _x, _y;

    jint x = MAX(sx, attr.x);
    jint y = MAX(sy, attr.y);
    jint width = MIN(sx + swidth, attr.x + attr.width) - x;
    jint height = MIN(sy + sheight, attr.y + attr.height) - y;


    int dx = attr.x > sx ? attr.x - sx : 0;
    int dy = attr.y > sy ? attr.y - sy : 0;

    int index;

    if (useGtk) {
        gtk->gdk_threads_enter();
        gtk_failed = gtk->get_drawable_data(env, pixelArray, x, y, width,
                                            height, jwidth, dx, dy, scale);
        gtk->gdk_threads_leave();
    }

    if (gtk_failed) {
        image = getWindowImage(awt_display, rootWindow, sx, sy, swidth, sheight);

        ary = (*env)->GetPrimitiveArrayCritical(env, pixelArray, NULL);

        if (!ary) {
            XDestroyImage(image);
            AWT_UNLOCK();
            return;
        }

        dx /= scale;
        dy /= scale;
        width /= scale;
        height /= scale;

        /* convert to Java ARGB pixels */
        for (_y = 0; _y < height; _y++) {
            for (_x = 0; _x < width; _x++) {
                jint pixel = (jint) XGetPixel(image, _x * scale, _y * scale);
                                                              /* Note ignore upper
                                                               * 32-bits on 64-bit
                                                               * OSes.
                                                               */
                pixel |= 0xff000000; /* alpha - full opacity */

                index = (_y + dy) * jwidth + (_x + dx);
                ary[index] = pixel;
            }
        }

        XDestroyImage(image);
        (*env)->ReleasePrimitiveArrayCritical(env, pixelArray, ary, 0);
    }
    AWT_UNLOCK();
}