bool StSettings::loadString(const StString& theParam, StString& theValue) { const StStringUtfWide aParam = theParam.toUtfWide(); StRegKey aKey; if(!aKey.open(myRegisterPath)) { return false; } // request size DWORD aValueSize = 0; if(RegQueryValueExW(aKey, aParam.toCString(), NULL, NULL, NULL, &aValueSize) != ERROR_SUCCESS) { return false; } if(aValueSize == 0) { theValue = ""; return true; } DWORD aValueSizeRead = aValueSize; stUtfWide_t* aDataOut = new stUtfWide_t[aValueSize / sizeof(stUtfWide_t) + 1]; if(RegQueryValueExW(aKey, aParam.toCString(), NULL, NULL, (LPBYTE )aDataOut, &aValueSizeRead) != ERROR_SUCCESS) { return false; } aDataOut[aValueSize / sizeof(stUtfWide_t)] = L'\0'; // NULL-terminate theValue = StString(aDataOut); return true; }
bool StFileNode::removeFile(const StCString& thePath) { #ifdef _WIN32 StStringUtfWide aPath; aPath.fromUnicode(thePath); return DeleteFileW(aPath.toCString()) != 0; #else return ::remove(thePath.toCString()) == 0; #endif }
bool StSettings::saveString(const StString& theParam, const StString& theValue) { StRegKey aKey; if(!aKey.create(myRegisterPath)) { return false; // No write registry success! } StStringUtfWide aValue = theValue.toUtfWide(); return RegSetValueExW(aKey, theParam.toUtfWide().toCString(), 0, REG_SZ, (LPBYTE )aValue.toCString(), DWORD(aValue.getSize() + sizeof(stUtfWide_t))) == ERROR_SUCCESS; }
bool StWinHandles::unregisterClass(StStringUtfWide& theName) { HMODULE aModule = GetModuleHandleW(NULL); if(!theName.isEmpty()) { if(UnregisterClassW(theName.toCString(), aModule) == 0) { ST_DEBUG_LOG("WinAPI, FAILED to unregister Class= '" + theName.toUtf8() + "'"); return false; } ST_DEBUG_LOG("WinAPI, Unregistered Class= " + theName.toUtf8()); theName.clear(); } return true; }
bool StFileNode::moveFile(const StCString& thePathFrom, const StCString& thePathTo) { #ifdef _WIN32 StStringUtfWide aPathFrom; aPathFrom.fromUnicode(thePathFrom); StStringUtfWide aPathTo; aPathTo .fromUnicode(thePathTo); return MoveFileW(aPathFrom.toCString(), aPathTo.toCString()) != 0; #else return ::rename(thePathFrom.toCString(), thePathTo.toCString()) == 0; #endif }
void StApplication::stApplicationInit(const StHandle<StOpenInfo>& theOpenInfo) { if(myResMgr.isNull()) { myResMgr = new StResourceManager(); } #ifdef ST_DEBUG_GL myGlDebug = true; #endif StSettings aGlobalSettings(myResMgr, "sview"); params.ActiveDevice = new StEnumParam(0, "Change device"); params.ActiveDevice->signals.onChanged.connect(this, &StApplication::doChangeDevice); params.VSyncMode = new StEnumParam(0, "VSync mode"); params.VSyncMode->changeValues().add("Off"); params.VSyncMode->changeValues().add("On"); params.VSyncMode->changeValues().add("Mixed"); bool isOutModeAuto = true; // AUTO by default aGlobalSettings.loadBool(ST_SETTING_RENDERER_AUTO, isOutModeAuto); if(!isOutModeAuto) { aGlobalSettings.loadString(ST_SETTING_RENDERER, myRendId); } // add additional paths #ifdef _WIN32 // requires Windows XP with SP1 or higher StStringUtfWide aStCoreFolder = StProcess::getStCoreFolder().toUtfWide(); SetDllDirectoryW(aStCoreFolder.toCString()); #endif myOpenFileInfo = theOpenInfo; if(myOpenFileInfo.isNull()) { myOpenFileInfo = parseProcessArguments(); } if(myOpenFileInfo.isNull()) { myOpenFileInfo = new StOpenInfo(); } const StArgumentsMap anArgs = myOpenFileInfo->getArgumentsMap(); const StString ARGUMENT_PLUGIN_OUT = "out"; const StString ARGUMENT_PLUGIN_OUT_DEVICE = "outDevice"; const StString ARGUMENT_GLDEBUG = "gldebug"; StArgument anArgRenderer = anArgs[ARGUMENT_PLUGIN_OUT]; StArgument anArgDevice = anArgs[ARGUMENT_PLUGIN_OUT_DEVICE]; StArgument anArgGlDebug = anArgs[ARGUMENT_GLDEBUG]; if(anArgRenderer.isValid()) { myRendId = anArgRenderer.getValue(); } //if(anArgDevice.isValid()) { // aDevice = anArgDevice.getValue(); //} if(anArgGlDebug.isValid()) { myGlDebug = true; } }
bool StFileNode::isFileExists(const StCString& thePath) { #ifdef _WIN32 StStringUtfWide aPath; aPath.fromUnicode(thePath); struct __stat64 aStatBuffer; return _wstat64(aPath.toCString(), &aStatBuffer) == 0; #elif (defined(__APPLE__)) struct stat aStatBuffer; return stat(thePath.toCString(), &aStatBuffer) == 0; #else struct stat64 aStatBuffer; return stat64(thePath.toCString(), &aStatBuffer) == 0; #endif }
bool StWinHandles::registerClass(const StStringUtfWide& theName, WNDPROC theProc) { HINSTANCE aModule = GetModuleHandleW(NULL); WNDCLASSW aClass; stMemZero(&aClass, sizeof(aClass)); // redraw on resize, and request own DC for window aClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; aClass.lpfnWndProc = theProc; aClass.cbClsExtra = 0; aClass.cbWndExtra = 0; aClass.hInstance = aModule; aClass.hIcon = LoadIconW(aModule, L"A"); aClass.hCursor = LoadCursor(NULL, IDC_ARROW); aClass.hbrBackground = NULL; aClass.lpszMenuName = NULL; aClass.lpszClassName = theName.toCString(); if(RegisterClassW(&aClass) == 0) { stError(StString("WinAPI: Failed to register window class '") + theName.toUtf8() + "'"); return false; } return true; }
bool StFolder::isFolder(const StCString& thePath) { #ifdef _WIN32 StStringUtfWide aPath; aPath.fromUnicode(thePath); DWORD aFileAttributes = GetFileAttributesW(aPath.toCString()); if(aFileAttributes == INVALID_FILE_ATTRIBUTES) { return false; } if((aFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { return true; } return false; #else DIR* aDir = opendir(thePath.toCString()); if(aDir == NULL) { return false; } closedir(aDir); return true; #endif }
StString StLibrary::DLibGetVersion(const StStringUtfWide& theLibPath) { DWORD aFVInfoSize = GetFileVersionInfoSizeW(theLibPath.toCString(), NULL); if(aFVInfoSize == 0) { return StString(); } LPVOID aBlock = stMemAlloc(aFVInfoSize); GetFileVersionInfoW(theLibPath.toCString(), NULL, aFVInfoSize, aBlock); VS_FIXEDFILEINFO* aFixedInfo; UINT aBufferSize; stUtfWide_t aPathToSubBlock[] = L"\\"; if(VerQueryValueW(aBlock, aPathToSubBlock, (LPVOID* )&aFixedInfo, &aBufferSize) == FALSE || aBufferSize < sizeof(VS_FIXEDFILEINFO)) { stMemFree(aBlock); return StString(); } StString aVersion = StString("ver.") + HIWORD(aFixedInfo->dwFileVersionMS) + '.' + LOWORD(aFixedInfo->dwFileVersionMS) + '.' + HIWORD(aFixedInfo->dwFileVersionLS) + '.' + LOWORD(aFixedInfo->dwFileVersionLS); stMemFree(aBlock); return aVersion; }
static bool wndRegisterClass(HINSTANCE theInstance, const StStringUtfWide& theClassName) { WNDCLASSW aClass; aClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; aClass.lpfnWndProc = (WNDPROC )wndProcWrapper; aClass.cbClsExtra = 0; aClass.cbWndExtra = 0; aClass.hInstance = theInstance; aClass.hIcon = LoadIconW(theInstance, L"A"); aClass.hCursor = LoadCursor(NULL, IDC_ARROW); aClass.hbrBackground = NULL; aClass.lpszMenuName = NULL; aClass.lpszClassName = theClassName.toCString(); return (RegisterClassW(&aClass) != 0); }
bool StFreeImage::load(const StString& theFilePath, ImageType theImageType, uint8_t* theDataPtr, int theDataSize) { if(!StFreeImage::init()) { setState("FreeImage library is not initialized"); return false; } // reset current data StImage::nullify(); setState(); close(); FREE_IMAGE_FORMAT aFIF = convertToFIF(theImageType); if(theDataPtr != NULL && theDataSize != 0 && aFIF != FIF_UNKNOWN) { FIMEMORY* aFIMemory = FreeImage_OpenMemory(theDataPtr, theDataSize); if(aFIMemory == NULL) { setState("FreeImage library, internal error"); return false; } myDIB = FreeImage_LoadFromMemory(aFIF, aFIMemory, 0); FreeImage_CloseMemory(aFIMemory); } else { // check the file signature and deduce its format #if defined(_WIN32) StStringUtfWide aFilePathWide = theFilePath.toUtfWide(); aFIF = FreeImage_GetFileType(aFilePathWide.toCString(), 0); #else aFIF = FreeImage_GetFileType(theFilePath.toCString(), 0); #endif if(aFIF == FIF_UNKNOWN) { // no signature? try to guess the file format from the file extension #if defined(_WIN32) aFIF = FreeImage_GetFIFFromFilename(aFilePathWide.toCString()); #else aFIF = FreeImage_GetFIFFromFilename(theFilePath.toCString()); #endif } if((aFIF == FIF_UNKNOWN) || !FreeImage_FIFSupportsReading(aFIF)) { setState("FreeImage library does not support image format"); return false; } int loadFlags = 0; if(aFIF == FIF_GIF) { // GIF_PLAYBACK - 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading loadFlags = 2; } else if(aFIF == FIF_ICO) { // ICO_MAKEALPHA - convert to 32bpp and create an alpha channel from the AND-mask when loading loadFlags = 1; } #if defined(_WIN32) myDIB = FreeImage_Load(aFIF, aFilePathWide.toCString(), loadFlags); #else myDIB = FreeImage_Load(aFIF, theFilePath.toCString(), loadFlags); #endif } if(myDIB == NULL) { setState("FreeImage library, loading file failed"); return false; } StImagePlane::ImgFormat stImgFormat = convertFromFreeFormat(FreeImage_GetImageType(myDIB), FreeImage_GetColorType(myDIB), FreeImage_GetBPP(myDIB)); if(stImgFormat == StImagePlane::ImgUNKNOWN) { setState(StString("StFreeImage, image format ") + FreeImage_GetImageType(myDIB) + ", " + FreeImage_GetColorType(myDIB) + " doesn't supported by application"); close(); return false; } setColorModelPacked(stImgFormat); changePlane(0).initWrapper(stImgFormat, FreeImage_GetBits(myDIB), FreeImage_GetWidth(myDIB), FreeImage_GetHeight(myDIB), FreeImage_GetPitch(myDIB)); // FreeImage data always bottom-up... changePlane(0).setTopDown(false); // set debug information StString aDummy, aFileName; StFileNode::getFolderAndFile(theFilePath, aDummy, aFileName); setState(StString("FreeImage library, loaded image '") + aFileName + "' " + getDescription()); // we should not close the file because we create a wrapper over FreeImage native object return true; }
bool StProcess::execProcess(const StString& theExecutablePath, const StArray<StString>& theArguments) { if(!StFileNode::isFileExists(theExecutablePath)) { return false; } #ifdef _WIN32 // convert to wide strings StStringUtfWide anExecutablePathW = theExecutablePath.toUtfWide(); StArrayList<StStringUtfWide> anArgumentsW(theArguments.size()); StStringUtfWide aSplitter = ' '; StStringUtfWide aCmdLineW = StStringUtfWide('\"') + anExecutablePathW + StStringUtfWide("\" "); for(size_t anElem = 0;;) { // TODO (Kirill Gavrilov#9) we should probably quote arguments with spaces... // how to correctly deal this in the same way for UNIX / Windows? aCmdLineW += theArguments[anElem++].toUtfWide(); if(anElem >= theArguments.size()) { break; } aCmdLineW += aSplitter; } STARTUPINFOW aStartInfo; PROCESS_INFORMATION aProcessInfo; stMemSet(&aStartInfo, 0, sizeof(aStartInfo)); aStartInfo.cb = sizeof(aStartInfo); stMemSet(&aProcessInfo, 0, sizeof(aProcessInfo)); // start the process if(!CreateProcessW(anExecutablePathW.toCString(), (wchar_t* )aCmdLineW.toCString(), NULL, NULL, FALSE, 0, NULL, NULL, &aStartInfo, &aProcessInfo)) { return false; } // close process and thread handles CloseHandle(aProcessInfo.hProcess); CloseHandle(aProcessInfo.hThread); return true; #else char** anArgList = new char*[theArguments.size() + 2]; anArgList[0] = (char* )theExecutablePath.toCString(); for(size_t anArgId = 0; anArgId < theArguments.size(); ++anArgId) { anArgList[anArgId + 1] = (char* )theArguments.getValue(anArgId).toCString(); } anArgList[theArguments.size() + 1] = NULL; pid_t aChildPid = vfork(); if(aChildPid == -1) { // fork fail delete[] anArgList; return false; } else if(aChildPid != 0) { // parent process give the control only after child // calls exit() or exec() functions delete[] anArgList; return true; } // child process execv(theExecutablePath.toCString(), anArgList); // fail _exit(1); #endif }
bool StDXManager::getInfo(StDXInfo& theInfo, const bool theForced) { if(!theForced) { if(ST_DX_HAS_CACHED_INFO) { theInfo = ST_DX_CACHED_INFO; return true; } } const StStringUtfWide AQBS_TEST_CLASS = L"StTESTAqbsWin"; HINSTANCE anAppInst = GetModuleHandle(NULL); WNDCLASSW aWinClass; aWinClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; aWinClass.lpfnWndProc = (WNDPROC )aDummyWinProc; aWinClass.cbClsExtra = 0; aWinClass.cbWndExtra = 0; aWinClass.hInstance = anAppInst; aWinClass.hIcon = LoadIcon(anAppInst, L"A"); aWinClass.hCursor = LoadCursor(NULL, IDC_ARROW); aWinClass.hbrBackground = NULL; aWinClass.lpszMenuName = NULL; aWinClass.lpszClassName = AQBS_TEST_CLASS.toCString(); // class name if(RegisterClassW(&aWinClass) == 0) { ST_DEBUG_LOG("Failed to RegisterClass '" + AQBS_TEST_CLASS.toUtf8() + "'"); return false; } HWND aWinHandle = CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE, AQBS_TEST_CLASS.toCString(), L"StTESTAqbs Window", WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 32, 32, 32, 32, NULL, NULL, anAppInst, NULL); if(aWinHandle == NULL) { ST_DEBUG_LOG("Failed to create 'StTESTAqbsWin' window (" + int(GetLastError()) + ")"); UnregisterClassW(AQBS_TEST_CLASS.toCString(), anAppInst); return false; } StHandle<StDXManager> aDXManager = new StDXManager(); // test AQBS support theInfo.hasAqbsSupport = aDXManager->checkAqbsSupport(aWinHandle); // enumerate available adapters if(aDXManager->myD3dLib != NULL) { const UINT aD3dAdaptersNb = aDXManager->getAdapterCount(); D3DADAPTER_IDENTIFIER9 anAdapterInfo; for(UINT anAdapterIter = 0; anAdapterIter < aD3dAdaptersNb; ++anAdapterIter) { aDXManager->getAdapterIdentifier(anAdapterIter, 0, &anAdapterInfo); if(anAdapterInfo.VendorId == ST_DX_VENDOR_AMD) { theInfo.hasAmdAdapter = true; } else if(anAdapterInfo.VendorId == ST_DX_VENDOR_NVIDIA) { theInfo.hasNvAdapter = true; } } } // release resources aDXManager.nullify(); DestroyWindow(aWinHandle); UnregisterClass(AQBS_TEST_CLASS.toCString(), anAppInst); // check NVIDIA Stereo enabled state if(NvAPI_Initialize() == NVAPI_OK) { NvU8 isStereoEnabled = FALSE; NvAPI_Stereo_IsEnabled(&isStereoEnabled); theInfo.hasNvStereoSupport = isStereoEnabled == TRUE; } //ST_DEBUG_LOG("DXInfo, AMD(" + int(theInfo.hasAmdAdapter) + "), AQBS(" + int(theInfo.hasAqbsSupport) // + "); NVIDIA(" + int(theInfo.hasNvAdapter) + "), NvStereo(" + int(theInfo.hasNvStereoSupport) + ")"); // cache the state to avoid unnecessary calls ST_DX_CACHED_INFO = theInfo; ST_DX_HAS_CACHED_INFO = true; return true; }
/** * Create/open key for writing. */ bool create(const StStringUtfWide& thePath) { return RegCreateKeyExW(HKEY_CURRENT_USER, thePath.toCString(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &Key, NULL) == ERROR_SUCCESS; }
/** * Open (read-only) existing key. Will fail if key does not exists. */ bool open(const StStringUtfWide& thePath) { return RegOpenKeyExW(HKEY_CURRENT_USER, thePath.toCString(), 0, KEY_READ, &Key) == ERROR_SUCCESS; }
bool StQuadBufferCheck::testQuadBufferSupport() { #ifdef ST_HAVE_EGL return false; // unsupported at all! #elif defined(_WIN32) HINSTANCE anAppInst = GetModuleHandleW(NULL); // Holds The Instance Of The Application const StStringUtfWide QUAD_TEST_CLASS = L"StTESTQuadBufferWin"; if(!wndRegisterClass(anAppInst, QUAD_TEST_CLASS)) { ST_DEBUG_LOG_AT("Fail to register class"); return false; } HWND aWindow = CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE, QUAD_TEST_CLASS.toCString(), L"GL Quad Buffer test", WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED, 32, 32, 32, 32, NULL, NULL, anAppInst, NULL); if(aWindow == NULL) { UnregisterClassW(QUAD_TEST_CLASS.toCString(), anAppInst); return false; } HDC aDevCtx = GetDC(aWindow); if(aDevCtx == NULL) { // Did We Get A Device Context? ST_DEBUG_LOG_AT(L"WinAPI, Can't create Device Context for the entire screen"); DestroyWindow(aWindow); UnregisterClassW(QUAD_TEST_CLASS.toCString(), anAppInst); return false; } PIXELFORMATDESCRIPTOR aPixelFormat; memset(&aPixelFormat, 0, sizeof(PIXELFORMATDESCRIPTOR)); // zero out all fields aPixelFormat.nSize = sizeof(PIXELFORMATDESCRIPTOR); aPixelFormat.nVersion = 1; aPixelFormat.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_STEREO; const int aPixelFormatId = ChoosePixelFormat(aDevCtx, &aPixelFormat); DescribePixelFormat(aDevCtx, aPixelFormatId, sizeof(PIXELFORMATDESCRIPTOR), &aPixelFormat); // clean up if(ReleaseDC(aWindow, aDevCtx) == 0) { ST_DEBUG_LOG_AT(L"WinAPI, ReleaseDC(aWindow, aDevCtx) FAILED"); } DestroyWindow(aWindow); UnregisterClassW(QUAD_TEST_CLASS.toCString(), anAppInst); return (aPixelFormat.dwFlags & PFD_STEREO) != 0; #elif defined(__linux__) Display* hDisplay = XOpenDisplay(NULL); // get first display on server from DISPLAY in env if(hDisplay == NULL) { ST_DEBUG_LOG_AT("X: could not open display"); return false; } // make sure OpenGL's GLX extension supported int dummy = 0; if(!glXQueryExtension(hDisplay, &dummy, &dummy)) { ST_DEBUG_LOG_AT("X: server has no OpenGL GLX extension"); return false; } static int quadBuff[] = { GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, GLX_STEREO, None }; // find an appropriate visual XVisualInfo* vi = glXChooseVisual(hDisplay, DefaultScreen(hDisplay), quadBuff); return vi != NULL; #endif }