/** * 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_SIZE_ARRAY_ALLOC(safe_Malloc, numDevices, sizeof(AwtWin32GraphicsDevice *)); }
/* Could use npt but decided to cut down on linked code size */ char* SplashConvertStringAlloc(const char* in, int* size) { const char *codeset; const char *codeset_out; iconv_t cd; size_t rc; char *buf = NULL, *out; size_t bufSize, inSize, outSize; const char* old_locale; if (!in) { return NULL; } old_locale = setlocale(LC_ALL, ""); codeset = nl_langinfo(CODESET); if ( codeset == NULL || codeset[0] == 0 ) { goto done; } /* we don't need BOM in output so we choose native BE or LE encoding here */ codeset_out = (platformByteOrder()==BYTE_ORDER_MSBFIRST) ? "UCS-2BE" : "UCS-2LE"; cd = iconv_open(codeset_out, codeset); if (cd == (iconv_t)-1 ) { goto done; } inSize = strlen(in); buf = SAFE_SIZE_ARRAY_ALLOC(malloc, inSize, 2); if (!buf) { return NULL; } bufSize = inSize*2; // need 2 bytes per char for UCS-2, this is // 2 bytes per source byte max out = buf; outSize = bufSize; /* linux iconv wants char** source and solaris wants const char**... cast to void* */ rc = iconv(cd, (void*)&in, &inSize, &out, &outSize); iconv_close(cd); if (rc == (size_t)-1) { free(buf); buf = NULL; } else { if (size) { *size = (bufSize-outSize)/2; /* bytes to wchars */ } } done: setlocale(LC_ALL, old_locale); return buf; }
// 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_SIZE_ARRAY_ALLOC(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; } }
static void AddFontsToX11FontPath ( fDirRecord *fDirP ) { char *onePath; int index, nPaths; int origNumPaths, length; int origIndex; int totalDirCount; char **origFontPath; char **tempFontPath; int doNotAppend; int *appendDirList; char **newFontPath; int err, compareLength; char fontDirPath[512]; int dirFile; doNotAppend = 0; if ( fDirP->num == 0 ) return; appendDirList = SAFE_SIZE_ARRAY_ALLOC(malloc, fDirP->num, sizeof ( int )); if ( appendDirList == NULL ) { return; /* if it fails we cannot do much */ } origFontPath = XGetFontPath ( awt_display, &nPaths ); totalDirCount = nPaths; origNumPaths = nPaths; tempFontPath = origFontPath; for (index = 0; index < fDirP->num; index++ ) { doNotAppend = 0; tempFontPath = origFontPath; for ( origIndex = 0; origIndex < nPaths; origIndex++ ) { onePath = *tempFontPath; compareLength = strlen ( onePath ); if ( onePath[compareLength -1] == '/' ) compareLength--; /* there is a slash at the end of every solaris X11 font path name */ if ( strncmp ( onePath, fDirP->name[index], compareLength ) == 0 ) { doNotAppend = 1; break; } tempFontPath++; } appendDirList[index] = 0; if ( doNotAppend == 0 ) { strcpy ( fontDirPath, fDirP->name[index] ); strcat ( fontDirPath, "/fonts.dir" ); dirFile = open ( fontDirPath, O_RDONLY, 0 ); if ( dirFile == -1 ) { doNotAppend = 1; } else { close ( dirFile ); totalDirCount++; appendDirList[index] = 1; } } } /* if no changes are required do not bother to do a setfontpath */ if ( totalDirCount == nPaths ) { free ( ( void *) appendDirList ); XFreeFontPath ( origFontPath ); return; } newFontPath = SAFE_SIZE_ARRAY_ALLOC(malloc, totalDirCount, sizeof ( char **) ); /* if it fails free things and get out */ if ( newFontPath == NULL ) { free ( ( void *) appendDirList ); XFreeFontPath ( origFontPath ); return; } for ( origIndex = 0; origIndex < nPaths; origIndex++ ) { onePath = origFontPath[origIndex]; newFontPath[origIndex] = onePath; } /* now add the other font paths */ for (index = 0; index < fDirP->num; index++ ) { if ( appendDirList[index] == 1 ) { /* printf ( "Appending %s\n", fDirP->name[index] ); */ onePath = SAFE_SIZE_ARRAY_ALLOC(malloc, strlen (fDirP->name[index]) + 2, sizeof( char ) ); if (onePath == NULL) { free ( ( void *) appendDirList ); XFreeFontPath ( origFontPath ); return; } strcpy ( onePath, fDirP->name[index] ); strcat ( onePath, "/" ); newFontPath[nPaths++] = onePath; /* printf ( "The path to be appended is %s\n", onePath ); */ } } /* printf ( "The dir count = %d\n", totalDirCount ); */ free ( ( void *) appendDirList ); XSetFontPath ( awt_display, newFontPath, totalDirCount ); for ( index = origNumPaths; index < totalDirCount; index++ ) { free( newFontPath[index] ); } free ( (void *) newFontPath ); XFreeFontPath ( origFontPath ); return; }
JNIEXPORT jlong JNICALL Java_sun_font_FileFontStrike__1getGlyphImageFromWindows (JNIEnv *env, jobject unused, jstring fontFamily, jint style, jint size, jint glyphCode, jboolean fm) { GLYPHMETRICS glyphMetrics; LOGFONTW lf; BITMAPINFO bmi; TEXTMETRIC textMetric; RECT rect; int bytesWidth, dibBytesWidth, extra, imageSize, dibImageSize; unsigned char* dibImage = NULL, *rowPtr, *pixelPtr, *dibPixPtr, *dibRowPtr; unsigned char r,g,b; unsigned char* igTable; GlyphInfo* glyphInfo = NULL; int nameLen; LPWSTR name; HFONT oldFont, hFont; MAT2 mat2; unsigned short width; unsigned short height; short advanceX; short advanceY; int topLeftX; int topLeftY; int err; int bmWidth, bmHeight; int x, y; HBITMAP hBitmap = NULL, hOrigBM; int gamma, orient; HWND hWnd = NULL; HDC hDesktopDC = NULL; HDC hMemoryDC = NULL; hWnd = GetDesktopWindow(); hDesktopDC = GetWindowDC(hWnd); if (hDesktopDC == NULL) { return (jlong)0; } if (GetDeviceCaps(hDesktopDC, BITSPIXEL) < 15) { FREE_AND_RETURN; } hMemoryDC = CreateCompatibleDC(hDesktopDC); if (hMemoryDC == NULL || fontFamily == NULL) { FREE_AND_RETURN; } err = SetMapMode(hMemoryDC, MM_TEXT); if (err == 0) { FREE_AND_RETURN; } memset(&lf, 0, sizeof(LOGFONTW)); lf.lfHeight = -size; lf.lfWeight = (style & 1) ? FW_BOLD : FW_NORMAL; lf.lfItalic = (style & 2) ? 0xff : 0; lf.lfCharSet = DEFAULT_CHARSET; lf.lfQuality = CLEARTYPE_QUALITY; lf.lfOutPrecision = OUT_TT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfPitchAndFamily = DEFAULT_PITCH; nameLen = (*env)->GetStringLength(env, fontFamily); name = (LPWSTR)alloca((nameLen+1)*2); if (name == NULL) { FREE_AND_RETURN; } (*env)->GetStringRegion(env, fontFamily, 0, nameLen, name); name[nameLen] = '\0'; if (nameLen < (sizeof(lf.lfFaceName) / sizeof(lf.lfFaceName[0]))) { wcscpy(lf.lfFaceName, name); } else { FREE_AND_RETURN; } hFont = CreateFontIndirectW(&lf); if (hFont == NULL) { FREE_AND_RETURN; } oldFont = SelectObject(hMemoryDC, hFont); memset(&textMetric, 0, sizeof(TEXTMETRIC)); err = GetTextMetrics(hMemoryDC, &textMetric); if (err == 0) { FREE_AND_RETURN; } memset(&glyphMetrics, 0, sizeof(GLYPHMETRICS)); memset(&mat2, 0, sizeof(MAT2)); mat2.eM11.value = 1; mat2.eM22.value = 1; err = GetGlyphOutline(hMemoryDC, glyphCode, GGO_METRICS|GGO_GLYPH_INDEX, &glyphMetrics, 0, NULL, &mat2); if (err == GDI_ERROR) { /* Probably no such glyph - ie the font wasn't the one we expected. */ FREE_AND_RETURN; } width = (unsigned short)glyphMetrics.gmBlackBoxX; height = (unsigned short)glyphMetrics.gmBlackBoxY; /* Don't handle "invisible" glyphs in this code */ if (width <= 0 || height == 0) { FREE_AND_RETURN; } advanceX = glyphMetrics.gmCellIncX; advanceY = glyphMetrics.gmCellIncY; topLeftX = glyphMetrics.gmptGlyphOrigin.x; topLeftY = glyphMetrics.gmptGlyphOrigin.y; /* GetGlyphOutline pre-dates cleartype and I'm not sure that it will * account for all pixels touched by the rendering. Need to widen, * and also adjust by one the x position at which it is rendered. * The extra pixels of width are used as follows : * One extra pixel at the left and the right will be needed to absorb * the pixels that will be touched by filtering by GDI to compensate * for colour fringing. * However there seem to be some cases where GDI renders two extra * pixels to the right, so we add one additional pixel to the right, * and in the code that copies this to the image cache we test for * the (rare) cases when this is touched, and if its not reduce the * stated image width for the blitting loops. * For fractional metrics : * One extra pixel at each end to account for sub-pixel positioning used * when fractional metrics is on in LCD mode. * The pixel at the left is needed so the blitting loop can index into * that a byte at a time to more accurately position the glyph. * The pixel at the right is needed so that when such indexing happens, * the blitting still can use the same width. * Consequently the width that is specified for the glyph is one less * than that of the actual image. * Note that in the FM case as a consequence we need to adjust the * position at which GDI renders, and the declared width of the glyph * See the if (fm) {} cases in the code. * For the non-FM case, we not only save 3 bytes per row, but this * prevents apparent glyph overlapping which affects the rendering * performance of accelerated pipelines since it adds additional * read-back requirements. */ width+=3; if (fm) { width+=1; } /* DIB scanline must end on a DWORD boundary. We specify 3 bytes per pixel, * so must round up as needed to a multiple of 4 bytes. */ dibBytesWidth = bytesWidth = width*3; extra = dibBytesWidth % 4; if (extra != 0) { dibBytesWidth += (4-extra); } /* The glyph cache image must be a multiple of 3 bytes wide. */ extra = bytesWidth % 3; if (extra != 0) { bytesWidth += (3-extra); } bmWidth = width; bmHeight = height; /* Must use desktop DC to create a bitmap of that depth */ hBitmap = CreateCompatibleBitmap(hDesktopDC, bmWidth, bmHeight); if (hBitmap == NULL) { FREE_AND_RETURN; } hOrigBM = (HBITMAP)SelectObject(hMemoryDC, hBitmap); /* Fill in black */ rect.left = 0; rect.top = 0; rect.right = bmWidth; rect.bottom = bmHeight; FillRect(hMemoryDC, (LPRECT)&rect, GetStockObject(BLACK_BRUSH)); /* Set text color to white, background to black. */ SetBkColor(hMemoryDC, RGB(0,0,0)); SetTextColor(hMemoryDC, RGB(255,255,255)); /* adjust rendering position */ x = -topLeftX+1; if (fm) { x += 1; } y = topLeftY - textMetric.tmAscent; err = ExtTextOutW(hMemoryDC, x, y, ETO_GLYPH_INDEX|ETO_OPAQUE, (LPRECT)&rect, (LPCWSTR)&glyphCode, 1, NULL); if (err == 0) { FREE_AND_RETURN; } /* Now get the image into a DIB. * MS docs for GetDIBits says the compatible bitmap must not be * selected into a DC, so restore the original first. */ SelectObject(hMemoryDC, hOrigBM); SelectObject(hMemoryDC, oldFont); DeleteObject(hFont); memset(&bmi, 0, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = -height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB; dibImage = SAFE_SIZE_ARRAY_ALLOC(malloc, dibBytesWidth, height); if (dibImage == NULL) { FREE_AND_RETURN; } dibImageSize = dibBytesWidth*height; memset(dibImage, 0, dibImageSize); err = GetDIBits(hMemoryDC, hBitmap, 0, height, dibImage, &bmi, DIB_RGB_COLORS); if (err == 0) { /* GetDIBits failed. */ FREE_AND_RETURN; } err = SystemParametersInfo(SPI_GETFONTSMOOTHINGORIENTATION, 0, &orient, 0); if (err == 0) { FREE_AND_RETURN; } err = SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &gamma, 0); if (err == 0) { FREE_AND_RETURN; } igTable = getIGTable(gamma/10); if (igTable == NULL) { FREE_AND_RETURN; } /* Now copy glyph image into a GlyphInfo structure and return it. * NB the xadvance calculated here may be overwritten by the caller. * 1 is subtracted from the bitmap width to get the glyph width, since * that extra "1" was added as padding, so the sub-pixel positioning of * fractional metrics could index into it. */ glyphInfo = (GlyphInfo*)SAFE_SIZE_STRUCT_ALLOC(malloc, sizeof(GlyphInfo), bytesWidth, height); if (glyphInfo == NULL) { FREE_AND_RETURN; } imageSize = bytesWidth*height; glyphInfo->cellInfo = NULL; glyphInfo->rowBytes = bytesWidth; glyphInfo->width = width; if (fm) { glyphInfo->width -= 1; // must subtract 1 } glyphInfo->height = height; glyphInfo->advanceX = advanceX; glyphInfo->advanceY = advanceY; glyphInfo->topLeftX = (float)(topLeftX-1); if (fm) { glyphInfo->topLeftX -= 1; } glyphInfo->topLeftY = (float)-topLeftY; glyphInfo->image = (unsigned char*)glyphInfo+sizeof(GlyphInfo); memset(glyphInfo->image, 0, imageSize); /* DIB 24bpp data is always stored in BGR order, but we usually * need this in RGB, so we can't just memcpy and need to swap B and R. * Also need to apply inverse gamma adjustment here. * We re-use the variable "extra" to see if the last pixel is touched * at all. If its not we can reduce the glyph image width. This comes * into play in some cases where GDI touches more pixels than accounted * for by increasing width by two pixels over the B&W image. Whilst * the bytes are in the cache, it doesn't affect rendering performance * of the hardware pipelines. */ extra = 0; if (fm) { extra = 1; // always need it. } dibRowPtr = dibImage; rowPtr = glyphInfo->image; for (y=0;y<height;y++) { pixelPtr = rowPtr; dibPixPtr = dibRowPtr; for (x=0;x<width;x++) { if (orient == FE_FONTSMOOTHINGORIENTATIONRGB) { b = *dibPixPtr++; g = *dibPixPtr++; r = *dibPixPtr++; } else { r = *dibPixPtr++; g = *dibPixPtr++; b = *dibPixPtr++; } *pixelPtr++ = igTable[r]; *pixelPtr++ = igTable[g]; *pixelPtr++ = igTable[b]; if (!fm && (x==(width-1)) && (r|g|b)) { extra = 1; } } dibRowPtr += dibBytesWidth; rowPtr += bytesWidth; } if (!extra) { glyphInfo->width -= 1; } free(dibImage); ReleaseDC(hWnd, hDesktopDC); DeleteObject(hMemoryDC); DeleteObject(hBitmap); return ptr_to_jlong(glyphInfo); }
JNIEXPORT void JNICALL Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env, jclass cls, jobject xgc, jint x, jint y, jint width, jint height, jintArray pixelArray) { XImage *image; jint *ary; /* Array of jints for sending pixel values back * to parent process. */ Window rootWindow; AwtGraphicsConfigDataPtr adata; DTRACE_PRINTLN6("RobotPeer: getRGBPixelsImpl(%lx, %d, %d, %d, %d, %x)", xgc, x, y, width, height, pixelArray); AWT_LOCK(); /* avoid a lot of work for empty rectangles */ if ((width * height) == 0) { AWT_UNLOCK(); return; } DASSERT(width * height > 0); /* only allow positive size */ adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, xgc, x11GraphicsConfigIDs.aData); DASSERT(adata != NULL); rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen); image = getWindowImage(awt_display, rootWindow, x, y, width, height); /* Array to use to crunch around the pixel values */ if (!IS_SAFE_SIZE_MUL(width, height) || !(ary = (jint *) SAFE_SIZE_ARRAY_ALLOC(malloc, width * height, sizeof (jint)))) { JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); XDestroyImage(image); AWT_UNLOCK(); return; } /* convert to Java ARGB pixels */ for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { jint pixel = (jint) XGetPixel(image, x, y); /* Note ignore upper * 32-bits on 64-bit * OSes. */ pixel |= 0xff000000; /* alpha - full opacity */ ary[(y * width) + x] = pixel; } } (*env)->SetIntArrayRegion(env, pixelArray, 0, height * width, ary); free(ary); XDestroyImage(image); AWT_UNLOCK(); }
// static BOOL Devices::UpdateInstance(JNIEnv *env) { J2dTraceLn(J2D_TRACE_INFO, "Devices::UpdateInstance"); int numScreens = ::CountMonitors(); MHND *monHds = (MHND *)SAFE_SIZE_ARRAY_ALLOC(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; }
JNIEXPORT jintArray JNICALL Java_sun_print_Win32PrintService_getDefaultSettings(JNIEnv *env, jobject peer, jstring printer, jstring port) { HANDLE hPrinter; LPDEVMODE pDevMode = NULL; LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); if (printerName == NULL || printerPort == NULL) { if (printerName != NULL) { JNU_ReleaseStringPlatformChars(env, printer, printerName); } if (printerPort != NULL) { JNU_ReleaseStringPlatformChars(env, port, printerPort); } return NULL; } jint* defIndices = NULL; jintArray defaultArray = env->NewIntArray(NDEFAULT); if (defaultArray != NULL) { defIndices = env->GetIntArrayElements(defaultArray, NULL); } if (defIndices == NULL) { JNU_ReleaseStringPlatformChars(env, printer, printerName); JNU_ReleaseStringPlatformChars(env, port, printerPort); return NULL; } jint *saveFormats = defIndices; for (int i=0; i < NDEFAULT; i++) { defIndices[i] = GETDEFAULT_ERROR; } /* Start by opening the printer */ if (!::OpenPrinter(printerName, &hPrinter, NULL)) { env->ReleaseIntArrayElements(defaultArray, saveFormats, 0); JNU_ReleaseStringPlatformChars(env, printer, printerName); JNU_ReleaseStringPlatformChars(env, port, printerPort); return defaultArray; } if (!AwtPrintControl::getDevmode(hPrinter, printerName, &pDevMode)) { /* if failure, cleanup and return failure */ if (pDevMode != NULL) { ::GlobalFree(pDevMode); } ::ClosePrinter(hPrinter); env->ReleaseIntArrayElements(defaultArray, saveFormats, 0); JNU_ReleaseStringPlatformChars(env, printer, printerName); JNU_ReleaseStringPlatformChars(env, port, printerPort); return defaultArray; } /* Have seen one driver which reports a default paper id which is not * one of their supported paper ids. If what is returned is not * a supported paper, use one of the supported sizes instead. * */ if (pDevMode->dmFields & DM_PAPERSIZE) { defIndices[0] = pDevMode->dmPaperSize; SAVE_CONTROLWORD int numSizes = ::DeviceCapabilities(printerName, printerPort, DC_PAPERS, NULL, NULL); if (numSizes > 0) { LPTSTR papers = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, numSizes, sizeof(WORD)); if (papers != NULL && ::DeviceCapabilities(printerName, printerPort, DC_PAPERS, papers, NULL) != -1) { int present = 0; for (int i=0;i<numSizes;i++) { if (papers[i] == pDevMode->dmPaperSize) { present = 1; } } if (!present) { defIndices[0] = papers[0]; } if (papers != NULL) { free((char*)papers); } } } RESTORE_CONTROLWORD }
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"), AwtToolkit::GetNumberOfButtons()); 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)); SetBooleanProperty(TEXT("awt.wheelMousePresent"), ::GetSystemMetrics(SM_MOUSEWHEELPRESENT)); // END cross-platform properties //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)); 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); } SHELLFLAGSTATE sfs; ::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); try { if (value != NULL) { if (valueType == REG_SZ) { SetStringProperty(TEXT("win.icon.shellIconBPP"), value); } free(value); value = NULL; } // 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); } } catch (std::bad_alloc&) { if (value != NULL) { free(value); } throw; } LPTSTR valueName = TEXT("PlaceN"); LPTSTR valueNameBuf = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (lstrlen(valueName) + 1), sizeof(TCHAR)); lstrcpy(valueNameBuf, valueName); LPTSTR propKey = TEXT("win.comdlg.placesBarPlaceN"); LPTSTR propKeyBuf; try { propKeyBuf = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (lstrlen(propKey) + 1), sizeof(TCHAR)); } catch (std::bad_alloc&) { free(valueNameBuf); throw; } 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"); try { value = NULL; 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); } } catch (std::bad_alloc&) { if (value != NULL) { free(value); } free(propKeyBuf); free(valueNameBuf); throw; } } while (value != NULL); free(propKeyBuf); free(valueNameBuf); }
/* * 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); }
/* * Class: sun_awt_datatransfer_DataTransferer * Method: draqQueryFile * Signature: ([B)[Ljava/lang/String; */ JNIEXPORT jobjectArray JNICALL Java_sun_awt_windows_WDataTransferer_dragQueryFile (JNIEnv *env, jobject obj, jbyteArray bytes) { TRY; /* * Fix for the BugTraq ID 4327064 - inter-jvm DnD crashes the droping jvm. * On Win9X DragQueryFile() doesn't accept a pointer to the local help as the first * argument, so we should dump the bits into global memory. */ UINT size = env->GetArrayLength(bytes); HGLOBAL hglobal = NULL; jbyte *bBytes = NULL; HDROP hdrop = NULL; LPTSTR buffer = NULL; hglobal = ::GlobalAlloc(GALLOCFLG, size); if (hglobal == NULL) { throw std::bad_alloc(); } try { bBytes = (jbyte*)::GlobalLock(hglobal); env->GetByteArrayRegion(bytes, 0, size, bBytes); hdrop = (HDROP)bBytes; UINT nFilenames = ::DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0); jclass str_clazz = env->FindClass("java/lang/String"); DASSERT(str_clazz != NULL); jobjectArray filenames = env->NewObjectArray(nFilenames, str_clazz, NULL); if (filenames == NULL) { throw std::bad_alloc(); } UINT bufsize = 512; // in characters, not in bytes buffer = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, bufsize, sizeof(TCHAR)); for (UINT i = 0; i < nFilenames; i++) { UINT size = ::DragQueryFile(hdrop, i, NULL, 0); if (size > bufsize) { bufsize = size; buffer = (LPTSTR)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, buffer, bufsize, sizeof(TCHAR)); } ::DragQueryFile(hdrop, i, buffer, bufsize); jstring name = JNU_NewStringPlatform(env, buffer); if (name == NULL) { throw std::bad_alloc(); } env->SetObjectArrayElement(filenames, i, name); } free(buffer); ::GlobalUnlock(hglobal); ::GlobalFree(hglobal); return filenames; } catch (std::bad_alloc&) { free(buffer); ::GlobalUnlock(hglobal); ::GlobalFree(hglobal); throw; } CATCH_BAD_ALLOC_RET(NULL); }
/* * Class: sun_java2d_opengl_WGLSurfaceData * Method: updateWindowAccelImpl * Signature: (JJII)Z */ JNIEXPORT jboolean JNICALL Java_sun_java2d_opengl_WGLSurfaceData_updateWindowAccelImpl (JNIEnv *env, jclass clazz, jlong pData, jobject peer, jint w, jint h) { OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData); OGLPixelFormat pf = PixelFormats[0/*PF_INT_ARGB_PRE*/]; HBITMAP hBitmap = NULL; void *pDst; jint srcx, srcy, dstx, dsty, width, height; jint pixelStride = 4; jint scanStride = pixelStride * w; J2dTraceLn(J2D_TRACE_INFO, "WGLSurfaceData_updateWindowAccelImpl"); if (w <= 0 || h <= 0) { return JNI_TRUE; } if (oglsdo == NULL) { return JNI_FALSE; } RESET_PREVIOUS_OP(); width = w; height = h; srcx = srcy = dstx = dsty = 0; pDst = SAFE_SIZE_ARRAY_ALLOC(malloc, height, scanStride); if (pDst == NULL) { return JNI_FALSE; } ZeroMemory(pDst, height * scanStride); // the code below is mostly copied from OGLBlitLoops_SurfaceToSwBlit j2d_glPixelStorei(GL_PACK_SKIP_PIXELS, dstx); j2d_glPixelStorei(GL_PACK_ROW_LENGTH, scanStride / pixelStride); j2d_glPixelStorei(GL_PACK_ALIGNMENT, pf.alignment); // this accounts for lower-left origin of the source region srcx = oglsdo->xOffset + srcx; srcy = oglsdo->yOffset + oglsdo->height - (srcy + 1); // we must read one scanline at a time because there is no way // to read starting at the top-left corner of the source region while (height > 0) { j2d_glPixelStorei(GL_PACK_SKIP_ROWS, dsty); j2d_glReadPixels(srcx, srcy, width, 1, pf.format, pf.type, pDst); srcy--; dsty++; height--; } j2d_glPixelStorei(GL_PACK_SKIP_PIXELS, 0); j2d_glPixelStorei(GL_PACK_SKIP_ROWS, 0); j2d_glPixelStorei(GL_PACK_ROW_LENGTH, 0); j2d_glPixelStorei(GL_PACK_ALIGNMENT, 4); // the pixels read from the surface are already premultiplied hBitmap = BitmapUtil_CreateBitmapFromARGBPre(w, h, scanStride, (int*)pDst); free(pDst); if (hBitmap == NULL) { return JNI_FALSE; } AwtWindow_UpdateWindow(env, peer, w, h, hBitmap); // hBitmap is released in UpdateWindow return JNI_TRUE; }