From 6d81880fcbbab385007f4dc026b46a55a546e44d Mon Sep 17 00:00:00 2001 From: Sebastien Vincent Date: Tue, 2 Feb 2010 18:16:45 +0000 Subject: [PATCH] Add Windows native screen grabber, change UnixScreenCapture to NativeScreenCapture as file will be used for Linux, Windows and soon Mac OS X. Add the compiled JNI libraries for Linux (32 and 64-bit), FreeBSD (32 and 64-bit) and Windows (32 and 64-bit). --- lib/native/freebsd-64/libscreencapture.so | Bin 9480 -> 9484 bytes lib/native/freebsd/libscreencapture.so | Bin 7085 -> 7025 bytes lib/native/linux-64/libscreencapture.so | Bin 6784 -> 6784 bytes lib/native/linux/libscreencapture.so | Bin 4832 -> 4848 bytes lib/native/windows-64/screencapture.dll | Bin 0 -> 38780 bytes lib/native/windows/screencapture.dll | Bin 0 -> 57165 bytes src/native/linux/screencapture/Makefile | 32 ++- ...omedia_imgstreaming_NativeScreenCapture.c} | 186 +++++++++++++++++- ...omedia_imgstreaming_NativeScreenCapture.h} | 10 +- .../imgstreaming/DesktopInteractImpl.java | 4 +- ...nCapture.java => NativeScreenCapture.java} | 11 +- .../protocol/imgstreaming/ImageStream.java | 27 ++- 12 files changed, 239 insertions(+), 31 deletions(-) create mode 100755 lib/native/windows-64/screencapture.dll create mode 100644 lib/native/windows/screencapture.dll rename src/native/linux/screencapture/{net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture.c => net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.c} (53%) rename src/native/linux/screencapture/{net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture.h => net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h} (77%) rename src/net/java/sip/communicator/impl/neomedia/imgstreaming/{UnixScreenCapture.java => NativeScreenCapture.java} (87%) diff --git a/lib/native/freebsd-64/libscreencapture.so b/lib/native/freebsd-64/libscreencapture.so index 28c198c61c8bf822e6bb492405b61443e4573868..a592d3a57ac845654e6ca16002e7553fdf045093 100755 GIT binary patch delta 790 zcmZuuO=uHQ5Z>7&n;%o`u9TN`8?)xe#2!onErHJBIC`)WfaZK@({-_cTV!v`XE^BXu+=hyEt<`y*h!DAWmlW7ZrUx3~6kN>< z+GTb)l^$sR!xa+_%W|`Xd*^CIPENP zh3{0O)Wmj9P+M(kL2YMI*~hrx3i}0*X!1T9=HY#;$(qZXoXrQ)%GNoS?=z#N@k!D_ z{4^3^h4=KoYn_3|w>gVC+lKO+SZ04(`FA95-&4Iuv=2uEt)6|LYM#q_dzEYCw0qX! zX*aROYHyVOC+xHTU3PWc{6*@WbEdF_o5gdzaHV)0KMQk4t3B<_d*~V&d@YXs1-|~4 ACjbBd delta 783 zcmZuuO=uHQ5Pp+nH`!1j*;-$=F(%t=+o;gBg(8Ru{?SmBT2S#K8vH>o5}^n2BI2PQ zda!$ zK`I}viZ!V*^wvT#9K(YVE=PVd`x5K6C{}I=0o|Z}v`M;KICfYiYlT(GKMez)q!5wqY-kq|l2UA@(t3rmsxf$OGEj}e#;QpYY`yaL~I z&`keEGqY(YiA1bfMPqtQm<(!H(?TT0(I~g5ak z^iy;k%VkMtG-orKziZmgVQ)n`_xaR3vrx~kXJJA0j6UOP{B5HgD|ye}78%iGg5&Z* zPyVELt!Vs9|Hne7B8`pAoz0K$r9m`YN!wM{*`u=m`P5y^yVAMGRdwHYd;NV+(RQWr u{NKd4=<>uRHL+D0*hk^(E>vex_b%gGb=Tit_8aHUHf9>=m<4?F#{U4fL6m_2 diff --git a/lib/native/freebsd/libscreencapture.so b/lib/native/freebsd/libscreencapture.so index c17e9b022dd2e08234fb107dac7ac871091d35c3..97049f50f5bea8c042bef434d713b722446c4ef0 100755 GIT binary patch literal 7025 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 Chj}Fc literal 7085 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 MDcfLtM!0VH1A=68yZ`_I delta 1165 zcmZ`(TWAwe5Z%e6*);FObT`%5)<#sUZLO`1g0#ViTggX7TMbmKPpqJzZ6(r{R8(XM zf#{$p;)kGAMKBVCT72|F4d|EPhaxByg#-mfR77p#+}(}F4`-P>GiT<^o!!gb(U#Gc zRImAtom1q_$-Wb=UM=`z5nwBLaT`?C_^8Z9T1{F(%EYf4u7<3D7hx@a04s2KMDM9_ z5GInkNh?Wblg=V#Vk7lXeJw_G%^=|sodDgmdi6H07jIG&V-dd69Rw4u*9-82dJ1rj ztvD$fDp=Q|eAOH`;A4F~hzj8)x(oumQPw94c^N(>!ji0rNnU_Tyv(lyf94aP1(?S1^4gw9((y^hu`e`VM`8^(!RQhBTSWd? zNIf@loFs<>B9#nULiboM|ClPJXvt}}obK?RNDa?5-=(;iFh zoJ-S%LcWoeC58jR+ zIhBEOyU<~sv*IkJvf;pHHluWOIM7)b@JPvlK)c$cgVNN}twv9N6$-m|r}7)=7;wbu zt3N{krTa@5{RFY<&fHba3+CeF zaH+G3F6Vk@8+77H=M6|_Lax_(3TnI!<}}T~B%O(RPXKJjsfq@3@m@*j6I#vP+AZtG UC`EsND(5JQX}MVDg)pZ34PhTl0RR91 diff --git a/lib/native/linux/libscreencapture.so b/lib/native/linux/libscreencapture.so index 171eb02312d21fec18e604e87ee5371871254417..521d48aa14cef066e605534b5b2f5a121db9d2ed 100755 GIT binary patch delta 1521 zcmZ8hU1%It6ux(7W_Pxkb!R5qZqja=ZFXW}8$ziO3kh~3nP~l~NxCaV7c@|#kt%{| zK}frl=)g5FopJ^;7^r2R9MqsEh0$zGk#}gc7+}|_q*S@ z=bn4!-ZN*t_pjcM@^b&uo~;ct$p;PalwFD(MII_Mjvd7c#ee-&38&^?Sbm!KL*3 zzv1?npSTaZyUwN`=)C@Hwu*&XdELu6jScvE?iF6Ekew{a485Lwr}*%qd&3)Z)SA1_ z5q`eQ5l=o+b2k_M_2+c9eF7+=%Q1`xZI*| zj6m6TDEjLZsj#@O+z#d>nE0>abp^RPeBX1E&XH_;z2J=QOxd%8#vxb m(O$bp<4j64X%{qZ1r>VF?voYz)b8szgF0V9`c1)C1@a%JNh(kP delta 1522 zcmZ8hU1%It6h61RvpdO7l9|b-J837)W_RKi8)a=3MTHpLvDQY6O}2<48cb|LlcKl< zAJQx(DlAJN;ehnTH=hI{p@O~${sbag(HEg;AEGF1w9tro2sOHXXLfcK51jeV&pki) z-ZOV+aBFZStq^zyYH?^@0z9h5Ep#P8MHQ_m_7QVk3%BLome^ z=ncVX>CzRt4+}@aI$lec4vB_Zy3{2qNI6i1WS2yvExm{0ipqgeKC=9FOKa%w{ZD^8 z)NcW0yAtEZ8b+IRa^##t65kJ@{1i~ue--Ki;y2@B65^1SqSJluVuIN<^}>(-5*Y_bpY1p^x#Y$YJZJF!E)f)O&|7My^DQ z7iM4Q?&zhyXU1pdPfnLk%}<`2CQ%C0rOB6O=(U;osS>{*oo82bEa~|`m`LHEGd!Yo zmkTgUGxqE(ZZ1M&p>78H0eV)#KypFol^zdq2NxK_-0TX%wkMdz8pv_Xh#`ofFa?o0 zDTtYK1X0ixwCFiXi-1jeg1G#nf<2fJL5z1^5QXj)#DG2^i1B||5TpKxAPN^NzbxI< zYrW{V_O5)&SMQDuD7D68@ndR<7ve9dEZ>Mfp{{dIA5tScp&!4q6KB7?l)P21SE63+ z#$WaNo1b*O@g>el^tr!b_qW9KA+PDDQ|IBR7Pl%%ul6g}R{U?p_bA(K6N>m;+bg+) z%l^-mf)}m&Taw}XeaU#y41>-?-JU~toN6B|-_>v~G(#GR7`i*9AYOICdcWzEWhXH-g_UM*gSwb{k)pVI5K|1|O$EGM=3;#4HvJ8OmF3bM^xN^Ozk!@O@*nC?KcU#3g{n%f-{%^ diff --git a/lib/native/windows-64/screencapture.dll b/lib/native/windows-64/screencapture.dll new file mode 100755 index 0000000000000000000000000000000000000000..e1897bc8f167f209cf9c1c7fee8363fe2a8865a6 GIT binary patch literal 38780 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 #include + +#if defined(_WIN32) || defined(_WIN64) + +#define WIN32_LEAN_AND_MEAN +#include +#include + +typedef __int32 int32_t; + +#else /* Unix */ + #include #include @@ -24,7 +35,166 @@ #include #include -#include "net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture.h" +#endif + +#include "net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h" + +#if defined(_WIN32) || defined (_WIN64) + +/** + * \brief Grab Windows screen. + * \param data array that will contain screen capture + * \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(int32_t* data, int32_t x, int32_t y, int32_t w, int32_t h) +{ + static const RGBQUAD redColor = {0x00, 0x00, 0xFF, 0x00}; + static const RGBQUAD greenColor = {0x00, 0xFF, 0x00, 0x00}; + static const RGBQUAD blueColor = {0xFF, 0x00, 0x00, 0x00}; + HDC desktop = NULL; + HDC dest = NULL; + HBITMAP bitmap; + HBITMAP oldBitmap; + int width = 0; + int height = 0; + size_t size = 0; + BITMAPINFO* bitmap_info = NULL; + BITMAPINFOHEADER* bitmap_hdr = NULL; + RGBQUAD *pixels = NULL; + size_t i = 0; + + /* get handle to the entire screen of Windows */ + desktop = GetDC(NULL); + + if(!desktop) + { + fprintf(stderr, "GetDC failed!\n"); + return -1; + } + + /* get resolution */ + width = GetDeviceCaps(desktop, HORZRES); + height = GetDeviceCaps(desktop, VERTRES); + + /* check that user-defined parameters are in image */ + if((w + x) > width || (h + y) > height) + { + ReleaseDC(NULL, desktop); + return -1; + } + + size = w * h; + + /* fprintf(stderr, "Resolution: %dx%d\n", width, height); */ + + dest = CreateCompatibleDC(desktop); + + if(!dest) + { + fprintf(stderr, "CreateCompatibleDC failed!\n"); + ReleaseDC(NULL, desktop); + return -1; + } + + bitmap = CreateCompatibleBitmap(desktop, width, height); + + if(!bitmap) + { + fprintf(stderr, "CreateCompatibleBitmap failed!\n"); + ReleaseDC(NULL, desktop); + return -1; + } + + /* select bitmap to be used by DC */ + oldBitmap = SelectObject(dest, bitmap); + + if(BitBlt(dest, 0, 0, w, h, desktop, x, y, SRCCOPY | CAPTUREBLT) == FALSE) + { + fprintf(stderr, "BitBlt failed\n"); + SelectObject(dest, oldBitmap); /* restore old state before delete */ + DeleteDC(dest); + DeleteObject(bitmap); + ReleaseDC(NULL, desktop); + return -1; + } + + /* allocate memory for bitmap header, it consists + * of header size and the uncompressed pixels + * GetDiBits with BI_BITFIELDS requires array of 3 RBGQUAD + * structures and BITMAPINFO structure has just one allocated + * RGBQUAD array + */ + bitmap_info = malloc(sizeof(BITMAPINFO) + 3 * sizeof(RGBQUAD) + (size * 4)); + + if(!bitmap_info) + { + fprintf(stderr, "malloc failed\n"); + SelectObject(dest, oldBitmap); /* restore old state before delete */ + DeleteDC(dest); + DeleteObject(bitmap); + ReleaseDC(NULL, desktop); + return -1; + } + + bitmap_hdr = &bitmap_info->bmiHeader; + + bitmap_hdr->biSize = sizeof(BITMAPINFOHEADER); + bitmap_hdr->biWidth = w; + bitmap_hdr->biHeight = -h; /* otherwise inverse screen */ + bitmap_hdr->biPlanes = 1; + bitmap_hdr->biCompression = BI_BITFIELDS; + bitmap_hdr->biBitCount = 32; + bitmap_hdr->biSizeImage = 0; + bitmap_hdr->biXPelsPerMeter = 0; + bitmap_hdr->biYPelsPerMeter = 0; + bitmap_hdr->biClrImportant = 0; + bitmap_hdr->biClrUsed = 0; + + /* set up color */ + /* red */ + bitmap_info->bmiColors[0] = redColor; + /* green */ + bitmap_info->bmiColors[1] = greenColor; + /* blue */ + bitmap_info->bmiColors[2] = blueColor; + + /* first data pixel begins after the array of color mask */ + pixels = &bitmap_info->bmiColors[2]; + pixels++; + + /* get raw bytes */ + if(GetDIBits(dest, bitmap, 0, height, pixels, bitmap_info, DIB_RGB_COLORS) == 0) + { + fprintf(stderr, "GetDIBits failed!\n"); + free(bitmap_info); + SelectObject(dest, oldBitmap); /* restore old state before delete */ + DeleteDC(dest); + DeleteObject(bitmap); + ReleaseDC(NULL, desktop); + return -1; + } + + for(i = 0 ; i < size ; i++) + { + RGBQUAD* pixel = &pixels[i]; + data[i] = 0xFF000000 | pixel->rgbRed << 16 | pixel->rgbGreen << 8 | pixel->rgbBlue; + } + + /* cleanup */ + free(bitmap_info); + SelectObject(dest, oldBitmap); /* restore old state before delete */ + DeleteDC(dest); + DeleteObject(bitmap); + ReleaseDC(NULL, desktop); + + return 0; +} + +#else /* Unix */ /** * \brief Grab X11 screen. @@ -190,18 +360,20 @@ static int x11_grab_screen(const char* x11display, int32_t* data, int32_t x, int return 0; } +#endif + /** * \brief JNI native method to grab desktop screen and retrieve ARGB pixels. * \param env JVM environment - * \param obj UnixScreenCapture Java object + * \param obj NativeScreenCapture Java class * \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 (jint) */ -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) +JNIEXPORT jintArray JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen + (JNIEnv* env, jclass 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; @@ -223,7 +395,11 @@ JNIEXPORT jintArray JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstre return NULL; } +#if defined (_WIN32) || defined(_WIN64) + if(windows_grab_screen(data, x, y, width, height) == -1) +#else /* Unix */ if(x11_grab_screen(NULL, data, x, y, width, height) == -1) +#endif { (*env)->ReleaseIntArrayElements(env, ret, data, 0); return NULL; diff --git a/src/native/linux/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture.h b/src/native/linux/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h similarity index 77% rename from src/native/linux/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture.h rename to src/native/linux/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h index 7f6cce8cf..7c9d4dcde 100644 --- a/src/native/linux/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture.h +++ b/src/native/linux/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h @@ -1,18 +1,18 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include -/* Header for class net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture */ +/* Header for class net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture */ -#ifndef _Included_net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture -#define _Included_net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture +#ifndef _Included_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture +#define _Included_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture #ifdef __cplusplus extern "C" { #endif /* - * Class: net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture + * Class: net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture * Method: grabScreen * Signature: (IIII)[I */ -JNIEXPORT jintArray JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_UnixScreenCapture_grabScreen +JNIEXPORT jintArray JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen (JNIEnv *, jclass, jint, jint, jint, jint); #ifdef __cplusplus diff --git a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java index 581718943..4c4a9289b 100644 --- a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java @@ -74,9 +74,9 @@ public BufferedImage captureScreen(int x, int y, int width, int height) BufferedImage img = null; Rectangle rect = null; - if(OSUtils.IS_LINUX || OSUtils.IS_FREEBSD) + if(OSUtils.IS_LINUX || OSUtils.IS_FREEBSD || OSUtils.IS_WINDOWS) { - return UnixScreenCapture.captureScreen(x, y, width, height); + return NativeScreenCapture.captureScreen(x, y, width, height); } else { diff --git a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/UnixScreenCapture.java b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java similarity index 87% rename from src/net/java/sip/communicator/impl/neomedia/imgstreaming/UnixScreenCapture.java rename to src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java index 2347d43a7..9090849cf 100644 --- a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/UnixScreenCapture.java +++ b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java @@ -10,13 +10,12 @@ /** * This class uses native code to capture - * desktop screen. - * - * It should work on all OS with underlying X11. + * desktop screen. It should work for Windows and + * X11-based Unix such as Linux and FreeBSD. * * @author Sebastien Vincent */ -public class UnixScreenCapture +public class NativeScreenCapture { static { @@ -38,8 +37,8 @@ public static BufferedImage captureScreen(int x, int height) { DirectColorModel model - = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0xFF); - int masks[] = {0xFF0000, 0xFF00, 0xFF}; + = new DirectColorModel(32, 0xFF0000, 0x00FF00, 0xFF, 0xFF000000); + int masks[] = {0xFF0000, 0xFF00, 0xFF, 0xFF000000}; WritableRaster raster = null; DataBufferInt buffer = null; BufferedImage image = null; diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java index d359344d5..c938bc487 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java +++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java @@ -180,13 +180,26 @@ public void run() /* get desktop screen and resize it */ screen = desktopInteract.captureScreen(); - scaledScreen - = ImageStreamingUtils - .getScaledImage( - screen, - width, - height, - BufferedImage.TYPE_INT_ARGB); + + if(OSUtils.IS_LINUX || OSUtils.IS_FREEBSD || OSUtils.IS_WINDOWS) + { + /* with our native screencapture we + * automatically create BufferedImage in + * ARGB format so no need to rescale/convert + * to ARGB + */ + scaledScreen = screen; + } + else + { + scaledScreen + = ImageStreamingUtils + .getScaledImage( + screen, + width, + height, + BufferedImage.TYPE_INT_ARGB); + } /* get raw bytes */ data = ImageStreamingUtils.getImageBytes(scaledScreen);