< prev index next >

modules/javafx.graphics/src/main/native-glass/win/Robot.cpp

Print this page




 251     }
 252     if (buttons & (1 << 4)) {
 253         mouseInput.mi.dwFlags |= MOUSEEVENTF_XUP;
 254         mouseInput.mi.mouseData = XBUTTON2;
 255     }
 256 
 257     ::SendInput(1, &mouseInput, sizeof(mouseInput));
 258 }
 259 
 260 /*
 261  * Class:     com_sun_glass_ui_win_WinRobot
 262  * Method:    _mouseWheel
 263  * Signature: (I)V
 264  */
 265 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinRobot__1mouseWheel
 266     (JNIEnv *env, jobject jrobot, jint wheelAmt)
 267 {
 268     ::mouse_event(MOUSEEVENTF_WHEEL, 0, 0, wheelAmt * -1 * WHEEL_DELTA, 0);
 269 }
 270 
 271 void GetScreenCapture(jint x, jint y, jint devw, jint devh,
 272                       jint *pixelData, jint retw, jint reth);
 273 
 274 /*
 275  * Class:     com_sun_glass_ui_win_WinRobot
 276  * Method:    _getPixelColor
 277  * Signature: (II)I
 278  */
 279 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_win_WinRobot__1getPixelColor
 280     (JNIEnv *env, jobject jrobot, jint x, jint y)
 281 {
 282     jfloat fx = (jfloat) x + 0.5f;
 283     jfloat fy = (jfloat) y + 0.5f;
 284     GlassScreen::FX2Win(&fx, &fy);
 285     jint dx = (jint) fx;
 286     jint dy = (jint) fy;
 287 
 288     jint val = 0;
 289     //NOTE: we don't use the ::GetPixel() on the screen DC because it's not capable of
 290     //      getting the correct colors when non-opaque windows are present
 291     GetScreenCapture(dx, dy, 1, 1, &val, 1, 1);
 292     return val;
 293 }
 294 
 295 /*
 296  * Class:     com_sun_glass_ui_win_WinRobot
 297  * Method:    _getScreenCapture
 298  * Signature: (IIII[I;)V
 299  */
 300 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinRobot__1getScreenCapture
 301     (JNIEnv *env, jobject jrobot, jint x, jint y, jint width, jint height, jintArray pixelArray)
 302 {
 303     int numPixels = width * height;
 304     int pixelDataSize = sizeof(jint) * numPixels;
 305     ASSERT(pixelDataSize > 0 && pixelDataSize % 4 == 0);
 306 
 307     jint * pixelData = (jint *)(new BYTE[pixelDataSize]);
 308 
 309     if (pixelData) {
 310         GetScreenCapture(x, y, width, height, pixelData, width, height);
 311 
 312         // copy pixels into Java array
 313         env->SetIntArrayRegion(pixelArray, 0, numPixels, pixelData);
 314         delete[] pixelData;
 315     }
 316 }
 317 
 318 void GetScreenCapture(jint x, jint y, jint devw, jint devh,
 319                       jint *pixelData, jint retw, jint reth)
 320 {
 321     HDC hdcScreen = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
 322     HDC hdcMem = ::CreateCompatibleDC(hdcScreen);
 323     HBITMAP hbitmap;
 324     HBITMAP hOldBitmap;
 325     HPALETTE hOldPalette = NULL;
 326 
 327     // create an offscreen bitmap
 328     hbitmap = ::CreateCompatibleBitmap(hdcScreen, retw, reth);
 329     if (hbitmap == NULL) {
 330         //TODO: OOM might be better?
 331         //throw std::bad_alloc();
 332     }
 333     hOldBitmap = (HBITMAP)::SelectObject(hdcMem, hbitmap);
 334 
 335     /* TODO: check this out
 336     // REMIND: not multimon-friendly...
 337     int primaryIndex = AwtWin32GraphicsDevice::GetDefaultDeviceIndex();
 338     hOldPalette =
 339         AwtWin32GraphicsDevice::SelectPalette(hdcMem, primaryIndex);
 340     AwtWin32GraphicsDevice::RealizePalette(hdcMem, primaryIndex);
 341     */
 342 
 343     // copy screen image to offscreen bitmap
 344     // CAPTUREBLT flag is required to capture WS_EX_LAYERED windows' contents
 345     // correctly on Win2K/XP
 346     static const DWORD dwRop = SRCCOPY|CAPTUREBLT;
 347     if (retw == devw && reth == devh) {
 348         ::BitBlt(hdcMem, 0, 0, retw, reth, hdcScreen, x, y, dwRop);
 349     } else {
 350         ::StretchBlt(hdcMem, 0, 0, retw, reth, hdcScreen, x, y, devw, devh, dwRop);
 351     }
 352 
 353     static const int BITS_PER_PIXEL = 32;
 354 
 355     struct {
 356         BITMAPINFOHEADER bmiHeader;
 357         RGBQUAD          bmiColors[3];
 358     } BitmapInfo;
 359 
 360     // prepare BITMAPINFO for a 32-bit RGB bitmap
 361     ::memset(&BitmapInfo, 0, sizeof(BitmapInfo));
 362     BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 363     BitmapInfo.bmiHeader.biWidth = retw;
 364     BitmapInfo.bmiHeader.biHeight = -reth; // negative height means a top-down DIB
 365     BitmapInfo.bmiHeader.biPlanes = 1;
 366     BitmapInfo.bmiHeader.biBitCount = BITS_PER_PIXEL;
 367     BitmapInfo.bmiHeader.biCompression = BI_BITFIELDS;
 368 
 369     // Setup up color masks
 370     static const RGBQUAD redMask =   {0, 0, 0xFF, 0};
 371     static const RGBQUAD greenMask = {0, 0xFF, 0, 0};
 372     static const RGBQUAD blueMask =  {0xFF, 0, 0, 0};
 373 
 374     BitmapInfo.bmiColors[0] = redMask;
 375     BitmapInfo.bmiColors[1] = greenMask;
 376     BitmapInfo.bmiColors[2] = blueMask;
 377 
 378     // Get the bitmap data in device-independent, 32-bit packed pixel format
 379     ::GetDIBits(hdcMem, hbitmap, 0, reth, pixelData, (BITMAPINFO *)&BitmapInfo, DIB_RGB_COLORS);
 380 
 381     // convert Win32 pixel format (BGRX) to Java format (ARGB)
 382     ASSERT(sizeof(jint) == sizeof(RGBQUAD));
 383     jint numPixels = retw * reth;
 384     jint *pPixel = pixelData;
 385     for(int nPixel = 0; nPixel < numPixels; nPixel++) {
 386         RGBQUAD * prgbq = (RGBQUAD *) pPixel;
 387         *pPixel++ = WinToJavaPixel(prgbq->rgbRed, prgbq->rgbGreen, prgbq->rgbBlue);
 388     }
 389 
 390     // free all the GDI objects we made
 391     ::SelectObject(hdcMem, hOldBitmap);
 392     if (hOldPalette != NULL) {
 393         ::SelectPalette(hdcMem, hOldPalette, FALSE);
 394     }
 395     ::DeleteObject(hbitmap);
 396     ::DeleteDC(hdcMem);
 397     ::DeleteDC(hdcScreen);
 398 }
 399 
 400 }
 401 


 251     }
 252     if (buttons & (1 << 4)) {
 253         mouseInput.mi.dwFlags |= MOUSEEVENTF_XUP;
 254         mouseInput.mi.mouseData = XBUTTON2;
 255     }
 256 
 257     ::SendInput(1, &mouseInput, sizeof(mouseInput));
 258 }
 259 
 260 /*
 261  * Class:     com_sun_glass_ui_win_WinRobot
 262  * Method:    _mouseWheel
 263  * Signature: (I)V
 264  */
 265 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinRobot__1mouseWheel
 266     (JNIEnv *env, jobject jrobot, jint wheelAmt)
 267 {
 268     ::mouse_event(MOUSEEVENTF_WHEEL, 0, 0, wheelAmt * -1 * WHEEL_DELTA, 0);
 269 }
 270 
 271 void GetScreenCapture(jint x, jint y, jint width, jint height, jint *pixelData);

 272 
 273 /*
 274  * Class:     com_sun_glass_ui_win_WinRobot
 275  * Method:    _getPixelColor
 276  * Signature: (II)I
 277  */
 278 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_win_WinRobot__1getPixelColor
 279     (JNIEnv *env, jobject jrobot, jint x, jint y)
 280 {
 281     jfloat fx = (jfloat) x + 0.5f;
 282     jfloat fy = (jfloat) y + 0.5f;
 283     GlassScreen::FX2Win(&fx, &fy);
 284     jint dx = (jint) fx;
 285     jint dy = (jint) fy;
 286 
 287     jint val = 0;
 288     //NOTE: we don't use the ::GetPixel() on the screen DC because it's not capable of
 289     //      getting the correct colors when non-opaque windows are present
 290     GetScreenCapture(dx, dy, 1, 1, &val);
 291     return val;
 292 }
 293 
 294 /*
 295  * Class:     com_sun_glass_ui_win_WinRobot
 296  * Method:    _getScreenCapture
 297  * Signature: (IIII[I;)V
 298  */
 299 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinRobot__1getScreenCapture
 300     (JNIEnv *env, jobject jrobot, jint x, jint y, jint width, jint height, jintArray pixelArray)
 301 {
 302     int numPixels = width * height;
 303     int pixelDataSize = sizeof(jint) * numPixels;
 304     ASSERT(pixelDataSize > 0 && pixelDataSize % 4 == 0);
 305 
 306     jint * pixelData = (jint *)(new BYTE[pixelDataSize]);
 307 
 308     if (pixelData) {
 309         GetScreenCapture(x, y, width, height, pixelData);
 310 
 311         // copy pixels into Java array
 312         env->SetIntArrayRegion(pixelArray, 0, numPixels, pixelData);
 313         delete[] pixelData;
 314     }
 315 }
 316 
 317 void GetScreenCapture(jint x, jint y, jint width, jint height, jint *pixelData)

 318 {
 319     HDC hdcScreen = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
 320     HDC hdcMem = ::CreateCompatibleDC(hdcScreen);
 321     HBITMAP hbitmap;
 322     HBITMAP hOldBitmap;
 323     HPALETTE hOldPalette = NULL;
 324 
 325     // create an offscreen bitmap
 326     hbitmap = ::CreateCompatibleBitmap(hdcScreen, width, height);
 327     if (hbitmap == NULL) {
 328         //TODO: OOM might be better?
 329         //throw std::bad_alloc();
 330     }
 331     hOldBitmap = (HBITMAP)::SelectObject(hdcMem, hbitmap);
 332 
 333     /* TODO: check this out
 334     // REMIND: not multimon-friendly...
 335     int primaryIndex = AwtWin32GraphicsDevice::GetDefaultDeviceIndex();
 336     hOldPalette =
 337         AwtWin32GraphicsDevice::SelectPalette(hdcMem, primaryIndex);
 338     AwtWin32GraphicsDevice::RealizePalette(hdcMem, primaryIndex);
 339     */
 340 
 341     // copy screen image to offscreen bitmap
 342     // CAPTUREBLT flag is required to capture WS_EX_LAYERED windows' contents
 343     // correctly on Win2K/XP
 344     static const DWORD dwRop = SRCCOPY|CAPTUREBLT;
 345     ::BitBlt(hdcMem, 0, 0, width, height, hdcScreen, x, y, dwRop);




 346 
 347     static const int BITS_PER_PIXEL = 32;
 348 
 349     struct {
 350         BITMAPINFOHEADER bmiHeader;
 351         RGBQUAD          bmiColors[3];
 352     } BitmapInfo;
 353 
 354     // prepare BITMAPINFO for a 32-bit RGB bitmap
 355     ::memset(&BitmapInfo, 0, sizeof(BitmapInfo));
 356     BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 357     BitmapInfo.bmiHeader.biWidth = width;
 358     BitmapInfo.bmiHeader.biHeight = -height; // negative height means a top-down DIB
 359     BitmapInfo.bmiHeader.biPlanes = 1;
 360     BitmapInfo.bmiHeader.biBitCount = BITS_PER_PIXEL;
 361     BitmapInfo.bmiHeader.biCompression = BI_BITFIELDS;
 362 
 363     // Setup up color masks
 364     static const RGBQUAD redMask =   {0, 0, 0xFF, 0};
 365     static const RGBQUAD greenMask = {0, 0xFF, 0, 0};
 366     static const RGBQUAD blueMask =  {0xFF, 0, 0, 0};
 367 
 368     BitmapInfo.bmiColors[0] = redMask;
 369     BitmapInfo.bmiColors[1] = greenMask;
 370     BitmapInfo.bmiColors[2] = blueMask;
 371 
 372     // Get the bitmap data in device-independent, 32-bit packed pixel format
 373     ::GetDIBits(hdcMem, hbitmap, 0, height, pixelData, (BITMAPINFO *)&BitmapInfo, DIB_RGB_COLORS);
 374 
 375     // convert Win32 pixel format (BGRX) to Java format (ARGB)
 376     ASSERT(sizeof(jint) == sizeof(RGBQUAD));
 377     jint numPixels = width * height;
 378     jint *pPixel = pixelData;
 379     for(int nPixel = 0; nPixel < numPixels; nPixel++) {
 380         RGBQUAD * prgbq = (RGBQUAD *) pPixel;
 381         *pPixel++ = WinToJavaPixel(prgbq->rgbRed, prgbq->rgbGreen, prgbq->rgbBlue);
 382     }
 383 
 384     // free all the GDI objects we made
 385     ::SelectObject(hdcMem, hOldBitmap);
 386     if (hOldPalette != NULL) {
 387         ::SelectPalette(hdcMem, hOldPalette, FALSE);
 388     }
 389     ::DeleteObject(hbitmap);
 390     ::DeleteDC(hdcMem);
 391     ::DeleteDC(hdcScreen);
 392 }
 393 
 394 }
 395 
< prev index next >