static void fbDispmanAddDispmanxElement(void) {

    DISPMANX_DISPLAY_HANDLE_T display = 0;
    DISPMANX_UPDATE_HANDLE_T update;
    VC_DISPMANX_ALPHA_T alpha;
    VC_RECT_T dst;
    VC_RECT_T src = { 0, 0, cursor.cursorWidth << 16, cursor.cursorHeight << 16};
    VC_RECT_T pixelRect = { 0, 0, cursor.cursorWidth, cursor.cursorHeight };
    int rc;

    display = vc_dispmanx_display_open(0 /* LCD */);
    if (display == 0) {
        GLASS_LOG_SEVERE("Cannot open display");
        return;
    }

    update = vc_dispmanx_update_start(0);
    alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE;
    alpha.opacity = 0xff;
    alpha.mask = (DISPMANX_RESOURCE_HANDLE_T) 0;
    dst.x = cursor.x;
    dst.y = cursor.y;
    dst.width = cursor.cursorWidth;
    dst.height = cursor.cursorHeight;
    cursor.element = vc_dispmanx_element_add(
                         update,
                         display,
                         2 /*layer*/,
                         &dst,
                         0 /*resource*/,
                         &src,
                         DISPMANX_PROTECTION_NONE,
                         &alpha,
                         0 /*clamp*/,
                         0 /*transform*/);

    vc_dispmanx_update_submit_sync(update);

}
static jboolean fbDispmanRobotScreenCapture(jint x, jint y,
                                            jint width, jint height,
                                            jint *pixels) {
    FILE *fb;
    unsigned int *pixelBuffer = NULL;
    unsigned char *pixelBufferPtr = NULL;
    unsigned char *dst = (unsigned char *) pixels;
    int i = 0;
    int fbFileHandle;
    struct fb_var_screeninfo screenInfo;
    unsigned int dstByteStride = width * 4;
    VC_IMAGE_TRANSFORM_T transform = 0;
    DISPMANX_RESOURCE_HANDLE_T resource = 0;
    DISPMANX_DISPLAY_HANDLE_T display = 0;
    DISPMANX_RESOURCE_HANDLE_T screenResource = 0;
    uint32_t imagePtr;
    int rc;

    GLASS_LOG_FINE("Capture %i,%i+%ix%i", x, y, width, height);

    if (width < 1 || height < 1) {
        GLASS_LOG_SEVERE("Failed. width/height values must be at least = 1");
        return JNI_FALSE;
    }

    GLASS_LOG_FINE("open(%s, O_RDONLY)", FB_DEVICE);
    fbFileHandle = open(FB_DEVICE, O_RDONLY);
    if (fbFileHandle < 0) {
        GLASS_LOG_SEVERE("Cannot open framebuffer");
        return JNI_FALSE;
    }

    GLASS_LOG_FINE("ioctl(%s, FBIOGET_VSCREENINFO)", FB_DEVICE);
    if (ioctl(fbFileHandle, FBIOGET_VSCREENINFO, &screenInfo)) {
        GLASS_LOG_SEVERE("Cannot get screen info");
        GLASS_LOG_FINE("close(%s)", FB_DEVICE);
        close(fbFileHandle);
        return JNI_FALSE;
    }
    GLASS_LOG_FINE("Read screen info: res=%ix%i, offset=%ix%i",
                   screenInfo.xres, screenInfo.yres,
                   screenInfo.xoffset, screenInfo.yoffset);
    GLASS_LOG_FINE("close(%s)", FB_DEVICE);
    close(fbFileHandle);

    VC_RECT_T pixelRect = { 0, 0, screenInfo.xres, screenInfo.yres };

    int pixelBufferLength = screenInfo.xres * screenInfo.yres * 4;
    pixelBuffer = (unsigned int *) malloc(pixelBufferLength);
    pixelBufferPtr = (unsigned char *) pixelBuffer;

    if (pixelBuffer == NULL) {
        printf("Failed to allocate temporary pixel buffer\n");
        return JNI_FALSE;
    }

    GLASS_LOG_FINE("fopen(%s, \"r\") to read %ix%i pixels at bit depth %i\n",
                   FB_DEVICE, width, height, screenInfo.bits_per_pixel);

    display = vc_dispmanx_display_open(0 /* LCD */);
    if (display == 0) {
        fprintf(stderr, "fbRobotScreenCapture: Dispman: Cannot open display\n");
        free(pixelBuffer);
        return JNI_FALSE;
    }

    // create the resource for the snapshot
    screenResource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888, screenInfo.xres, screenInfo.yres, &imagePtr);
    if (!screenResource) {
        fprintf(stderr, "fbRobotScreenCapture: Cannot create resource\n");
        vc_dispmanx_display_close(display);
        free(pixelBuffer);
        return JNI_FALSE;
    }

    rc = vc_dispmanx_snapshot(display, screenResource, transform);
    rc = 0;
    if (rc) {
        fprintf(stderr, "fbRobotScreenCapture: snapshot failed\n");
        vc_dispmanx_display_close(display);
        free(pixelBuffer);
        return JNI_FALSE;
    }

    rc = vc_dispmanx_resource_read_data(screenResource, &pixelRect, pixelBuffer, screenInfo.xres * 4);

    if (rc) {
        fprintf(stderr, "fbRobotScreenCapture: Cannot read pixels %d\n", rc);
        vc_dispmanx_display_close(display);
        free(pixelBuffer);
        return JNI_FALSE;
    }

    rc = vc_dispmanx_resource_delete(screenResource);
    if (rc) {
        fprintf(stderr, "fbRobotScreenCapture: failed to free buffer %d\n", rc);
        vc_dispmanx_display_close(display);
        free(pixelBuffer);
        return JNI_FALSE;
    }
    screenResource = 0;

    if (x < 0) {
        pixelBuffer += -x;
        width += x;
        x = 0;
    }
    if (y < 0) {
        pixelBuffer += -y * (int)screenInfo.xres;
        height += y;
        y = 0;
    }

    int widthLimit = width;
    int heightLimit = height;

    // Required height is larger than screen's height
    if ((int) screenInfo.yres < height) {
        heightLimit = (int) screenInfo.yres;
    }
    // Required width is larger than screen's width
    if ((int) screenInfo.xres < width) {
        widthLimit = (int) screenInfo.xres;
    }
    // Required height is out of range
    if (((int) screenInfo.yres - y) < height) {
        heightLimit = (int) screenInfo.yres - y;
    }
    // Required width is out of range
    if (((int) screenInfo.xres - x) < width) {
        widthLimit = (int) screenInfo.xres - x;
    }

    if (widthLimit > 0 && heightLimit > 0) {
        // copy the relevant portion of the screen to the supplied pixel array
        int offset = y * screenInfo.xres * 4 + x * 4;
        for (i = 0; i < heightLimit; i++) {
            memcpy(dst + i * dstByteStride, pixelBufferPtr + offset, widthLimit * 4);
            offset += screenInfo.xres * 4;
        }
    } else {
        GLASS_LOG_SEVERE("Failed to take a snapshot, some of parameters are illegal");
        free(pixelBuffer);
        return JNI_FALSE;
    }

    vc_dispmanx_display_close(display);
    free(pixelBuffer);
    return JNI_TRUE;
}
static jlong fbDispmanCreateNativeCursor(JNIEnv *env, jint x, jint y,  jbyte *srcArray, jint width, jint height) {

    VC_RECT_T pixelRect;
    int rc;
    uint32_t imagePtr;
    jbyte *allocatedBuffer = NULL;
    DispmanCursorImage *cursorImage = (DispmanCursorImage *)malloc(sizeof(DispmanCursorImage));

    //Width should be aligned to 16 pixels
    if (width % 16 != 0) {
        int newWidth = width + 16 - (width % 16);
        allocatedBuffer = (jbyte *)malloc(newWidth * height * 4);
        int i;
        int offset = 0;
        for (i = 0; i < height; ++i) {
            memcpy(allocatedBuffer + offset, srcArray, width * 4);
            memset(allocatedBuffer + offset + (width * 4), 0, (newWidth - width) * 4);
            offset += newWidth * 4;
            srcArray += width * 4;
        }

        width = newWidth;
        srcArray = allocatedBuffer;
    }

    pixelRect.x = 0;
    pixelRect.y = 0;
    pixelRect.width = width;
    pixelRect.height = height;

    cursorImage->x = x;
    cursorImage->y = y;
    cursorImage->width = width;
    cursorImage->height = height;
    cursorImage->resource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888,
                            width,
                            height,
                            &imagePtr);
    if (cursorImage->resource == 0) {
        GLASS_LOG_SEVERE("Cannot create resource");
        if (allocatedBuffer != NULL) {
            free(allocatedBuffer);
            allocatedBuffer = NULL;
        }
        free(cursorImage);
        return 0;
    }

    rc = vc_dispmanx_resource_write_data(cursorImage->resource,
                                         VC_IMAGE_ARGB8888,
                                         width * 4,
                                         srcArray,
                                         &pixelRect);

    if (allocatedBuffer != NULL) {
        free(allocatedBuffer);
        allocatedBuffer = NULL;
    }

    if (rc != 0) {
        GLASS_LOG_SEVERE("Cannot write pixels");
        free(cursorImage);
        return 0;
    }

    return ptr_to_jlong(cursorImage);
}
Example #4
0
jboolean fbFBRobotScreen(jint x, jint y,
                                    jint width, jint height,
                                    jint *pixels) {

    FILE *fb;
    unsigned char *pixelBuffer = NULL;
    unsigned char *dst = (unsigned char *) pixels;
    unsigned int dstByteStride = width * 4;
    int i = 0;
    int fbFileHandle;
    struct fb_var_screeninfo screenInfo;
    int depth; // pixel size in bytes

    GLASS_LOG_FINE("Capture %i,%i+%ix%i", x, y, width, height);
    jboolean result = JNI_FALSE;

    if (width < 1 || height < 1) {
        GLASS_LOG_SEVERE("Failed. width/height values must be at least = 1");
        return JNI_FALSE;
    }

    GLASS_LOG_FINE("open(%s, O_RDONLY)", FB_DEVICE);
    fbFileHandle = open(FB_DEVICE, O_RDONLY);
    if (fbFileHandle < 0) {
        GLASS_LOG_SEVERE("Cannot open framebuffer");
        return JNI_FALSE;
    }
    GLASS_LOG_FINE("ioctl(%s, FBIOGET_VSCREENINFO)", FB_DEVICE);
    if (ioctl(fbFileHandle, FBIOGET_VSCREENINFO, &screenInfo)) {
        GLASS_LOG_SEVERE("Cannot get screen info");
        return JNI_FALSE;
    }
    GLASS_LOG_FINE("Read screen info: res=%ix%i, offset=%ix%i",
                   screenInfo.xres, screenInfo.yres,
                   screenInfo.xoffset, screenInfo.yoffset);
    GLASS_LOG_FINE("close(%s)", FB_DEVICE);
    close(fbFileHandle);
    depth = screenInfo.bits_per_pixel / 8;
    int pixelBufferLength = screenInfo.xres * screenInfo.yres * depth;
    pixelBuffer = (unsigned char *) malloc(pixelBufferLength);
    if (pixelBuffer == NULL) {
        GLASS_LOG_SEVERE("Failed to allocate temporary pixel buffer");
        return JNI_FALSE;
    }

    GLASS_LOG_FINE("fopen(%s, \"r\") to read %ix%i pixels at bit depth %i",
                   FB_DEVICE, width, height, screenInfo.bits_per_pixel);
    fb = fopen(FB_DEVICE, "r");
    if (fb == NULL) {
        GLASS_LOG_SEVERE("FB: Cannot open framebuffer for reading");
        free(pixelBuffer);
        return JNI_FALSE;
    }

    fseek(fb, screenInfo.yoffset * screenInfo.xres * depth, SEEK_SET);
    int numRead = fread(pixelBuffer, 1,
                        pixelBufferLength,
                        fb);

    if (x < 0) {
        dst += -x * 4;
        width += x;
        x = 0;
    }
    if (y < 0) {
        dst += -y * dstByteStride;
        height += y;
        y = 0;
    }

    int widthLimit = width;
    int heightLimit = height;

    // Required height is larger than screen's height
    if ((int) screenInfo.yres < height) {
        heightLimit = (int) screenInfo.yres;
    }
    // Required width is larger than screen's width
    if ((int) screenInfo.xres < width) {
        widthLimit = (int) screenInfo.xres;
    }
    // Required height is out of range
    if (((int) screenInfo.yres - y) < height) {
        heightLimit = (int) screenInfo.yres - y;
    }
    // Required width is out of range
    if (((int) screenInfo.xres - x) < width) {
        widthLimit = (int) screenInfo.xres - x;
    }

    if (widthLimit > 0 && heightLimit > 0) {
        // copy the relevant portion of the screen to the supplied pixel array
        int offset = y * screenInfo.xres * depth + x * depth;
        for (i = 0; i < heightLimit; i++) {
            memcpy(dst + i * dstByteStride, pixelBuffer + offset, widthLimit * depth);
            offset += screenInfo.xres * depth;
        }
    } else {
        free(pixelBuffer);
        fclose(fb);
        GLASS_LOG_FINE("fclose(%s)", FB_DEVICE);
        GLASS_LOG_SEVERE("Failed to take a snapshot, some of parameters are illegal");
        return JNI_FALSE;
    }

    free(pixelBuffer);
    GLASS_LOG_FINE("fclose(%s)", FB_DEVICE);
    fclose(fb);
    return JNI_TRUE;
}