mirror of https://github.com/sipwise/jitsi.git
parent
67e5dc87ca
commit
9f44c4f923
Binary file not shown.
Binary file not shown.
@ -0,0 +1,21 @@
|
||||
##
|
||||
# \file Makefile
|
||||
# \brief libscreencapture makefile.
|
||||
# \author Sebastien Vincent
|
||||
|
||||
CC = gcc
|
||||
JNI_HEADERS = -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux
|
||||
CFLAGS = -std=c99 -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=600 -Wall -Wextra -pedantic -Wstrict-prototypes -Wredundant-decls $(JNI_HEADERS)
|
||||
|
||||
all: libscreencapture
|
||||
|
||||
libscreencapture: net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture.c
|
||||
$(CC) -shared -fPIC $(CFLAGS) -o libscreencapture.so -O $<
|
||||
|
||||
# To compile 32 bit library under 64 bit system
|
||||
libscreencapture-32: net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture.c
|
||||
$(CC) -shared -m32 $(CFLAGS) -o libscreencapture.so -O $<
|
||||
|
||||
clean:
|
||||
rm -f *.o *.so
|
||||
|
||||
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture.c
|
||||
* \brief X11 screen capture.
|
||||
* \author Sebastien Vincent
|
||||
* \date 2009
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/XShm.h>
|
||||
|
||||
#include "net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture.h"
|
||||
|
||||
/**
|
||||
* \brief Grab X11 screen.
|
||||
* \param x11display display string (i.e. :0.0), if NULL getenv("DISPLAY") is used
|
||||
* \param x x position to start capture
|
||||
* \param y y position to start capture
|
||||
* \param width capture width
|
||||
* \param height capture height
|
||||
* \return array of integers which will contains screen capture
|
||||
* (ARGB format) or NULL if failure. This parameter needs to be freed by caller
|
||||
*/
|
||||
static int32_t* grab_screen(const char* x11display, int32_t x, int32_t y, int32_t w, int32_t h)
|
||||
{
|
||||
const char* display_str; /* display string */
|
||||
Display* display = NULL; /* X11 display */
|
||||
Visual* visual = NULL;
|
||||
int screen = 0; /* X11 screen */
|
||||
Window root_window = 0; /* X11 root window of a screen */
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int depth = 0;
|
||||
int shm_support = 0;
|
||||
XImage* img = NULL;
|
||||
XShmSegmentInfo shm_info;
|
||||
int32_t* data = NULL;
|
||||
size_t off = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
size_t size = 0;
|
||||
|
||||
display_str = x11display ? x11display : getenv("DISPLAY");
|
||||
|
||||
if(!display_str)
|
||||
{
|
||||
/* fprintf(stderr, "No display!\n"); */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* open current X11 display */
|
||||
display = XOpenDisplay(display_str);
|
||||
|
||||
if(!display)
|
||||
{
|
||||
/* fprintf(stderr, "Cannot open X11 display!\n"); */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
screen = DefaultScreen(display);
|
||||
root_window = RootWindow(display, screen);
|
||||
visual = DefaultVisual(display, screen);
|
||||
width = DisplayWidth(display, screen);
|
||||
height = DisplayHeight(display, screen);
|
||||
depth = DefaultDepth(display, screen);
|
||||
|
||||
/* check that user-defined parameters are in image */
|
||||
if((w + x) > width || (h + y) > height)
|
||||
{
|
||||
XCloseDisplay(display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = w * h;
|
||||
|
||||
/* test is XServer support SHM */
|
||||
shm_support = XShmQueryExtension(display);
|
||||
|
||||
/* fprintf(stdout, "Display=%s width=%d height=%d depth=%d SHM=%s\n", display_str, width, height, depth, shm_support ? "true" : "false"); */
|
||||
|
||||
if(shm_support)
|
||||
{
|
||||
/* fprintf(stdout, "Use XShmGetImage\n"); */
|
||||
|
||||
/* create image for SHM use */
|
||||
img = XShmCreateImage(display, visual, depth, ZPixmap, NULL, &shm_info, w, h);
|
||||
|
||||
if(!img)
|
||||
{
|
||||
/* fprintf(stderr, "Image cannot be created!\n"); */
|
||||
XCloseDisplay(display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* setup SHM stuff */
|
||||
shm_info.shmid = shmget(IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT | 0777);
|
||||
shm_info.shmaddr = (char*)shmat(shm_info.shmid, NULL, 0);
|
||||
img->data = shm_info.shmaddr;
|
||||
shmctl(shm_info.shmid, IPC_RMID, NULL);
|
||||
shm_info.readOnly = 0;
|
||||
|
||||
if((shm_info.shmaddr == (void*)-1) || !XShmAttach(display, &shm_info))
|
||||
{
|
||||
/* fprintf(stderr, "Cannot use shared memory!\n"); */
|
||||
XCloseDisplay(display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* grab screen */
|
||||
if(!XShmGetImage(display, root_window, img, x, y, 0xffffffff))
|
||||
{
|
||||
/* fprintf(stderr, "Cannot grab image!\n"); */
|
||||
XShmDetach(display, &shm_info);
|
||||
shmdt(shm_info.shmaddr);
|
||||
XCloseDisplay(display);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fprintf(stdout, "Use XGetImage\n"); */
|
||||
/* no SHM */
|
||||
img = XGetImage(display, root_window, x, y, w, h, 0xffffffff, ZPixmap);
|
||||
|
||||
if(!img)
|
||||
{
|
||||
/* fprintf(stderr, "Cannot grab image!\n"); */
|
||||
XCloseDisplay(display);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
data = malloc(sizeof(int32_t) * size);
|
||||
|
||||
if(!data)
|
||||
{
|
||||
XDestroyImage(img);
|
||||
|
||||
if(shm_support)
|
||||
{
|
||||
XShmDetach(display, &shm_info);
|
||||
shmdt(shm_info.shmaddr);
|
||||
}
|
||||
|
||||
XCloseDisplay(display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* convert to Java ARGB */
|
||||
for(j = 0 ; j < h ; j++)
|
||||
{
|
||||
for(i = 0 ; i < w ; i++)
|
||||
{
|
||||
/* do not care about hight 32-bit for 64 bit host
|
||||
* (sizeof(long) = 8 on 64 bit Linux host)
|
||||
*/
|
||||
unsigned int pixel = (unsigned int)XGetPixel(img, i, j);
|
||||
|
||||
pixel |= 0xff000000; /* ARGB */
|
||||
data[off++] = pixel;
|
||||
}
|
||||
}
|
||||
|
||||
/* free X11 resources and close display */
|
||||
XDestroyImage(img);
|
||||
|
||||
if(shm_support)
|
||||
{
|
||||
XShmDetach(display, &shm_info);
|
||||
shmdt(shm_info.shmaddr);
|
||||
}
|
||||
|
||||
XCloseDisplay(display);
|
||||
|
||||
/* return array */
|
||||
return data;
|
||||
}
|
||||
|
||||
JNIEXPORT jintArray JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture_grabScreen
|
||||
(JNIEnv* env, jobject obj, jint x, jint y, jint width, jint height)
|
||||
{
|
||||
int32_t* data = NULL; /* jint is always four-bytes signed integer */
|
||||
size_t size = width * height;
|
||||
jintArray ret = NULL;
|
||||
|
||||
obj = obj; /* not used */
|
||||
|
||||
data = grab_screen(NULL, x, y, width, height);
|
||||
|
||||
if(!data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = (*env)->NewIntArray(env, size);
|
||||
|
||||
/* updates array with data's content */
|
||||
(*env)->SetIntArrayRegion(env, ret, 0, size, data);
|
||||
free(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture */
|
||||
|
||||
#ifndef _Included_net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture
|
||||
#define _Included_net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture
|
||||
* Method: grabScreen
|
||||
* Signature: (IIII)[I
|
||||
*/
|
||||
JNIEXPORT jintArray JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture_grabScreen
|
||||
(JNIEnv *, jclass, jint, jint, jint, jint);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.neomedia.imgstreaming;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* This class uses native code to capture
|
||||
* desktop screen.
|
||||
*
|
||||
* It should work on all OS with underlying X11.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class UnixScreenCapture
|
||||
{
|
||||
static
|
||||
{
|
||||
System.loadLibrary("screencapture");
|
||||
}
|
||||
|
||||
/**
|
||||
* Capture desktop screen.
|
||||
*
|
||||
* @param x x position to start capture
|
||||
* @param y y position to start capture
|
||||
* @param width capture width
|
||||
* @param height capture height
|
||||
* @return <tt>BufferedImage</tt> of the desktop screen
|
||||
*/
|
||||
public static BufferedImage captureScreen(int x, int y, int width, int height)
|
||||
{
|
||||
DirectColorModel model = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0xFF);
|
||||
int masks[] = {0xFF0000, 0xFF00, 0xFF};
|
||||
WritableRaster raster = null;
|
||||
DataBufferInt buffer = null;
|
||||
BufferedImage image = null;
|
||||
int data[] = null;
|
||||
|
||||
data = grabScreen(x, y, width, height);
|
||||
|
||||
if(data == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
buffer = new DataBufferInt(data, data.length);
|
||||
raster = Raster.createPackedRaster(buffer, width, height, width, masks, null);
|
||||
image = new BufferedImage(model, raster, false, null);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab desktop screen and get ARGB pixels.
|
||||
*
|
||||
* @param x x position to start capture
|
||||
* @param y y position to start capture
|
||||
* @param width capture width
|
||||
* @param height capture height
|
||||
* @return array of ARGB pixels
|
||||
*/
|
||||
private static native int[] grabScreen(int x, int y, int width, int height);
|
||||
}
|
||||
|
||||
Loading…
Reference in new issue