예제 #1
0
void initScreens(JNIEnv *env) {
    awt_numScreens = ::CountMonitors();
    monHds = (MHND *)safe_Malloc(awt_numScreens * sizeof(MHND));
    AwtWin32GraphicsDevice **tempDevArray;
    if (awt_numScreens != ::CollectMonitors(monHds, awt_numScreens)) {
        JNU_ThrowInternalError(env, "Failed to get all monitor handles.");
    }

    if (devices) {
	devices->RemoveReference();
	// Lock access to devices array until we've created the new
	// array.  Prevents things like accessing out-of-date color
	// models and partially-created devices array.
    }
    MTSafeArray *tmpDevices = new MTSafeArray(awt_numScreens);
    // Add reference for the overall array - don't want to delete it just
    // because there are no surfaceData objects referencing it
    tmpDevices->AddReference();

    // Create all devices first, then initialize them.  This allows
    // correct configuration of devices after contruction of the
    // primary device (which may not be device 0).
    tempDevArray = (AwtWin32GraphicsDevice**)
	safe_Malloc(awt_numScreens * sizeof(AwtWin32GraphicsDevice));
    for (int i = 0; i < awt_numScreens; ++i) {
	tempDevArray[i] = new AwtWin32GraphicsDevice(i, tmpDevices);
    }
    for (i = 0; i < awt_numScreens; ++i) {
	tempDevArray[i]->Initialize();
	tmpDevices->AddElement(tempDevArray[i], i);
    }
    free(tempDevArray);
    devices = tmpDevices;
    InitDirectX();
}
예제 #2
0
/*
 * Class:     sun_awt_windows_WInputMethodDescriptor
 * Method:    getNativeAvailableLocales
 * Signature: ()[Ljava/util/Locale;
 */
JNIEXPORT jobjectArray JNICALL Java_sun_awt_windows_WInputMethodDescriptor_getNativeAvailableLocales
  (JNIEnv *env, jclass self) 
{
    TRY;

    // get list of available HKLs
    int layoutCount = ::GetKeyboardLayoutList(0, NULL);
    HKL FAR * hKLList = (HKL FAR *)safe_Malloc(sizeof(HKL)*layoutCount);
    DASSERT(!safe_ExceptionOccurred(env));
    ::GetKeyboardLayoutList(layoutCount, hKLList);
    
    // get list of Java locale names while getting rid of duplicates
    int srcIndex = 0;
    int destIndex = 0;
    int javaLocaleNameCount = 0;
    int current = 0;
    const char ** javaLocaleNames = (const char **)safe_Malloc(sizeof(char *)*layoutCount);
    DASSERT(!safe_ExceptionOccurred(env));
    for (; srcIndex < layoutCount; srcIndex++) {
	const char * srcLocaleName = getJavaIDFromLangID(LOWORD(hKLList[srcIndex]));

	if (srcLocaleName == NULL) {
	    // could not find corresponding Java locale name for this HKL.
	    continue;
	}
	
	for (current = 0; current < destIndex; current++) {
	    if (strcmp(javaLocaleNames[current], srcLocaleName) == 0) {
	        // duplicated. ignore this HKL
		break;
	    }
	}

	if (current == destIndex) {
	    javaLocaleNameCount++;
	    destIndex++;
	    javaLocaleNames[current] = srcLocaleName;
	}
    }
	
    // convert it to an array of Java locale objects 
    jclass localeClass = env->FindClass("java/util/Locale");
    jobjectArray locales = env->NewObjectArray(javaLocaleNameCount, localeClass, NULL); 
    for (current = 0; current < javaLocaleNameCount; current++) {
        env->SetObjectArrayElement(locales, 
	                           current, 
				   CreateLocaleObject(env, javaLocaleNames[current]));
    }
    DASSERT(!safe_ExceptionOccurred(env));
    
    env->DeleteLocalRef(localeClass);
    free(hKLList);
    free(javaLocaleNames);
    return locales;

    CATCH_BAD_ALLOC_RET(NULL);
}
예제 #3
0
/**
 * Class:     sun_awt_windows_WInputMethod
 * Method:    getNativeIMMDescription
 * Signature: ()Ljava/lang/String;
 * 
 * This method tries to get the information about the input method associated with
 * the current active thread.
 *
 */
JNIEXPORT jstring JNICALL Java_sun_awt_windows_WInputMethod_getNativeIMMDescription
  (JNIEnv *env, jobject self) {

    TRY;

    // Get the keyboard layout of the active thread.
    HKL hkl = AwtComponent::GetKeyboardLayout();
    LPTSTR szImmDescription = NULL;
    UINT buffSize = 0;
    jstring infojStr = NULL;
  
    if ((buffSize = ::ImmGetDescription(hkl, szImmDescription, 0)) > 0) {
	szImmDescription = (LPTSTR) safe_Malloc(buffSize * sizeof(TCHAR));

	if (szImmDescription != NULL) {
	    ImmGetDescription(hkl, szImmDescription, buffSize);

	    infojStr = JNU_NewStringPlatform(env, szImmDescription);
      
	    free(szImmDescription);
	}
    }
  
    return infojStr;

    CATCH_BAD_ALLOC_RET(NULL);
}
예제 #4
0
/**
 * Create a new Devices object with numDevices elements.
 */
Devices::Devices(int numDevices) 
{
    J2dTraceLn1(J2D_TRACE_INFO, "Devices::Devices numDevices=%d", numDevices);
    this->numDevices = numDevices;
    this->refCount = 0;
    devices = (AwtWin32GraphicsDevice**)safe_Malloc
        (numDevices * sizeof(AwtWin32GraphicsDevice *));
}
예제 #5
0
static POINT *TransformPoly(jint *xpoints, jint *ypoints,
                            jint transx, jint transy,
                            POINT *pPoints, jint *pNpoints,
                            BOOL close, BOOL fixend)
{
    int npoints = *pNpoints;
    int outpoints = npoints;
    jint x, y;

    // Fix for 4298688 - draw(Line) and Polygon omit last pixel
    // We will need to add a point if we need to close it off or
    // if we need to fix the endpoint to accomodate the Windows
    // habit of never drawing the last pixel of a Polyline.  Note
    // that if the polyline is already closed then neither fix
    // is needed because the last pixel is also the first pixel
    // and so will be drawn just fine.
    // Clarification for 4298688 - regression bug 4678208 points
    // out that we still need to fix the endpoint if the closed
    // polygon never went anywhere (all vertices on same coordinate).
    jint mx = xpoints[0];
    jint my = ypoints[0];
    BOOL isclosed = (xpoints[npoints-1] == mx && ypoints[npoints-1] == my);
    if ((close && !isclosed) || fixend) {
        outpoints++;
        *pNpoints = outpoints;
    }
    if (outpoints > POLYTEMPSIZE) {
        pPoints = (POINT *) safe_Malloc(sizeof(POINT) * outpoints);
    }
    BOOL isempty = fixend;
    for (int i = 0; i < npoints; i++) {
        x = xpoints[i];
        y = ypoints[i];
        isempty = isempty && (x == mx && y == my);
        pPoints[i].x = CLAMP(x + transx);
        pPoints[i].y = CLAMP(y + transy);
    }
    if (close && !isclosed) {
        pPoints[npoints] = pPoints[0];
    } else if (fixend) {
        if (!close || isempty) {
            // Fix for 4298688 - draw(Line) and Polygon omit last pixel
            // Fix up the last segment by adding another segment after
            // it that is only 1 pixel long.  The first pixel of that
            // segment will be drawn, but the second pixel is the one
            // that Windows omits.
            pPoints[npoints] = pPoints[npoints-1];
            pPoints[npoints].x++;
        } else {
            outpoints--;
            *pNpoints = outpoints;
        }
    }

    return pPoints;
}
예제 #6
0
// Local function for getting values from the Windows registry
// Note that it uses malloc() and returns the pointer to allocated
// memory, so remember to use free() when you are done with its
// result.
static LPTSTR getWindowsPropFromReg(LPTSTR subKey, LPTSTR valueName, DWORD *valueType) {
    HKEY handle;
    if (RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_READ, &handle) != 0) {
	return NULL;
    }
    // valueSize is in bytes, while valueChar is in characters.
    DWORD valueSize, valueChar;
    if (RegQueryValueEx((HKEY)handle, valueName, NULL,
			valueType, NULL, &valueSize) != 0) {
        RegCloseKey(handle);
	return NULL;
    }
    LPTSTR buffer = (LPTSTR)safe_Malloc(valueSize);
    if (RegQueryValueEx((HKEY)handle, valueName, NULL,
			valueType, (unsigned char *)buffer, &valueSize) != 0) {
	free(buffer);
        RegCloseKey(handle);
	return NULL;
    }
    RegCloseKey(handle);

    if (*valueType == REG_EXPAND_SZ) {  
	// Pending: buffer must be null-terminated at this point
	valueChar = ExpandEnvironmentStrings(buffer, NULL, 0);
	LPTSTR buffer2 = (LPTSTR)safe_Malloc(valueChar*sizeof(TCHAR));
	ExpandEnvironmentStrings(buffer, buffer2, valueChar);
	free(buffer);
	return buffer2;
    } else if (*valueType == REG_SZ) {  
	return buffer;
    } else if (*valueType == REG_DWORD) {  
	return buffer;
    } else {
	free(buffer);
	return NULL;
    }
}
예제 #7
0
/*
 * Class:     sun_awt_windows_WInputMethod
 * Method:    setNativeLocale
 * Signature: (Ljava/lang/String;Z)Z
 */
JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale
  (JNIEnv *env, jclass cls, jstring localeString, jboolean onActivate)
{
    TRY;

    // check if current language ID is the requested one.  Note that the
    // current language ID (returned from 'getJavaIDFromLangID') is in 
    // ASCII encoding, so we use 'GetStringUTFChars' to retrieve requested 
    // language ID from the 'localeString' object.
    const char * current = getJavaIDFromLangID(AwtComponent::GetInputLanguage());
    jboolean isCopy;
    const char * requested = env->GetStringUTFChars(localeString, &isCopy);
    if ((current != NULL) && (strcmp(current, requested) == 0)) {
	env->ReleaseStringUTFChars(localeString, requested);
	return JNI_TRUE;
    }
    
    // get list of available HKLs.  Adding the user's preferred layout on top of the layout
    // list which is returned by GetKeyboardLayoutList ensures to match first when 
    // looking up suitable layout.
    int layoutCount = ::GetKeyboardLayoutList(0, NULL) + 1;  // +1 for user's preferred HKL
    HKL FAR * hKLList = (HKL FAR *)safe_Malloc(sizeof(HKL)*layoutCount);
    DASSERT(!safe_ExceptionOccurred(env));
    ::GetKeyboardLayoutList(layoutCount - 1, &(hKLList[1]));
    hKLList[0] = getDefaultKeyboardLayout(); // put user's preferred layout on top of the list
    
    // lookup matching LangID 
    jboolean retValue = JNI_FALSE;
    for (int i = 0; i < layoutCount; i++) {
        const char * supported = getJavaIDFromLangID(LOWORD(hKLList[i]));
	if ((supported != NULL) && (strcmp(supported, requested) == 0)) {
	    // use special message to call ActivateKeyboardLayout() in main thread.
            if (AwtToolkit::GetInstance().SendMessage(WM_AWT_ACTIVATEKEYBOARDLAYOUT, (WPARAM)onActivate, (LPARAM)hKLList[i])) {
                //also need to change the same keyboard layout for the Java AWT-EventQueue thread
                AwtToolkit::activateKeyboardLayout(hKLList[i]);
	        retValue = JNI_TRUE;
	    }
	    break;
	}
    }

    env->ReleaseStringUTFChars(localeString, requested);
    free(hKLList);
    return retValue;
	
    CATCH_BAD_ALLOC_RET(JNI_FALSE);
}
예제 #8
0
static void DumpRegion(HRGN rgn) {
    DWORD size = ::GetRegionData(rgn, 0, NULL);
    char* buffer = (char *)safe_Malloc(size);
    memset(buffer, 0, size);
    LPRGNDATA rgndata = (LPRGNDATA)buffer;
    rgndata->rdh.dwSize = sizeof(RGNDATAHEADER);
    rgndata->rdh.iType = RDH_RECTANGLES;
    VERIFY(::GetRegionData(rgn, size, rgndata));

    RECT* r = (RECT*)(buffer + rgndata->rdh.dwSize);
    for (DWORD i=0; i<rgndata->rdh.nCount; i++) {
        if ( !::IsRectEmpty(r) ) {
            DTrace_PrintImpl("\trect %d %d %d %d\n", r->left, r->top, r->right, r->bottom);
        }
        r++;
    }

    free(buffer);
}
예제 #9
0
// Does the actual lookup for shell dialog font (MS Shell Dlg).  fontName
// contains the name to lookup (either MS Shell Dlg or MS Shell Dlg 2) and
// handle contains a reference toe the registry entry to look in.
// This will return NULL or a pointer to the resolved name.
// Note that it uses malloc() and returns the pointer to allocated
// memory, so remember to use free() when you are done with its
// result.
static LPTSTR resolveShellDialogFont(LPTSTR fontName, HKEY handle) {
    DWORD valueType, valueSize;
    if (RegQueryValueEx((HKEY)handle, fontName, NULL,
			&valueType, NULL, &valueSize) != 0) {
        // Couldn't find it
        return NULL;
    }
    if (valueType != REG_SZ) {
        // Not the expected type
        return NULL;
    }
    LPTSTR buffer = (LPTSTR)safe_Malloc(valueSize);
    if (RegQueryValueEx((HKEY)handle, fontName, NULL,
			&valueType, (unsigned char *)buffer, &valueSize) != 0) {
        // Error fetching
	free(buffer);
	return NULL;
    }
    return buffer;
}
예제 #10
0
HRESULT DDraw::GetDDAvailableVidMem(DWORD *freeMem)
{
    DDrawDisplayMode dm;
    HRESULT ddResult;
    
    ddResult = dxObject->GetAvailableVidMem((DDSCAPS_VIDEOMEMORY |
    					     DDSCAPS_OFFSCREENPLAIN),
    					    NULL, freeMem);
    if (*freeMem == 0 || ddResult != DD_OK) {
	// Need to check it out ourselves: allocate as much as we can
	// and return that amount
	DDSURFACEDESC ddsd;
	ZeroMemory (&ddsd, sizeof(ddsd));
	ddsd.dwSize = sizeof( ddsd );
	HRESULT ddr = dxObject->GetDisplayMode(dm);
	if (ddr != DD_OK) 
	    DebugPrintDirectDrawError(ddr, "getDispMode");
	int bytesPerPixel = dm.bitDepth;
	static int maxSurfaces = 20;
	DXSurface **lpDDSOffscreenVram = (DXSurface**)
	    safe_Malloc(maxSurfaces*sizeof(DXSurface*));
	DWORD dwFlags = (DWORD)(DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH);
	DWORD ddsCaps = (DWORD)(DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN);
	int size = 1024;
	int numVramSurfaces = 0;
	int bitsAllocated = 0;
	BOOL done = FALSE;
	while (!done) {
	    HRESULT hResult = 
	    	dxObject->CreateSurface(dwFlags, ddsCaps, NULL, size, size,
					&lpDDSOffscreenVram[numVramSurfaces]);
	    if (hResult != DD_OK) {
		if (size > 1) {
		    size >>= 1;
		} else {
		    done = TRUE;
		}
	    } else {
예제 #11
0
/*
 * Create a Java locale object from its name string
 */
jobject CreateLocaleObject(JNIEnv *env, const char * name) 
{
    TRY;
    
    // get language, country, variant information
    char * language = (char *)safe_Malloc(strlen(name) + 1);
    char * country;
    char * variant;
    DASSERT(!safe_ExceptionOccurred(env));
    strcpy(language, name);
    for (country = language; *country != '_' && *country != '\0'; country++);
    if (*country == '_') {
        *country++ = '\0';
        for (variant = country; *variant != '_' && *variant != '\0'; variant++);
        if (*variant == '_') {
            *variant++ = '\0';
        }
    } else {
        variant = country;
    }

    // create Locale object
    jobject langObj = env->NewStringUTF(language);
    jobject ctryObj = env->NewStringUTF(country);
    jobject vrntObj = env->NewStringUTF(variant);
    jobject localeObj = JNU_NewObjectByName(env, "java/util/Locale",
                                            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
					    langObj, ctryObj, vrntObj);
    free(language);
    env->DeleteLocalRef(langObj);
    env->DeleteLocalRef(ctryObj);
    env->DeleteLocalRef(vrntObj);

    return localeObj;

    CATCH_BAD_ALLOC_RET(NULL);
}
예제 #12
0
void AwtDesktopProperties::GetOtherParameters() {
    // TODO BEGIN: On NT4, some setttings don't trigger WM_SETTINGCHANGE --
    // check whether this has been fixed on Windows 2000 and Windows 98
    // ECH 10/6/2000 seems to be fixed on NT4 SP5, but not on 98
    SetBooleanProperty(TEXT("win.frame.fullWindowDragsOn"), GetBooleanParameter(SPI_GETDRAGFULLWINDOWS));
    SetBooleanProperty(TEXT("win.text.fontSmoothingOn"), GetBooleanParameter(SPI_GETFONTSMOOTHING));
    // TODO END

    if (IS_WINXP) {
        SetIntegerProperty(TEXT("win.text.fontSmoothingType"), 
                           GetIntegerParameter(SPI_GETFONTSMOOTHINGTYPE));
        SetIntegerProperty(TEXT("win.text.fontSmoothingContrast"), 
                           GetIntegerParameter(SPI_GETFONTSMOOTHINGCONTRAST));
        SetIntegerProperty(TEXT("win.text.fontSmoothingOrientation"),
                           GetLCDSubPixelOrder());
    }

    int cxdrag = GetSystemMetrics(SM_CXDRAG);
    int cydrag = GetSystemMetrics(SM_CYDRAG);
    SetIntegerProperty(TEXT("win.drag.width"), cxdrag);
    SetIntegerProperty(TEXT("win.drag.height"), cydrag);
    SetIntegerProperty(TEXT("DnD.gestureMotionThreshold"), max(cxdrag, cydrag)/2);
    SetIntegerProperty(TEXT("awt.mouse.numButtons"), GetSystemMetrics(SM_CMOUSEBUTTONS));
    SetIntegerProperty(TEXT("awt.multiClickInterval"), GetDoubleClickTime());

    // BEGIN cross-platform properties
    // Note that these are cross-platform properties, but are being stuck into
    // WDesktopProperties.  WToolkit.lazilyLoadDesktopProperty() can find them,
    // but if a Toolkit subclass uses the desktopProperties
    // member, these properties won't be there. -bchristi, echawkes
    // This property is called "win.frame.fullWindowDragsOn" above
    // This is one of the properties that don't trigger WM_SETTINGCHANGE
    SetBooleanProperty(TEXT("awt.dynamicLayoutSupported"), GetBooleanParameter(SPI_GETDRAGFULLWINDOWS));

    // 95 MouseWheel support
    // More or less copied from the MSH_MOUSEWHEEL MSDN entry
    if (IS_WIN95 && !IS_WIN98) {
        HWND hdlMSHWHEEL = NULL;
        UINT msgMSHWheelSupported = NULL;
        BOOL wheelSupported = FALSE;

        msgMSHWheelSupported = RegisterWindowMessage(MSH_WHEELSUPPORT);
        hdlMSHWHEEL = FindWindow(MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE);
        if (hdlMSHWHEEL && msgMSHWheelSupported) {
            wheelSupported = (BOOL)::SendMessage(hdlMSHWHEEL,
                                                 msgMSHWheelSupported, 0, 0);
        }
        SetBooleanProperty(TEXT("awt.wheelMousePresent"), wheelSupported);
    }
    else {
        SetBooleanProperty(TEXT("awt.wheelMousePresent"),
                           ::GetSystemMetrics(SM_MOUSEWHEELPRESENT));
    }

    // END cross-platform properties

    if (IS_WIN98 || IS_WIN2000) {
      //DWORD	menuShowDelay;
        //SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &menuShowDelay, 0);
	// SetIntegerProperty(TEXT("win.menu.showDelay"), menuShowDelay);
        SetBooleanProperty(TEXT("win.frame.captionGradientsOn"), GetBooleanParameter(SPI_GETGRADIENTCAPTIONS));
        SetBooleanProperty(TEXT("win.item.hotTrackingOn"), GetBooleanParameter(SPI_GETHOTTRACKING));
    }

    if (IS_WIN2000) {
        SetBooleanProperty(TEXT("win.menu.keyboardCuesOn"), GetBooleanParameter(SPI_GETKEYBOARDCUES));
    }

    // High contrast accessibility property
    HIGHCONTRAST contrast;
    contrast.cbSize = sizeof(HIGHCONTRAST);
    if (SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(HIGHCONTRAST),
			     &contrast, 0) != 0 &&
	      (contrast.dwFlags & HCF_HIGHCONTRASTON) == HCF_HIGHCONTRASTON) {
      SetBooleanProperty(TEXT("win.highContrast.on"), TRUE);
    }
    else {
      SetBooleanProperty(TEXT("win.highContrast.on"), FALSE);
    }
    
    if (fn_SHGetSettings != NULL) {
        SHELLFLAGSTATE sfs;
        fn_SHGetSettings(&sfs, SSF_SHOWALLOBJECTS | SSF_SHOWATTRIBCOL);
        if (sfs.fShowAllObjects) {
            SetBooleanProperty(TEXT("awt.file.showHiddenFiles"), TRUE);
        }
        else {
            SetBooleanProperty(TEXT("awt.file.showHiddenFiles"), FALSE);
        }
        if (sfs.fShowAttribCol) {
            SetBooleanProperty(TEXT("awt.file..showAttribCol"), TRUE);
        }
        else {
            SetBooleanProperty(TEXT("awt.file.showAttribCol"), FALSE);
        }
    }

    LPTSTR value;
    DWORD valueType;

    // Shell Icon BPP - only honored on platforms before XP
    value = getWindowsPropFromReg(TEXT("Control Panel\\Desktop\\WindowMetrics"),
				  TEXT("Shell Icon BPP"), &valueType);
    if (value != NULL) {
	if (valueType == REG_SZ) {
	    SetStringProperty(TEXT("win.icon.shellIconBPP"), value);
	}
	free(value);
    }


    // The following registry settings control the file chooser places bar
    // under the Windows L&F. These settings are not present by default, but
    // can be enabled using the TweakUI tool from Microsoft. For more info,
    // see http://msdn.microsoft.com/msdnmag/issues/1100/Registry/

    // NoPlacesBar is a REG_DWORD, with values 0 or 1
    value = getWindowsPropFromReg(TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\comdlg32"),
				  TEXT("NoPlacesBar"), &valueType);
    if (value != NULL) {
	if (valueType == REG_DWORD) {
	    SetBooleanProperty(TEXT("win.comdlg.noPlacesBar"), (BOOL)((int)*value != 0));
	}
	free(value);
    }

    LPTSTR valueName = TEXT("PlaceN");
    LPTSTR valueNameBuf = (LPTSTR)safe_Malloc((lstrlen(valueName) + 1) * sizeof(TCHAR));
    lstrcpy(valueNameBuf, valueName);

    LPTSTR propKey = TEXT("win.comdlg.placesBarPlaceN");
    LPTSTR propKeyBuf = (LPTSTR)safe_Malloc((lstrlen(propKey) + 1) * sizeof(TCHAR));
    lstrcpy(propKeyBuf, propKey);

    int i = 0;
    do {
	valueNameBuf[5] = _T('0' + i++);
	propKeyBuf[25] = valueNameBuf[5];

	LPTSTR key = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\comdlg32\\PlacesBar");
	if ((value = getWindowsPropFromReg(key, valueNameBuf, &valueType)) != NULL) {
	    if (valueType == REG_DWORD) {
		// Value is a CSIDL
		SetIntegerProperty(propKeyBuf, (int)*value);
	    } else {
		// Value is a path
		SetStringProperty(propKeyBuf, value);
	    }
	    free(value);
	}
    } while (value != NULL);

    free(valueNameBuf);
    free(propKeyBuf);
}
예제 #13
0
void *safe_Malloc_outofmem(size_t size, const char *file, int line)
    throw (std::bad_alloc)
{
    rand_alloc_fail(file, line);
    return safe_Malloc(size);
}
예제 #14
0
// This function exists because VC++ 5.0 currently does not conform to the
// Standard C++ specification which requires that operator new throw
// std::bad_alloc in an out of memory situation. Instead, VC++ 5.0 returns 0.
//
// This function can be safely removed when the problem is corrected.
void * CDECL operator new(size_t size) throw (std::bad_alloc) {
    return safe_Malloc(size);
}
/**
 * Init this device.  This creates the bitmap structure
 * used to hold the device color data and initializes any
 * appropriate palette structures.
 */
void AwtWin32GraphicsDevice::Initialize()
{
    unsigned int ri, gi, bi;
    if (colorData->bitsperpixel < 8) {
        // REMIND: how to handle?
    }

    // Create a BitmapInfo object for color data
    if (!gpBitmapInfo) {
        try {
            gpBitmapInfo = (BITMAPINFO *)
                safe_Malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
        } catch (std::bad_alloc&) {
            throw;
        }
        gpBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    }
    gpBitmapInfo->bmiHeader.biBitCount = 0;
    HDC hBMDC = this->GetDC();
    HBITMAP hBM = ::CreateCompatibleBitmap(hBMDC, 1, 1);
    VERIFY(::GetDIBits(hBMDC, hBM, 0, 1, NULL, gpBitmapInfo, DIB_RGB_COLORS));

    if (colorData->bitsperpixel > 8) {
        if (MONITORINFOF_PRIMARY & pMonitorInfo->dwFlags) {
            primaryPalettized = FALSE;
        }
        if (colorData->bitsperpixel != 24) { // 15, 16, or 32 bpp
            int foo;
            gpBitmapInfo->bmiHeader.biCompression = BI_BITFIELDS;
            if (::GetDIBits(hBMDC, hBM, 0, 1, &foo, gpBitmapInfo,
                            DIB_RGB_COLORS) == 0)
            {
                // Bug 4684966: If GetDIBits returns an error, we could
                // get stuck in an infinite loop setting the colorData
                // fields.  Hardcode bitColors to reasonable values instead.
                // These values are picked according to standard masks
                // for these bit depths on win9x, according to MSDN docs.
                switch (colorData->bitsperpixel) {
                case 15:
                    ((int *)gpBitmapInfo->bmiColors)[0] = 0x7c00;
                    ((int *)gpBitmapInfo->bmiColors)[1] = 0x03e0;
                    ((int *)gpBitmapInfo->bmiColors)[2] = 0x001f;
                    break;
                case 16:
                    ((int *)gpBitmapInfo->bmiColors)[0] = 0xf800;
                    ((int *)gpBitmapInfo->bmiColors)[1] = 0x07e0;
                    ((int *)gpBitmapInfo->bmiColors)[2] = 0x001f;
                    break;
                case 32:
                default:
                    ((int *)gpBitmapInfo->bmiColors)[0] = 0xff0000;
                    ((int *)gpBitmapInfo->bmiColors)[1] = 0x00ff00;
                    ((int *)gpBitmapInfo->bmiColors)[2] = 0x0000ff;
                    break;
                }
            }
            ri = ((unsigned int *)gpBitmapInfo->bmiColors)[0];
            colorData->rOff = 0;
            while ((ri & 1) == 0) {
                colorData->rOff++;
                ri >>= 1;
            }
            colorData->rScale = 0;
            while (ri < 0x80) {
                colorData->rScale++;
                ri <<= 1;
            }
            gi = ((unsigned int *)gpBitmapInfo->bmiColors)[1];
            colorData->gOff = 0;
            while ((gi & 1) == 0) {
                colorData->gOff++;
                gi >>= 1;
            }
            colorData->gScale = 0;
            while (gi < 0x80) {
                colorData->gScale++;
                gi <<= 1;
            }
            bi = ((unsigned int *)gpBitmapInfo->bmiColors)[2];
            colorData->bOff = 0;
            while ((bi & 1) == 0) {
                colorData->bOff++;
                bi >>= 1;
            }
            colorData->bScale = 0;
            while (bi < 0x80) {
                colorData->bScale++;
                bi <<= 1;
            }
            if (   (0 == colorData->bOff)
                && (5 == colorData->gOff)
                && (10 == colorData->rOff)
                && (3 == colorData->bScale)
                && (3 == colorData->gScale)
                && (3 == colorData->rScale)) {
                colorData->bitsperpixel = 15;
                gpBitmapInfo->bmiHeader.biCompression = BI_RGB;
            }
        } else {    // 24 bpp
예제 #16
0
// static
BOOL Devices::UpdateInstance(JNIEnv *env)
{
    J2dTraceLn(J2D_TRACE_INFO, "Devices::UpdateInstance");

    int numScreens = ::CountMonitors();
    MHND *monHds = (MHND *)safe_Malloc(numScreens * sizeof(MHND));
    if (numScreens != ::CollectMonitors(monHds, numScreens)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR, 
                      "Devices::UpdateInstance: Failed to get all "\
                      "monitor handles.");
        free(monHds);
        return FALSE;
    }

    Devices *newDevices = new Devices(numScreens);
    // This way we know that the array will not be disposed of
    // at least until we replaced it with a new one.
    newDevices->AddReference();

    // Create all devices first, then initialize them.  This allows
    // correct configuration of devices after contruction of the
    // primary device (which may not be device 0).
    AwtWin32GraphicsDevice** rawDevices = newDevices->GetRawArray();
    int i;
    for (i = 0; i < numScreens; ++i) {
        J2dTraceLn2(J2D_TRACE_VERBOSE, "  hmon[%d]=0x%x", i, monHds[i]);
        rawDevices[i] = new AwtWin32GraphicsDevice(i, monHds[i], newDevices);
    }
    for (i = 0; i < numScreens; ++i) {
        rawDevices[i]->Initialize();
    }
    {
        CriticalSection::Lock l(arrayLock);

        // install the new devices array
        Devices *oldDevices = theInstance;
        theInstance = newDevices;

        if (oldDevices) {
            // Invalidate the devices with indexes out of the new set of
            // devices. This doesn't cover all cases when the device
            // might should be invalidated (like if it's not the last device
            // that was removed), but it will have to do for now.
            int oldNumScreens = oldDevices->GetNumDevices();
            int newNumScreens = theInstance->GetNumDevices();
            J2dTraceLn(J2D_TRACE_VERBOSE, "  Invalidating removed devices");
            for (int i = newNumScreens; i < oldNumScreens; i++) {
                // removed device, needs to be invalidated
                J2dTraceLn1(J2D_TRACE_WARNING, 
                            "Devices::UpdateInstance: device removed: %d", i);
                oldDevices->GetDevice(i)->Invalidate(env);
            }
            // Now that we have a new array in place, remove this (possibly the
            // last) reference to the old instance.
            oldDevices->Release();
        }
        D3DPipelineManager::HandleAdaptersChange((HMONITOR*)monHds,
                                                 theInstance->GetNumDevices());
    }
    free(monHds);

    return TRUE;
}
/*
 * Class:     sun_awt_windows_WDataTransferer
 * Method:    imageDataToPlatformImageBytes
 * Signature: ([BIII)[B
 */
JNIEXPORT jbyteArray JNICALL
Java_sun_awt_windows_WDataTransferer_imageDataToPlatformImageBytes(JNIEnv *env,
                                               jobject self, jbyteArray imageData,
                                               jint width, jint height,
                                               jlong format) {

    TRY;

    if (JNU_IsNull(env, imageData)) {
        return NULL;
    }

    UINT size = env->GetArrayLength(imageData);
    if (size == 0) {
        return NULL;
    }

    // In the passed imageData array all lines are padded with zeroes except for
    // the last one, so we have to add one pad size here.
    int mod = (width * 3) % 4;
    int pad = mod > 0 ? 4 - mod : 0;
    int nBytes = sizeof(BITMAPINFO) + size + pad;
    BITMAPINFO* pinfo = (BITMAPINFO*)safe_Calloc(1, nBytes);

    static const int BITS_PER_PIXEL = 24;

    // prepare BITMAPINFO for a 24-bit BGR bitmap
    pinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    pinfo->bmiHeader.biWidth = width;
    pinfo->bmiHeader.biHeight = height; // positive height means a bottom-up DIB
    pinfo->bmiHeader.biPlanes = 1;
    pinfo->bmiHeader.biBitCount = BITS_PER_PIXEL;
    pinfo->bmiHeader.biCompression = BI_RGB;
    // NOTE: MSDN says that biSizeImage may be set to 0 for BI_RGB bitmaps,
    // but some programs (e.g. Imaging for Windows NT by Wang Laboratories)
    // don't handle such DIBs correctly, so we specify the size explicitly.
    pinfo->bmiHeader.biSizeImage = size + pad;

    jbyte *array = (jbyte*)((LPSTR)pinfo + sizeof(BITMAPINFOHEADER));
    env->GetByteArrayRegion(imageData, 0, size, array);
    HRESULT hr = S_OK;

    jbyteArray bytes = NULL;
    switch (format) {
    case CF_DIB:
        bytes = env->NewByteArray(nBytes);
        if( NULL == bytes ) {
            hr = E_OUTOFMEMORY;
        } else {
            env->SetByteArrayRegion(bytes, 0, nBytes, (jbyte*)pinfo);
        }
        break;
    case CF_ENHMETAFILE:
    {
        HDC hdc = ::GetDC(NULL);
        if( NULL == hdc) {
            hr = HRESULT_FROM_WIN32(::GetLastError());
        } else {
            POINT p = { width, height };
            //We are trying to support context-independent metafile.
            //To implement it we have to select correct MM_HIMETRIC map mode.
            VERIFY(::SetMapMode(hdc, MM_HIMETRIC));
            VERIFY(::DPtoLP(hdc, &p, 1));
            //In accordance with CreateEnhMetaFile documentation the rectangle have to
            //be normal (left <= right, top <= bottom)
            RECT r = { min(0, p.x), min(0, p.y), max(0, p.x), max(0, p.y) };
            //Due to inversed row order in source bitmap the destination
            //height have to be negative.
            HDC hemfdc = ::CreateEnhMetaFile(NULL, NULL, &r, NULL);
            if( NULL == hemfdc) {
                hr = HRESULT_FROM_WIN32(::GetLastError());
            } else {
                int iMFHeight = r.bottom - r.top;
                int iMFWidth = r.right - r.left;
                VERIFY(::SetMapMode(hemfdc, MM_HIMETRIC));
                if( GDI_ERROR == ::StretchDIBits(hemfdc,
                    0, iMFHeight, iMFWidth, -iMFHeight,
                    0, 0, width, height,
                    (LPVOID)array, pinfo,
                    DIB_RGB_COLORS, SRCCOPY))
                {
                    hr = HRESULT_FROM_WIN32(::GetLastError());
                }
                HENHMETAFILE hemf = ::CloseEnhMetaFile(hemfdc);
                if( NULL == hemf) {
                    hr = HRESULT_FROM_WIN32(::GetLastError());
                } else {
                    if(SUCCEEDED(hr)){
                        UINT uEmfSize = ::GetEnhMetaFileBits(hemf, 0, NULL);
                        if( 0 == uEmfSize) {
                            hr = HRESULT_FROM_WIN32(::GetLastError());
                        } else {
                            LPBYTE lpbEmfBuffer = NULL;
                            try {
                                lpbEmfBuffer = (LPBYTE)safe_Malloc(uEmfSize);
                                VERIFY(::GetEnhMetaFileBits(hemf, uEmfSize,
                                                            lpbEmfBuffer) == uEmfSize);
                                bytes = env->NewByteArray(uEmfSize);
                                if(NULL == bytes) {
                                    hr = E_OUTOFMEMORY;
                                } else {
                                    env->SetByteArrayRegion(bytes, 0, uEmfSize, (jbyte*)lpbEmfBuffer);
                                }
                            } catch (std::bad_alloc &) {
                                hr = E_OUTOFMEMORY;
                            }
                            free(lpbEmfBuffer);
                        }
                    }
                    VERIFY(::DeleteEnhMetaFile(hemf));
                }
            }
            VERIFY(::ReleaseDC(NULL, hdc));
        }
        break;
    }
    case CF_METAFILEPICT:
    {
        HDC hdc = ::GetDC(NULL);
        if( NULL == hdc) {
            hr = HRESULT_FROM_WIN32(::GetLastError());
        } else {
            POINT p = { width, height };
            VERIFY(::SetMapMode(hdc, MM_HIMETRIC));
            VERIFY(::DPtoLP(hdc, &p, 1));
            RECT r = { min(0, p.x), min(0, p.y), max(0, p.x), max(0, p.y) };
            HDC hmfdc = ::CreateMetaFile(NULL);
            if( NULL == hmfdc) {
                hr = HRESULT_FROM_WIN32(::GetLastError());
            } else {
                VERIFY(::SetMapMode(hmfdc, MM_HIMETRIC));
                int iMFHeight = r.bottom - r.top;
                int iMFWidth = r.right - r.left;
                //The destination Y coordinate (3d parameter in StretchDIBits call) is different for
                //CF_ENHMETAFILE and CF_METAFILEPICT formats due to applying MM_ANISOTROPIC map mode
                //at very last moment. MM_ANISOTROPIC map mode changes the Y-axis direction and can be
                //selected just for metafile header.
                if( GDI_ERROR == ::StretchDIBits(hmfdc,
                    0, 0, iMFWidth, -iMFHeight,
                    0, 0, width, height,
                    (LPVOID)array, pinfo,
                    DIB_RGB_COLORS, SRCCOPY))
                {
                    hr = HRESULT_FROM_WIN32(::GetLastError());
                }
                HMETAFILE hmf = ::CloseMetaFile(hmfdc);
                if( NULL == hmf) {
                    hr = HRESULT_FROM_WIN32(::GetLastError());
                } else {
                    if(SUCCEEDED(hr)){
                        UINT uMfSize = ::GetMetaFileBitsEx(hmf, 0, NULL);
                        if( 0 == uMfSize) {
                            hr = HRESULT_FROM_WIN32(::GetLastError());
                        } else {
                            LPBYTE lpbMfBuffer = NULL;
                            try {
                                lpbMfBuffer = (LPBYTE)SAFE_SIZE_STRUCT_ALLOC(safe_Malloc,
                                        sizeof(METAFILEPICT), uMfSize, 1);
                                const UINT uMfSizeWithHead = uMfSize + sizeof(METAFILEPICT);
                                VERIFY(::GetMetaFileBitsEx(hmf, uMfSize,
                                                            lpbMfBuffer + sizeof(METAFILEPICT)) == uMfSize);
                                bytes = env->NewByteArray(uMfSizeWithHead);
                                if(NULL == bytes) {
                                    hr = E_OUTOFMEMORY;
                                } else {
                                    LPMETAFILEPICT lpMfp = (LPMETAFILEPICT)lpbMfBuffer;
                                    lpMfp->mm = MM_ANISOTROPIC; // should use MM_ANISOTROPIC exactly (MSDN)
                                    lpMfp->xExt = iMFWidth;
                                    lpMfp->yExt = iMFHeight;
                                    env->SetByteArrayRegion(bytes, 0, uMfSizeWithHead, (jbyte*)lpbMfBuffer);
                                }
                            } catch (std::bad_alloc &) {
                                hr = E_OUTOFMEMORY;
                            }
                            free(lpbMfBuffer);
                        }
                    }
                    VERIFY(::DeleteMetaFile(hmf));
                }
            }
            VERIFY(::ReleaseDC(NULL, hdc));
        }
        break;
    }
    default:
        DASSERT(FALSE); // Other formats are not supported yet.
        hr = E_NOTIMPL;
        break;
    }
    free(pinfo);
    if(FAILED(hr)){
        if(E_OUTOFMEMORY == hr)
            throw std::bad_alloc();
        return NULL;
    }
    return bytes;
    CATCH_BAD_ALLOC_RET(NULL);
}
/*
 * Class:     sun_awt_windows_WDataTransferer
 * Method:    platformImageBytesToImageData
 * Signature: ([BI)[I
 */
JNIEXPORT jintArray JNICALL
Java_sun_awt_windows_WDataTransferer_platformImageBytesToImageData(
    JNIEnv *env, jobject self, jbyteArray bytes, jlong format) {

    TRY;

    HDC hdc = NULL;

    LOGPALETTE* pLogPalette = NULL;
    WORD uPaletteEntries = 0;
    SIZE_T uOffset = 0;
    HPALETTE hPalette = NULL;
    HPALETTE hOldPalette = NULL;

    BITMAPINFO* pSrcBmi = NULL;
    BITMAPINFOHEADER* pSrcBmih = NULL;
    LPVOID pSrcBits = NULL;
    BITMAPINFO* pDstBmi = NULL;
    BITMAPINFOHEADER* pDstBmih = NULL;
    LPVOID pDstBits = NULL;

    LPBYTE lpEnhMetaFileBits = NULL;
    HENHMETAFILE hEnhMetaFile = NULL;

    HBITMAP hDibSection = NULL;
    HBITMAP hOldBitmap = NULL;
    jintArray buffer = NULL;
    LONG width = 0;
    LONG height = 0;
    int numPixels = 0;

    if (JNU_IsNull(env, bytes)) {
        return NULL;
    }

    jsize size = env->GetArrayLength(bytes);
    if (size == 0) {
        return NULL;
    }

    jbyte* bBytes = (jbyte*)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, size, sizeof(jbyte));

    try {

        env->GetByteArrayRegion(bytes, 0, size, bBytes);

        pLogPalette = (LOGPALETTE*)bBytes;
        uPaletteEntries = pLogPalette->palNumEntries;
        uOffset = sizeof(LOGPALETTE) + uPaletteEntries * sizeof(PALETTEENTRY);
        DASSERT(uOffset < (SIZE_T)size);

        if (uPaletteEntries == 0) {
            pLogPalette = NULL;
        }

        hdc = ::CreateCompatibleDC(NULL);
        if (hdc == NULL) {
            free(bBytes);
            return NULL;
        }

        switch (format) {
        case CF_DIB:

            pSrcBmi = (BITMAPINFO*)((LPSTR)bBytes + uOffset);
            pSrcBmih = &pSrcBmi->bmiHeader;

            width = pSrcBmih->biWidth;
            height = abs(pSrcBmih->biHeight);

            {
                DWORD nColorEntries = 0;

                switch (pSrcBmih->biBitCount) {
                case  0: nColorEntries = 0; break;
                case  1: nColorEntries = 2; break;
                case  4:
                case  8:
                    nColorEntries = (pSrcBmih->biClrUsed != 0) ?
                        pSrcBmih->biClrUsed : (1 << pSrcBmih->biBitCount);
                    break;
                case 16:
                case 24:
                case 32:
                    nColorEntries = pSrcBmih->biClrUsed;
                    // If biBitCount is 16 or 32 and biCompression is
                    // BI_BITFIELDS the color table will be prefixed with
                    // three DWORD color masks.
                    if (pSrcBmih->biCompression == BI_BITFIELDS &&
                        (pSrcBmih->biBitCount == 16 ||
                         pSrcBmih->biBitCount == 32)) {
                        nColorEntries += 3;
                    }
                    break;
                default:
                    // The header is probably corrupted.
                    // Fail immediatelly to avoid memory access violation.
                    free(bBytes);
                    ::DeleteDC(hdc);
                    return NULL;
                }

                pSrcBits = (LPSTR)pSrcBmi + pSrcBmih->biSize
                    + nColorEntries * sizeof(RGBQUAD);
            }
            break;
        case CF_ENHMETAFILE:
        case CF_METAFILEPICT:
            lpEnhMetaFileBits = (BYTE*)bBytes + uOffset;
            // Warning C4244. size is jsize, uOffset is SIZE_T.
            // We assert that size > uOffset, so it is safe to cast to jsize.
            hEnhMetaFile = ::SetEnhMetaFileBits(size - (jsize)uOffset,
                                                lpEnhMetaFileBits);
            DASSERT(hEnhMetaFile != NULL);

            {
                UINT uHeaderSize =
                    ::GetEnhMetaFileHeader(hEnhMetaFile, 0, NULL);
                DASSERT(uHeaderSize != 0);
                ENHMETAHEADER* lpemh = (ENHMETAHEADER*)safe_Malloc(uHeaderSize);
                VERIFY(::GetEnhMetaFileHeader(hEnhMetaFile, uHeaderSize,
                                              lpemh) == uHeaderSize);
                LPRECTL lpFrame = &lpemh->rclFrame;
                POINT p = { abs(lpFrame->right - lpFrame->left),
                            abs(lpFrame->bottom - lpFrame->top) };
                VERIFY(::SaveDC(hdc));
                VERIFY(::SetMapMode(hdc, MM_HIMETRIC));
                VERIFY(::LPtoDP(hdc, &p, 1));
                VERIFY(::RestoreDC(hdc, -1));
                width = p.x;
                height = -p.y;

                free(lpemh);
            }
            break;
        default:
            DASSERT(FALSE); // Other formats are not supported yet.
            free(bBytes);
            ::DeleteDC(hdc);
            return NULL;
        }

        // JNI doesn't allow to store more than INT_MAX in a single array.
        // We report conversion failure in this case.
        if (width * height > INT_MAX) {
            free(bBytes);
            ::DeleteDC(hdc);
            return NULL;
        }

        numPixels = width * height;

        if (pLogPalette != NULL) {
            hPalette = ::CreatePalette(pLogPalette);
            if (hPalette == NULL) {
                free(bBytes);
                ::DeleteDC(hdc);
                return NULL;
            }
            hOldPalette = ::SelectPalette(hdc, hPalette, FALSE);
            ::RealizePalette(hdc);
        }

        // allocate memory for BITMAPINFO
        pDstBmi = (BITMAPINFO *)safe_Calloc(1, sizeof(BITMAPINFO));
        pDstBmih = &pDstBmi->bmiHeader;

        static const int BITS_PER_PIXEL = 32;

        // prepare BITMAPINFO for a 32-bit RGB bitmap
        pDstBmih->biSize = sizeof(BITMAPINFOHEADER);
        pDstBmih->biWidth = width;
        pDstBmih->biHeight = -height; // negative height means a top-down DIB
        pDstBmih->biPlanes = 1;
        pDstBmih->biBitCount = BITS_PER_PIXEL;
        pDstBmih->biCompression = BI_RGB;
        // NOTE: MSDN says that biSizeImage may be set to 0 for BI_RGB bitmaps,
        // but this causes CreateDIBSection to allocate zero-size memory block
        // for DIB data. It works okay when biSizeImage is explicitly specified.
        pDstBmih->biSizeImage = width * height * (BITS_PER_PIXEL >> 3);

        hDibSection = ::CreateDIBSection(hdc, (BITMAPINFO*)pDstBmi,
                                         DIB_RGB_COLORS, &pDstBits,
                                         NULL, 0);

        if (hDibSection == NULL) {
            free(pDstBmi); pDstBmi = NULL;
            if (hPalette != NULL) {
                VERIFY(::SelectPalette(hdc, hOldPalette, FALSE) != NULL);
                hOldPalette = NULL;
                VERIFY(::DeleteObject(hPalette)); hPalette = NULL;
            }
            VERIFY(::DeleteDC(hdc)); hdc = NULL;
            free(bBytes); bBytes = NULL;

            JNU_ThrowIOException(env, "failed to get drop data");
            return NULL;
        }

        hOldBitmap = (HBITMAP)::SelectObject(hdc, hDibSection);
        DASSERT(hOldBitmap != NULL);

        switch (format) {
        case CF_DIB:
            VERIFY(::StretchDIBits(hdc,
                                   0, 0, width, height,
                                   0, 0, width, height,
                                   pSrcBits, pSrcBmi,
                                   DIB_RGB_COLORS, SRCCOPY) != GDI_ERROR);
            break;
        case CF_ENHMETAFILE:
        case CF_METAFILEPICT: {
            RECT rect = { 0, 0, width, height };

            VERIFY(::PlayEnhMetaFile(hdc, hEnhMetaFile, &rect));
            VERIFY(::DeleteEnhMetaFile(hEnhMetaFile)); hEnhMetaFile = NULL;
            break;
        }
        default:
            // Other formats are not supported yet.
            DASSERT(FALSE);
            break;
        }

        // convert Win32 pixel format (BGRX) to Java format (ARGB)
        DASSERT(sizeof(jint) == sizeof(RGBQUAD));
        RGBQUAD* prgbq = (RGBQUAD*)pDstBits;
        for(int nPixel = 0; nPixel < numPixels; nPixel++, prgbq++) {
            jint jpixel = WIN_TO_JAVA_PIXEL(prgbq->rgbRed,
                                            prgbq->rgbGreen,
                                            prgbq->rgbBlue);
            // stuff the 32-bit pixel back into the 32-bit RGBQUAD
            *prgbq = *((RGBQUAD*)(&jpixel));
        }

        buffer = env->NewIntArray(numPixels + 2);
        if (buffer == NULL) {
            throw std::bad_alloc();
        }

        // copy pixels into Java array
        env->SetIntArrayRegion(buffer, 0, numPixels, (jint*)pDstBits);

        // copy dimensions into Java array
        env->SetIntArrayRegion(buffer, numPixels, 1, (jint*)&width);
        env->SetIntArrayRegion(buffer, numPixels + 1, 1, (jint*)&height);

        VERIFY(::SelectObject(hdc, hOldBitmap) != NULL); hOldBitmap = NULL;
        VERIFY(::DeleteObject(hDibSection)); hDibSection = NULL;
        free(pDstBmi); pDstBmi = NULL;
        if (hPalette != NULL) {
            VERIFY(::SelectPalette(hdc, hOldPalette, FALSE) != NULL);
            hOldPalette = NULL;
            VERIFY(::DeleteObject(hPalette)); hPalette = NULL;
        }
        VERIFY(::DeleteDC(hdc)); hdc = NULL;
        free(bBytes); bBytes = NULL;
    } catch (...) {
        if (hdc != NULL && hOldBitmap != NULL) {
            VERIFY(::SelectObject(hdc, hOldBitmap) != NULL); hOldBitmap = NULL;
        }
        if (hDibSection != NULL) {
            VERIFY(::DeleteObject(hDibSection)); hDibSection = NULL;
        }
        if (pDstBmi != NULL) {
            free(pDstBmi); pDstBmi = NULL;
        }
        if (hPalette != NULL) {
            if (hdc != NULL) {
                VERIFY(::SelectPalette(hdc, hOldPalette, FALSE) != NULL);
                hOldPalette = NULL;
            }
            VERIFY(::DeleteObject(hPalette)); hPalette = NULL;
        }
        if (hdc != NULL) {
            VERIFY(::DeleteDC(hdc)); hdc = NULL;
        }
        if (hEnhMetaFile != NULL) {
            VERIFY(::DeleteEnhMetaFile(hEnhMetaFile)); hEnhMetaFile = NULL;
        }
        if (bBytes != NULL) {
            free(bBytes); bBytes = NULL;
        }
        throw;
    }

    return buffer;

    CATCH_BAD_ALLOC_RET(NULL);
}
예제 #19
0
/*
 * Class:     sun_java2d_windows_GDIBlitLoops
 * Method:    nativeBlit
 * Signature: (Lsun/java2d/SurfaceData;Lsun/java2d/SurfaceData;IIIIIIZ)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_windows_GDIBlitLoops_nativeBlit
    (JNIEnv *env, jobject joSelf,
     jobject srcData, jobject dstData,
     jobject clip,
     jint srcx, jint srcy,
     jint dstx, jint dsty,
     jint width, jint height,
     jint rmask, jint gmask, jint bmask,
     jboolean needLut)
{
    J2dTraceLn(J2D_TRACE_INFO, "GDIBlitLoops_nativeBlit");

    SurfaceDataRasInfo srcInfo;
    SurfaceDataOps *srcOps = SurfaceData_GetOps(env, srcData);
    GDIWinSDOps *dstOps = GDIWindowSurfaceData_GetOps(env, dstData);
    jint lockFlags;    
    HDC hDC = dstOps->GetDC(env, dstOps, 0, NULL, clip, NULL, 0);

    if (hDC == NULL) {
        return;
    }
    srcInfo.bounds.x1 = srcx;
    srcInfo.bounds.y1 = srcy;
    srcInfo.bounds.x2 = srcx + width;
    srcInfo.bounds.y2 = srcy + height;
    if (needLut) {
	lockFlags = (SD_LOCK_READ | SD_LOCK_LUT);
    } else {
	lockFlags = SD_LOCK_READ;
    }
    if (srcOps->Lock(env, srcOps, &srcInfo, lockFlags) != SD_SUCCESS) {
	dstOps->ReleaseDC(env, dstOps, hDC);
	return;
    }

    SurfaceDataBounds dstBounds = {dstx, dsty, dstx + width, dsty + height};
    // Intersect the source and dest rects. Note that the source blit bounds
    // will be adjusted to the surfaces's bounds if needed.
    SurfaceData_IntersectBlitBounds(&(srcInfo.bounds), &dstBounds, 
                                    dstx - srcx, dsty - srcy);

    srcx = srcInfo.bounds.x1;
    srcy = srcInfo.bounds.y1;
    dstx = dstBounds.x1;
    dsty = dstBounds.y1;
    width = srcInfo.bounds.x2 - srcInfo.bounds.x1;
    height = srcInfo.bounds.y2 - srcInfo.bounds.y1;

    if (width > 0 && height > 0)
    {
	BmiType bmi;
	// REMIND: A performance tweak here would be to make some of this 
	// data static.  For example, we could have one structure that is
	// always used for ByteGray copies and we only change dynamic data
	// in the structure with every new copy.  Also, we could store
	// structures with Ops or with the Java objects so that surfaces
	// could retain their own DIB info and we would not need to 
	// recreate it every time.

	srcOps->GetRasInfo(env, srcOps, &srcInfo);
	void *rasBase = ((char *)srcInfo.rasBase) + srcInfo.scanStride * srcy +
			srcInfo.pixelStride * srcx;

	// If scanlines are DWORD-aligned (scanStride is a multiple of 4),
	// then we can do the work much faster.  This is due to a constraint
	// in the way DIBs are structured and parsed by GDI
	jboolean fastBlt = ((srcInfo.scanStride & 0x03) == 0);

	bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
	bmi.bmiHeader.biWidth = srcInfo.scanStride/srcInfo.pixelStride;
	// fastBlt copies whole image in one call; else copy line-by-line
	bmi.bmiHeader.biHeight = (fastBlt) ? 
	    -(srcInfo.bounds.y2 - srcInfo.bounds.y1) : -1;
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biBitCount = srcInfo.pixelStride * 8;
	// 1,3,4 byte use BI_RGB, 2 byte use BI_BITFIELD...
	// 4 byte _can_ use BI_BITFIELD, but this seems to cause a performance
	// penalty.  Since we only ever have one format (xrgb) for 32-bit
	// images that enter this function, just use BI_RGB.
	// Could do BI_RGB for 2-byte 555 format, but no perceived
	// performance benefit.
	bmi.bmiHeader.biCompression = (srcInfo.pixelStride != 2)
		? BI_RGB : BI_BITFIELDS;
	bmi.bmiHeader.biSizeImage = (bmi.bmiHeader.biWidth * 
				     bmi.bmiHeader.biHeight * 
				     srcInfo.pixelStride);
	bmi.bmiHeader.biXPelsPerMeter = 0;
	bmi.bmiHeader.biYPelsPerMeter = 0;
	bmi.bmiHeader.biClrUsed = 0;
	bmi.bmiHeader.biClrImportant = 0;
	if (srcInfo.pixelStride == 1) {
	    // Copy palette info into bitmap for 8-bit image
	    if (needLut) {
		memcpy(bmi.colors.palette, srcInfo.lutBase, srcInfo.lutSize * sizeof(RGBQUAD));
		if (srcInfo.lutSize != 256) {
		    bmi.bmiHeader.biClrUsed = srcInfo.lutSize;
		}
	    } else {
		// If no LUT needed, must be ByteGray src.  If we have not
		// yet created the byteGrayPalette, create it now and copy
		// it into our temporary bmi structure.
		// REMIND: byteGrayPalette is a leak since we do not have
		// a mechansim to free it up.  This should be fine, since it
		// is only 256 bytes for any process and only gets malloc'd
		// when using ByteGray surfaces.  Eventually, we should use
		// the new Disposer mechanism to delete this native memory.
		if (byteGrayPalette == NULL) {
		    byteGrayPalette = (RGBQUAD *)safe_Malloc(256 * sizeof(RGBQUAD));
		    for (int i = 0; i < 256; ++i) {
			byteGrayPalette[i].rgbRed = i;
			byteGrayPalette[i].rgbGreen = i;
			byteGrayPalette[i].rgbBlue = i;
		    }
		}
		memcpy(bmi.colors.palette, byteGrayPalette, 256 * sizeof(RGBQUAD));
	    }
	} else if (srcInfo.pixelStride == 2) {
	    // For 16-bit case, init the masks for the pixel depth
	    bmi.colors.dwMasks[0] = rmask;
	    bmi.colors.dwMasks[1] = gmask;
	    bmi.colors.dwMasks[2] = bmask;
	} 
	if (fastBlt) {
	    // Window could go away at any time, leaving bits on the screen
	    // from this GDI call, so make sure window still exists
	    if (::IsWindowVisible(dstOps->window)) {
		// Could also call StretchDIBits.  Testing showed slight
		// performance advantage of SetDIBits instead, so since we
		// have no need of scaling, might as well use SetDIBits.
		SetDIBitsToDevice(hDC, dstx, dsty, width, height, 
		    0, 0, 0, height, rasBase, 
		    (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
	    }
	} else {
	    // Source scanlines not DWORD-aligned - copy each scanline individually
	    for (int i = 0; i < height; i += 1) {
		if (::IsWindowVisible(dstOps->window)) {
		    SetDIBitsToDevice(hDC, dstx, dsty+i, width, 1, 
			0, 0, 0, 1, rasBase, 
			(BITMAPINFO*)&bmi, DIB_RGB_COLORS);
		    rasBase = (void*)((char*)rasBase + srcInfo.scanStride);
		} else {
		    break;
		}
	    }
	}	
	SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
    }
    SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
    dstOps->ReleaseDC(env, dstOps, hDC);

    return;
}
예제 #20
0
/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getFileChooserBitmapBits
 * Signature: ()[I
 */
JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getFileChooserBitmapBits
    (JNIEnv* env, jclass cls)
{
    HBITMAP hBitmap = NULL;
    BITMAP bm;
    HINSTANCE libComCtl32;
    HINSTANCE libShell32;


    libShell32 = LoadLibrary(TEXT("shell32.dll"));
    if (libShell32 != NULL) {
	hBitmap = (HBITMAP)LoadImage(libShell32, MAKEINTRESOURCE(216),
				     IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
    }
    if (hBitmap == NULL) {
	libComCtl32 = LoadLibrary(TEXT("comctl32.dll"));
	if (libComCtl32 != NULL) {
	    hBitmap = (HBITMAP)LoadImage(libComCtl32, MAKEINTRESOURCE(124),
					 IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
	}
    }
    if (hBitmap == NULL) {
	return NULL;
    }

    GetObject(hBitmap, sizeof(bm), (LPSTR)&bm);

    // Get the screen DC
    HDC dc = GetDC(NULL);
    if (dc == NULL) {
        return NULL;
    }

    // Set up BITMAPINFO
    BITMAPINFO bmi;
    memset(&bmi, 0, sizeof(BITMAPINFO));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = bm.bmWidth;
    bmi.bmiHeader.biHeight = -bm.bmHeight;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    // Extract the color bitmap
    int numPixels = bm.bmWidth * bm.bmHeight;
    //long colorBits[192 * 16];
    long *colorBits = (long*)safe_Malloc(numPixels * sizeof(long));
    if (GetDIBits(dc, hBitmap, 0, bm.bmHeight, colorBits, &bmi, DIB_RGB_COLORS) == 0) {
        return NULL;
    }

    // Release DC
    ReleaseDC(NULL, dc);

    // The color of the first pixel defines the transparency, according
    // to the documentation for LR_LOADTRANSPARENT at
    // http://msdn.microsoft.com/library/psdk/winui/resource_9fhi.htm
    long transparent = colorBits[0];
    for (int i=0; i < numPixels; i++) {
	if (colorBits[i] != transparent) {
	    colorBits[i] |= 0xff000000;
	}
    }

    // Create java array
    jintArray bits = env->NewIntArray(numPixels);
    // Copy values to java array
    env->SetIntArrayRegion(bits, 0, numPixels, colorBits);
    // Fix 4745575 GDI Resource Leak
    ::DeleteObject(hBitmap);
    ::FreeLibrary(libComCtl32);
    return bits;
}
예제 #21
0
WORD AwtPrintControl::getNearestMatchingPaper(LPTSTR printer, LPTSTR port,
                                      double origWid, double origHgt,
                                      double* newWid, double *newHgt) {
    const double epsilon = 0.50;
    const double tolerance = (1.0 * 72.0);  // # inches * 72
    int numPaperSizes = 0;
    WORD *papers = NULL;
    POINT *paperSizes = NULL;

    if ((printer== NULL) || (port == NULL)) {
        return 0;
    }

    SAVE_CONTROLWORD
    numPaperSizes = (int)DeviceCapabilities(printer, port, DC_PAPERSIZE,
                                              NULL, NULL);

    if (numPaperSizes > 0) {
        papers = (WORD*)safe_Malloc(sizeof(WORD) * numPaperSizes);
        paperSizes = (POINT *)safe_Malloc(sizeof(*paperSizes) *
                                          numPaperSizes);

        DWORD result1 = DeviceCapabilities(printer, port,
                                       DC_PAPERS, (LPTSTR) papers, NULL);

        DWORD result2 = DeviceCapabilities(printer, port,
                                       DC_PAPERSIZE, (LPTSTR) paperSizes,
                                       NULL);

        // REMIND: cache in papers and paperSizes
        if (result1 == -1 || result2 == -1 ) {
            free((LPTSTR) papers);
            papers = NULL;
            free((LPTSTR) paperSizes);
            paperSizes = NULL;
        }
    }
    RESTORE_CONTROLWORD

    double closestWid = 0.0;
    double closestHgt = 0.0;
    WORD   closestMatch = 0;

    if (paperSizes != NULL) {

      /* Paper sizes are in 0.1mm units. Convert to 1/72"
       * For each paper size, compute the difference from the paper size
       * passed in. Use a least-squares difference, so paper much different
       * in x or y should score poorly
       */
        double diffw = origWid;
        double diffh = origHgt;
        double least_square = diffw * diffw + diffh * diffh;
        double tmp_ls;
        double widpts, hgtpts;

        for (int i=0;i<numPaperSizes;i++) {
            widpts = paperSizes[i].x * LOMETRIC_TO_POINTS;
            hgtpts = paperSizes[i].y * LOMETRIC_TO_POINTS;

            if ((fabs(origWid - widpts) < epsilon) &&
                (fabs(origHgt - hgtpts) < epsilon)) {
                closestWid = origWid;
                closestHgt = origHgt;
                closestMatch = papers[i];
                break;
            }

            diffw = fabs(widpts - origWid);
            diffh = fabs(hgtpts - origHgt);
            tmp_ls = diffw * diffw + diffh * diffh;
            if ((diffw < tolerance) && (diffh < tolerance) &&
                (tmp_ls < least_square)) {
                least_square = tmp_ls;
                closestWid = widpts;
                closestHgt = hgtpts;
                closestMatch = papers[i];
            }
        }
    }

    if (closestWid > 0) {
        *newWid = closestWid;
    }
    if (closestHgt > 0) {
        *newHgt = closestHgt;
    }

    if (papers != NULL) {
        free((LPTSTR)papers);
    }

    if (paperSizes != NULL) {
        free((LPTSTR)paperSizes);
    }

    return closestMatch;
}
예제 #22
0
/*
 * Class:     sun_awt_windows_WClipboard
 * Method:    getClipboardData
 * Signature: (J)[B
 */
JNIEXPORT jbyteArray JNICALL
Java_sun_awt_windows_WClipboard_getClipboardData
    (JNIEnv *env, jobject self, jlong format)
{
    TRY;

    DASSERT(::GetOpenClipboardWindow() == AwtToolkit::GetInstance().GetHWnd());

    HANDLE handle = ::GetClipboardData((UINT)format);
    if (handle == NULL) {
        JNU_ThrowIOException(env, "system clipboard data unavailable");
        return NULL;
    }

    jbyteArray bytes = NULL;
    jbyteArray paletteData = NULL;

    switch (format) {
    case CF_ENHMETAFILE:
    case CF_METAFILEPICT: {
        HENHMETAFILE hemf = NULL;

        if (format == CF_METAFILEPICT) {
            HMETAFILEPICT hMetaFilePict = (HMETAFILEPICT)handle;
            LPMETAFILEPICT lpMetaFilePict =
                (LPMETAFILEPICT)::GlobalLock(hMetaFilePict);
            UINT uSize = ::GetMetaFileBitsEx(lpMetaFilePict->hMF, 0, NULL);
            DASSERT(uSize != 0);

            try {
                LPBYTE lpMfBits = (LPBYTE)safe_Malloc(uSize);
                VERIFY(::GetMetaFileBitsEx(lpMetaFilePict->hMF, uSize,
                                           lpMfBits) == uSize);
                hemf = ::SetWinMetaFileBits(uSize, lpMfBits, NULL,
                                            lpMetaFilePict);
                free(lpMfBits);
                if (hemf == NULL) {
                    ::GlobalUnlock(hMetaFilePict);
                    JNU_ThrowIOException(env, "failed to get system clipboard data");
                    return NULL;
                }
            } catch (...) {
                ::GlobalUnlock(hMetaFilePict);
                throw;
            }
            ::GlobalUnlock(hMetaFilePict);
        } else {
            hemf = (HENHMETAFILE)handle;
        }

        UINT uEmfSize = ::GetEnhMetaFileBits(hemf, 0, NULL);
        if (uEmfSize == 0) {
            JNU_ThrowIOException(env, "cannot retrieve metafile bits");
            return NULL;
        }

        bytes = env->NewByteArray(uEmfSize);
        if (bytes == NULL) {
            throw std::bad_alloc();
        }

        LPBYTE lpbEmfBuffer =
            (LPBYTE)env->GetPrimitiveArrayCritical(bytes, NULL);
        if (lpbEmfBuffer == NULL) {
            env->DeleteLocalRef(bytes);
            throw std::bad_alloc();
        }
        VERIFY(::GetEnhMetaFileBits(hemf, uEmfSize, lpbEmfBuffer) == uEmfSize);
        env->ReleasePrimitiveArrayCritical(bytes, lpbEmfBuffer, 0);

        paletteData =
            AwtDataTransferer::GetPaletteBytes(hemf, OBJ_ENHMETAFILE, FALSE);
        break;
    }
    case CF_LOCALE: {
        LCID *lcid = (LCID *)::GlobalLock(handle);
        if (lcid == NULL) {
            JNU_ThrowIOException(env, "invalid LCID");
            return NULL;
        }
        try {
            bytes = AwtDataTransferer::LCIDToTextEncoding(env, *lcid);
        } catch (...) {
            ::GlobalUnlock(handle);
            throw;
        }
        ::GlobalUnlock(handle);
        break;
    }
    default: {
        ::SetLastError(0); // clear error
        // Warning C4244.
        // Cast SIZE_T (__int64 on 64-bit/unsigned int on 32-bit)
        // to jsize (long).
        SIZE_T globalSize = ::GlobalSize(handle);
        jsize size = (globalSize <= INT_MAX) ? (jsize)globalSize : INT_MAX;
        if (::GetLastError() != 0) {
            JNU_ThrowIOException(env, "invalid global memory block handle");
            return NULL;
        }

        bytes = env->NewByteArray(size);
        if (bytes == NULL) {
            throw std::bad_alloc();
        }

        if (size != 0) {
            LPVOID data = ::GlobalLock(handle);
            env->SetByteArrayRegion(bytes, 0, size, (jbyte *)data);
            ::GlobalUnlock(handle);
        }
        break;
    }
    }

    switch (format) {
    case CF_ENHMETAFILE:
    case CF_METAFILEPICT:
    case CF_DIB: {
        if (JNU_IsNull(env, paletteData)) {
            HPALETTE hPalette = (HPALETTE)::GetClipboardData(CF_PALETTE);
            paletteData =
                AwtDataTransferer::GetPaletteBytes(hPalette, OBJ_PAL, TRUE);
        }
        DASSERT(!JNU_IsNull(env, paletteData) &&
                !JNU_IsNull(env, bytes));

        jbyteArray concat =
            (jbyteArray)AwtDataTransferer::ConcatData(env, paletteData, bytes);

        if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
            env->ExceptionDescribe();
            env->ExceptionClear();
            env->DeleteLocalRef(bytes);
            env->DeleteLocalRef(paletteData);
            return NULL;
        }

        env->DeleteLocalRef(bytes);
        env->DeleteLocalRef(paletteData);
        bytes = concat;
        break;
    }
    }

    return bytes;

    CATCH_BAD_ALLOC_RET(NULL);
}