Each screen display has now its own capture device. Note that on Linux, multiple monitors are seen as one screen.

JAWTRenderer on Linux will not display image > 2048x2048 due to driver limitation (XvCreateImage), so avoid dropping image if size mismatch and show what we can.
cusax-fix
Sebastien Vincent 16 years ago
parent 5a799d3efe
commit 53d72aa039

@ -293,7 +293,12 @@ _JAWTRenderer_createImage(JAWTRenderer *renderer)
image = renderer->image;
width = renderer->dataWidth;
height = renderer->dataHeight;
if (image && ((image->width != width) || (image->height != height)))
/* XvCreateImage is limited to 2048x2048 image so do not drop image
* if size exceed the limit
*/
if (image && ((image->width != width) || (image->height != height)) &&
width < 2048 && height < 2048)
{
XFree(image);
image = NULL;
@ -307,11 +312,16 @@ _JAWTRenderer_createImage(JAWTRenderer *renderer)
renderer->imageFormatID,
NULL,
width, height);
/*
* XvCreateImage is documented to enlarge width and height for some YUV
* formats. But I don't know how to handle such a situation.
*/
if (image && ((image->width != width) || (image->height != height)))
/* XvCreateImage is limited to 2048x2048 image so do not drop image
* if size exceed this limit
*/
if (image && ((image->width != width) || (image->height != height)) &&
width < 2048 && height < 2048)
{
XFree(image);
image = NULL;

@ -50,16 +50,83 @@ typedef unsigned __int8 uint8_t;
#if defined(_WIN32) || defined (_WIN64)
/**
* \struct monitor_data
* \brief Used with monitorCallback to pass index and receive DC
*/
struct monitor_data
{
unsigned int monitor_index; /**< Index of the specific monitor */
unsigned int current_index; /**< Internal index of monitor in callback */
HDC monitor_dc; /**< DC of the monitor (set by monitorCallback if any) */
};
/**
* \brief Callback when using EnumDisplayMonitors function.
* \param hMonitor monitor object
* \param hdcMonitor DC passed from EnumDisplayMonitors
* \param lpcrMonitor clipping rectangle
* \param dwData additionnal data
* \return true if enumeration have to be stopped, false otherwise
*/
BOOL CALLBACK monitorCallback(HMONITOR hMonitor, HDC hdcMonitor,
LPRECT lprcMonitor, LPARAM dwData)
{
struct monitor_data* data = (struct monitor_data*)dwData;
MONITORINFOEX info;
/* avoid warnings */
hdcMonitor = hdcMonitor;
lprcMonitor = lprcMonitor;
if(data->current_index == data->monitor_index)
{
info.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfo(hMonitor, (LPMONITORINFO)&info);
/* create the DC for this monitor */
data->monitor_dc = CreateDC(info.szDevice, info.szDevice, NULL, NULL);
/* found the right monitor, breaks */
return FALSE;
}
data->current_index++;
return TRUE;
}
/**
* \brief Get DC pointer for a specific display.
* \param display display index.
* \return DC pointer or NULL if failure
*/
static HDC get_dc(unsigned int index)
{
HDC hDC = NULL;
struct monitor_data data;
data.monitor_index = index;
data.current_index = 0;
data.monitor_dc = NULL;
EnumDisplayMonitors(NULL, NULL, &monitorCallback, (LPARAM)&data);
hDC = data.monitor_dc;
return hDC;
}
/**
* \brief Grab Windows screen.
* \param data array that will contain screen capture
* \param display display index
* \param x x position to start capture
* \param y y position to start capture
* \param w capture width
* \param h capture height
* \return 0 if success, -1 otherwise
*/
static int windows_grab_screen(jbyte* data, int32_t x, int32_t y, int32_t w, int32_t h)
static int windows_grab_screen(jbyte* data, unsigned int display, int x, int y, int w, int h)
{
static const RGBQUAD redColor = {0x00, 0x00, 0xFF, 0x00};
static const RGBQUAD greenColor = {0x00, 0xFF, 0x00, 0x00};
@ -79,8 +146,8 @@ static int windows_grab_screen(jbyte* data, int32_t x, int32_t y, int32_t w, int
uint32_t test = 1;
int little_endian = *((uint8_t*)&test);
/* get handle to the entire screen of Windows */
desktop = GetDC(NULL);
/* get handle corresponding to the display specified */
desktop = get_dc(display);
if(!desktop)
{
@ -107,7 +174,7 @@ static int windows_grab_screen(jbyte* data, int32_t x, int32_t y, int32_t w, int
if(!dest)
{
fprintf(stderr, "CreateCompatibleDC failed!\n");
fprintf(stderr, "CreateCompatibleDC failed!\n");
ReleaseDC(NULL, desktop);
return -1;
}
@ -224,13 +291,14 @@ static int windows_grab_screen(jbyte* data, int32_t x, int32_t y, int32_t w, int
/**
* \brief Grab Mac OS X screen (with Quartz API).
* \param data array that will contain screen capture
* \param display display index
* \param x x position to start capture
* \param y y position to start capture
* \param w capture width
* \param h capture height
* \return 0 if success, -1 otherwise
*/
static int quartz_grab_screen(jbyte* data, int32_t x, int32_t y, int32_t w, int32_t h)
static int quartz_grab_screen(jbyte* data, unsigned int display, int x, int y, int w, int h)
{
CGImageRef img = NULL;
CGDataProviderRef provider = NULL;
@ -242,8 +310,26 @@ static int quartz_grab_screen(jbyte* data, int32_t x, int32_t y, int32_t w, int3
CGRect rect;
uint32_t test = 1;
int little_endian = *((uint8_t*)&test);
CGDirectDisplayID displayIds[16];
CGDisplayCount displayNb = 0;
rect = CGRectMake(x, y, w, h);
/* find display */
if(CGGetActiveDisplayList(display + 1, displayIds, &displayNb) != kCGErrorSuccess)
{
return -1;
}
if(displayNb < (display + 1))
{
/* request a non existent display */
return -1;
}
rect = CGDisplayBounds(displayIds[display]);
rect.size.width = w;
rect.size.height = h;
rect.origin.x += x;
rect.origin.y += y;
img = CGWindowListCreateImage(rect, kCGWindowListOptionOnScreenOnly, kCGNullWindowID, kCGWindowImageDefault);
if(img == NULL)
@ -291,13 +377,14 @@ static int quartz_grab_screen(jbyte* data, int32_t x, int32_t y, int32_t w, int3
* \brief Grab X11 screen.
* \param x11display display string (i.e. :0.0), if NULL getenv("DISPLAY") is used
* \param data array that will contain screen capture
* \param displayIndex display index
* \param x x position to start capture
* \param y y position to start capture
* \param w capture width
* \param h capture height
* \return 0 if success, -1 otherwise
*/
static int x11_grab_screen(const char* x11display, jbyte* data, int32_t x, int32_t y, int32_t w, int32_t h)
static int x11_grab_screen(jbyte* data, unsigned int displayIndex, int x, int y, int w, int h)
{
const char* display_str; /* display string */
Display* display = NULL; /* X11 display */
@ -316,14 +403,10 @@ static int x11_grab_screen(const char* x11display, jbyte* data, int32_t x, int32
size_t size = 0;
uint32_t test = 1;
int little_endian = *((uint8_t*)&test);
char buf[16];
display_str = x11display ? x11display : getenv("DISPLAY");
if(!display_str)
{
/* fprintf(stderr, "No display!\n"); */
return -1;
}
snprintf(buf, sizeof(buf), ":0.%u", displayIndex);
display_str = buf;
/* open current X11 display */
display = XOpenDisplay(display_str);
@ -463,6 +546,7 @@ static int x11_grab_screen(const char* x11display, jbyte* data, int32_t x, int32
* \brief JNI native method to grab desktop screen and retrieve ARGB pixels.
* \param env JVM environment
* \param clazz NativeScreenCapture Java class
* \param display display index
* \param x x position to start capture
* \param y y position to start capture
* \param width capture width
@ -470,8 +554,8 @@ static int x11_grab_screen(const char* x11display, jbyte* data, int32_t x, int32
* \param output output buffer, screen bytes will be stored in
* \return true if success, false otherwise
*/
JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen__IIII_3B
(JNIEnv* env, jclass clazz, jint x, jint y, jint width, jint height, jbyteArray output)
JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen__IIIII_3B
(JNIEnv* env, jclass clazz, jint display, jint x, jint y, jint width, jint height, jbyteArray output)
{
jint size = width * height * 4;
jbyte* data = NULL;
@ -491,11 +575,11 @@ JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstrea
}
#if defined (_WIN32) || defined(_WIN64)
if(windows_grab_screen(data, x, y, width, height) == -1)
if(windows_grab_screen(data, display, x, y, width, height) == -1)
#elif defined(__APPLE__)
if(quartz_grab_screen(data, x, y, width, height) == -1)
if(quartz_grab_screen(data, display, x, y, width, height) == -1)
#else /* Unix */
if(x11_grab_screen(NULL, data, x, y, width, height) == -1)
if(x11_grab_screen(data, display, x, y, width, height) == -1)
#endif
{
(*env)->ReleasePrimitiveArrayCritical(env, output, data, 0);
@ -510,6 +594,7 @@ JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstrea
* \brief JNI native method to grab desktop screen and retrieve ARGB pixels.
* \param env JVM environment
* \param clazz NativeScreenCapture Java class
* \param display display index
* \param x x position to start capture
* \param y y position to start capture
* \param width capture width
@ -517,8 +602,8 @@ JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstrea
* \param output native output buffer
* \return true if success, false otherwise
*/
JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen__IIIIJI
(JNIEnv* env, jclass clazz, jint x, jint y, jint width, jint height, jlong output, jint outputLength)
JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen__IIIIIJI
(JNIEnv* env, jclass clazz, jint display, jint x, jint y, jint width, jint height, jlong output, jint outputLength)
{
jint size = width * height * 4;
jbyte* data = (jbyte*)output;
@ -533,11 +618,11 @@ JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstrea
}
#if defined (_WIN32) || defined(_WIN64)
if(windows_grab_screen(data, x, y, width, height) == -1)
if(windows_grab_screen(data, display, x, y, width, height) == -1)
#elif defined(__APPLE__)
if(quartz_grab_screen(data, x, y, width, height) == -1)
if(quartz_grab_screen(data, display, x, y, width, height) == -1)
#else /* Unix */
if(x11_grab_screen(NULL, data, x, y, width, height) == -1)
if(x11_grab_screen(data, display, x, y, width, height) == -1)
#endif
{
return JNI_FALSE;
@ -545,4 +630,4 @@ JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstrea
return JNI_TRUE;
}

@ -10,10 +10,10 @@ extern "C" {
/*
* Class: net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture
* Method: grabScreen
* Signature: (IIII[B)Z
* Signature: (IIIII[B)Z
*/
JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen__IIII_3B
(JNIEnv *, jclass, jint, jint, jint, jint, jbyteArray);
JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen__IIIII_3B
(JNIEnv *, jclass, jint, jint, jint, jint, jint, jbyteArray);
/*
* Class: net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture

@ -6,8 +6,16 @@
*/
package net.java.sip.communicator.impl.neomedia.device;
import java.util.List;
import java.awt.*;
import javax.media.*;
import javax.media.format.*;
import net.java.sip.communicator.service.neomedia.device.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.impl.neomedia.codec.video.*;
import net.java.sip.communicator.impl.neomedia.*;
import net.java.sip.communicator.impl.neomedia.imgstreaming.*;
import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.imgstreaming.*;
@ -25,16 +33,78 @@ public class ImageStreamingAuto
*/
public ImageStreamingAuto() throws Exception
{
String name = "Desktop Streaming (Experimental)";
CaptureDeviceInfo devInfo
= new CaptureDeviceInfo(
name,
new MediaLocator(
ImageStreamingUtils.LOCATOR_PROTOCOL + ":" + name),
DataSource.getFormats());
/* add to JMF device manager */
CaptureDeviceManager.addDevice(devInfo);
String name = "Desktop Streaming";
List<ScreenDevice> screens = NeomediaActivator.getMediaServiceImpl().
getAvailableScreenDevices();
int i = 0;
boolean multipleMonitorOneScreen = false;
Dimension screenSize = null;
/* on Linux, multiple monitors may result in only one
* X display (:0.0) that combine those monitors
*/
if(OSUtils.IS_LINUX)
{
Dimension size = new Dimension(0, 0);
for(ScreenDevice screen : screens)
{
size.width += screen.getSize().width;
size.height += screen.getSize().height;
}
try
{
screenSize = Toolkit.getDefaultToolkit().getScreenSize();
if(screenSize.width == size.width ||
screenSize.height == size.height)
{
multipleMonitorOneScreen = true;
}
}
catch(Exception e)
{
}
}
for(ScreenDevice screen : screens)
{
Dimension size = screenSize != null ? screenSize : screen.getSize();
Format formats[]= new Format[]
{
new AVFrameFormat(
size,
Format.NOT_SPECIFIED,
FFmpeg.PIX_FMT_ARGB,
Format.NOT_SPECIFIED),
new RGBFormat(
size, // size
Format.NOT_SPECIFIED, // maxDataLength
Format.byteArray, // dataType
Format.NOT_SPECIFIED, // frameRate
32, // bitsPerPixel
2 /* red */, 3 /* green */, 4 /* blue */)
};
CaptureDeviceInfo devInfo
= new CaptureDeviceInfo(
name + " " + i,
new MediaLocator(
ImageStreamingUtils.LOCATOR_PROTOCOL + ":" + i),
formats);
/* add to JMF device manager */
CaptureDeviceManager.addDevice(devInfo);
i++;
if(multipleMonitorOneScreen)
{
break;
}
}
CaptureDeviceManager.commit();
}
}

@ -26,11 +26,12 @@ public interface DesktopInteract
* 9 MB of memory for grabbing and another 9 MB array for conversion
* operation.
*
* @param display index of display
* @param output output buffer to store bytes in.
* Be sure that output length is sufficient
* @return true if success, false if JNI error or output length too short
*/
public boolean captureScreen(byte output[]);
public boolean captureScreen(int display, byte output[]);
/**
* Capture the full desktop screen using native grabber.
@ -42,12 +43,13 @@ public interface DesktopInteract
* 9 MB of memory for grabbing and another 9 MB array for conversion
* operation.
*
* @param display index of display
* @param buffer native output buffer to store bytes in.
* Be sure that output length is sufficient
* @param bufferLength length of native buffer
* @return true if success, false if JNI error or output length too short
*/
public boolean captureScreen(long buffer, int bufferLength);
public boolean captureScreen(int display, long buffer, int bufferLength);
/**
* Capture a part of the desktop screen using native grabber.
@ -59,6 +61,7 @@ public interface DesktopInteract
* 9 MB of memory for grabbing and another 9 MB array for conversion
* operation.
*
* @param display index of display
* @param x x position to start capture
* @param y y position to start capture
* @param width capture width
@ -67,7 +70,7 @@ public interface DesktopInteract
* Be sure that output length is sufficient
* @return true if success, false if JNI error or output length too short
*/
public boolean captureScreen(int x, int y, int width, int height,
public boolean captureScreen(int display, int x, int y, int width, int height,
byte output[]);
/**
@ -80,6 +83,7 @@ public boolean captureScreen(int x, int y, int width, int height,
* 9 MB of memory for grabbing and another 9 MB array for conversion
* operation.
*
* @param display index of display
* @param x x position to start capture
* @param y y position to start capture
* @param width capture width
@ -89,7 +93,7 @@ public boolean captureScreen(int x, int y, int width, int height,
* @param bufferLength length of native buffer
* @return true if success, false if JNI error or output length too short
*/
public boolean captureScreen(int x, int y, int width, int height,
public boolean captureScreen(int display, int x, int y, int width, int height,
long buffer, int bufferLength);
/**

@ -54,15 +54,16 @@ public DesktopInteractImpl() throws AWTException, SecurityException
* 9 MB of memory for grabbing and another 9 MB array for conversion
* operation.
*
* @param display index of display
* @param output output buffer to store bytes in.
* Be sure that output length is sufficient
* @return true if success, false if JNI error or output length too short
*/
public boolean captureScreen(byte output[])
public boolean captureScreen(int display, byte output[])
{
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
return captureScreen(0, 0, dim.width, dim.height,
return captureScreen(display, 0, 0, dim.width, dim.height,
output);
}
@ -76,15 +77,16 @@ public boolean captureScreen(byte output[])
* 9 MB of memory for grabbing and another 9 MB array for conversion
* operation.
*
* @param display index of display
* @param buffer native output buffer to store bytes in.
* Be sure that output length is sufficient
* @param bufferLength length of native buffer
* @return true if success, false if JNI error or output length too short
*/
public boolean captureScreen(long buffer, int bufferLength)
public boolean captureScreen(int display, long buffer, int bufferLength)
{
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
return captureScreen(0, 0, dim.width, dim.height, buffer, bufferLength);
return captureScreen(display, 0, 0, dim.width, dim.height, buffer, bufferLength);
}
/**
@ -97,6 +99,7 @@ public boolean captureScreen(long buffer, int bufferLength)
* 9 MB of memory for grabbing and another 9 MB array for conversion
* operation.
*
* @param display index of display
* @param x x position to start capture
* @param y y position to start capture
* @param width capture width
@ -105,14 +108,14 @@ public boolean captureScreen(long buffer, int bufferLength)
* Be sure that output length is sufficient
* @return true if success, false if JNI error or output length too short
*/
public boolean captureScreen(int x, int y, int width, int height,
public boolean captureScreen(int display, int x, int y, int width, int height,
byte output[])
{
if(OSUtils.IS_LINUX || OSUtils.IS_FREEBSD || OSUtils.IS_WINDOWS
|| OSUtils.IS_MAC)
{
return NativeScreenCapture.grabScreen(
x, y, width, height, output);
display, x, y, width, height, output);
}
return false;
@ -128,6 +131,7 @@ public boolean captureScreen(int x, int y, int width, int height,
* 9 MB of memory for grabbing and another 9 MB array for conversion
* operation.
*
* @param display index of display
* @param x x position to start capture
* @param y y position to start capture
* @param width capture width
@ -137,14 +141,14 @@ public boolean captureScreen(int x, int y, int width, int height,
* @param bufferLength length of native buffer
* @return true if success, false if JNI error or output length too short
*/
public boolean captureScreen(int x, int y, int width, int height,
public boolean captureScreen(int display, int x, int y, int width, int height,
long buffer, int bufferLength)
{
if(OSUtils.IS_LINUX || OSUtils.IS_FREEBSD || OSUtils.IS_WINDOWS
|| OSUtils.IS_MAC)
{
return NativeScreenCapture.grabScreen(
x, y, width, height, buffer, bufferLength);
display, x, y, width, height, buffer, bufferLength);
}
return false;

@ -24,6 +24,7 @@ public class NativeScreenCapture
/**
* Grab desktop screen and get raw bytes.
*
* @param display index of display
* @param x x position to start capture
* @param y y position to start capture
* @param width capture width
@ -31,12 +32,13 @@ public class NativeScreenCapture
* @param output output buffer to store screen bytes
* @return true if grab success, false otherwise
*/
public static native boolean grabScreen(int x, int y, int width, int height,
public static native boolean grabScreen(int display, int x, int y, int width, int height,
byte output[]);
/**
* Grab desktop screen and get raw bytes.
*
* @param display index of display
* @param x x position to start capture
* @param y y position to start capture
* @param width capture width
@ -45,6 +47,6 @@ public static native boolean grabScreen(int x, int y, int width, int height,
* @param outputLength native output length
* @return true if grab success, false otherwise
*/
public static native boolean grabScreen(int x, int y, int width, int height,
public static native boolean grabScreen(int display, int x, int y, int width, int height,
long output, int outputLength);
}

@ -26,34 +26,6 @@
public class DataSource
extends AbstractPullBufferCaptureDevice
{
/**
* The list of supported formats.
*/
private static final Format[] FORMATS;
static
{
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
FORMATS
= new Format[]
{
new AVFrameFormat(
screenSize,
Format.NOT_SPECIFIED,
FFmpeg.PIX_FMT_ARGB,
Format.NOT_SPECIFIED),
new RGBFormat(
screenSize, // size
Format.NOT_SPECIFIED, // maxDataLength
Format.byteArray, // dataType
Format.NOT_SPECIFIED, // frameRate
32, // bitsPerPixel
2 /* red */, 3 /* green */, 4 /* blue */)
};
}
/**
* Initializes a new <tt>DataSource</tt> instance.
*/
@ -92,16 +64,9 @@ protected AbstractPullBufferStream createStream(
int streamIndex,
FormatControl formatControl)
{
return new ImageStream(formatControl);
}
/**
* Gets the list of supported formats.
*
* @return the list of supported formats
*/
public static Format[] getFormats()
{
return FORMATS;
int index = Integer.parseInt(getLocator().getRemainder());
ImageStream stream = new ImageStream(formatControl);
stream.setDisplayIndex(index);
return stream;
}
}

@ -54,6 +54,11 @@ public class ImageStream
*/
private boolean reinit = false;
/**
* Index of display that we will capture from.
*/
private int displayIndex = -1;
/**
* Initializes a new <tt>ImageStream</tt> instance which is to have a
* specific <tt>FormatControl</tt>
@ -126,9 +131,15 @@ public void read(Buffer buffer)
data.ptr,
bufferFrameFormat.getPixFmt(),
bufferFrameSize.width, bufferFrameSize.height);
buffer.setData(bufferFrame);
}
else
{
/* this can happen when we disconnect a monitor from computer
* before or during grabbing
*/
throw new IOException("Failed to grab screen");
}
buffer.setData(bufferFrame);
}
else
{
@ -137,7 +148,8 @@ public void read(Buffer buffer)
if((dataByte != null) || (dataLength != 0))
{
byte buf[] = readScreen(dataByte);
Dimension bufferFrameSize = ((VideoFormat)bufferFormat).getSize();
byte buf[] = readScreen(dataByte, bufferFrameSize);
if(buf != dataByte)
{
@ -183,6 +195,16 @@ public void read(Buffer buffer)
}
}
/**
* Set display index.
*
* @param index display index
*/
public void setDisplayIndex(int index)
{
displayIndex = index;
}
/**
* Start desktop capture stream.
*
@ -202,6 +224,7 @@ public void start()
logger.warn("Cannot create DesktopInteract object!");
}
}
reinit = true;
}
@ -247,17 +270,19 @@ else if(data.capacity < size)
}
/* get desktop screen via native grabber */
return desktopInteract.captureScreen(data.ptr, data.getLength());
return desktopInteract.captureScreen(displayIndex, 0, 0, dim.width,
dim.height, data.ptr, data.getLength());
}
/**
* Read screen.
*
* @param output output buffer for screen bytes
* @param dim dimension of the screen
* @return raw bytes, it could be equal to output or not. Take care in the
* caller to check if output is the returned value.
*/
public byte[] readScreen(byte output[])
public byte[] readScreen(byte output[], Dimension dim)
{
VideoFormat format = (VideoFormat) getFormat();
Dimension formatSize = format.getSize();
@ -278,7 +303,8 @@ public byte[] readScreen(byte output[])
}
/* get desktop screen via native grabber if available */
if(desktopInteract.captureScreen(output))
if(desktopInteract.captureScreen(displayIndex, 0, 0, dim.width,
dim.height, output))
{
return output;
}
@ -290,6 +316,7 @@ public byte[] readScreen(byte output[])
*
* Note that it is very memory consuming since memory are allocated
* to capture screen (via Robot) and then for converting to raw bytes
* Moreover support for multiple display has not yet been investigated
*
* Normally not of our supported platform (Windows (x86, x64),
* Linux (x86, x86-64), Mac OS X (i386, x86-64, ppc) and

Loading…
Cancel
Save