diff --git a/CMakeModules/nel.cmake b/CMakeModules/nel.cmake index ea1642eb8..39b7d6c14 100644 --- a/CMakeModules/nel.cmake +++ b/CMakeModules/nel.cmake @@ -249,6 +249,8 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS) OPTION(WITH_ASSIMP "Use assimp exporter" OFF) OPTION(WITH_LIBGSF "Use libgsf for max file library" OFF) + OPTION(WITH_FFMPEG "Use ffmpeg for audio decoder" OFF) + ### # GUI toolkits ### diff --git a/nel/CMakeLists.txt b/nel/CMakeLists.txt index 1530e75e3..b102310ab 100644 --- a/nel/CMakeLists.txt +++ b/nel/CMakeLists.txt @@ -20,7 +20,9 @@ ENDIF() IF(WITH_SOUND) FIND_PACKAGE(Ogg) FIND_PACKAGE(Vorbis) - FIND_PACKAGE(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWRESAMPLE) + IF(WITH_FFMPEG) + FIND_PACKAGE(FFmpeg REQUIRED COMPONENTS AVCODEC AVFORMAT AVUTIL SWRESAMPLE) + ENDIF() IF(WITH_DRIVER_OPENAL) FIND_PACKAGE(OpenAL) diff --git a/nel/src/3d/driver/opengl/driver_opengl.h b/nel/src/3d/driver/opengl/driver_opengl.h index 4941a98d1..ec9b59345 100644 --- a/nel/src/3d/driver/opengl/driver_opengl.h +++ b/nel/src/3d/driver/opengl/driver_opengl.h @@ -999,6 +999,9 @@ private: bool createWindow(const GfxMode& mode); bool destroyWindow(); + // Return monitor info and positon in multi monitor setup or false if monitor not found. + bool getMonitorByName(const std::string &name, sint32 &x, sint32 &y, uint32 &w, uint32 &h) const; + enum EWindowStyle { EWSWindowed, EWSFullscreen }; void setWindowSize(uint32 width, uint32 height); diff --git a/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 06f95c38c..35dc433a8 100644 --- a/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -650,8 +650,6 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re _win = EmptyWindow; - _CurrentMode = mode; - _WindowVisible = false; _Resizable = resizeable; _DestroyWindow = false; @@ -1194,6 +1192,8 @@ bool CDriverGL::saveScreenMode() #ifdef HAVE_XRANDR + // TODO: if using mode switching, save current xrandr mode to _OldSizeID + res = true; if (!res && _xrandr_version > 0) { XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen)); @@ -1254,6 +1254,8 @@ bool CDriverGL::restoreScreenMode() #ifdef HAVE_XRANDR + // TODO: if using mode switching, then restore mode from _OldSizeID + res = true; if (!res && _xrandr_version > 0) { Window root = RootWindow(_dpy, screen); @@ -1348,7 +1350,8 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) && mode.Width == previousMode.Width && mode.Height == previousMode.Height && mode.Depth == previousMode.Depth - && mode.Frequency == previousMode.Frequency) + && mode.Frequency == previousMode.Frequency + && mode.DisplayDevice == previousMode.DisplayDevice) return true; #if defined(NL_OS_WINDOWS) @@ -1388,6 +1391,8 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) bool found = false; #ifdef HAVE_XRANDR + // TODO: implement mode switching using xrandr crts + found = true; if (!found && _xrandr_version > 0) { @@ -1911,8 +1916,92 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) return true; } +bool CDriverGL::getMonitorByName(const std::string &name, sint32 &x, sint32 &y, uint32 &w, uint32 &h) const +{ + bool found = false; + +#if HAVE_XRANDR + int screen = DefaultScreen(_dpy); + + // xrandr 1.5+ + if (_xrandr_version >= 105) + { + int nmonitors = 0; + XRRMonitorInfo *monitor = XRRGetMonitors(_dpy, RootWindow(_dpy, screen), 1, &nmonitors); + if (!monitor) + return false; + + for(sint i = 0; i< nmonitors; ++i) + { + char* pname = XGetAtomName(_dpy, monitor[i].name); + found = (nlstricmp(pname, name) == 0); + XFree(pname); + + if (found) + { + x = monitor[i].x; + y = monitor[i].y; + w = monitor[i].width; + h = monitor[i].height; + + break; + } + } + + XRRFreeMonitors(monitor); + } + else + { + XRRScreenResources *resources = XRRGetScreenResourcesCurrent(_dpy, RootWindow(_dpy, screen)); + if (!resources) + resources = XRRGetScreenResources(_dpy, RootWindow(_dpy, screen)); + + for(uint i = 0; i < resources->noutput; ++i) + { + XRROutputInfo *output = XRRGetOutputInfo(_dpy, resources, resources->outputs[i]); + if (!output) + continue; + + if (output->crtc && output->connection == RR_Connected && nlstricmp(name, output->name) == 0) + { + // physical monitor + XRRCrtcInfo *crtc = XRRGetCrtcInfo(_dpy, resources, output->crtc); + if (crtc) + { + found = true; + x = crtc->x; + y = crtc->y; + + // TODO: test rotation + if (crtc->rotation == RR_Rotate_0 || crtc->rotation == RR_Rotate_180) + { + w = crtc->width; + h = crtc->height; + } + else + { + w = crtc->height; + h = crtc->width; + } + + XRRFreeCrtcInfo(crtc); + } + } + + XRRFreeOutputInfo(output); + + if (found) + break; + } + + XRRFreeScreenResources(resources); + } +#endif + return found; +} + // -------------------------------------------------- -bool CDriverGL::setMode(const GfxMode& mode) +bool CDriverGL::setMode(const GfxMode& amode) { H_AUTO_OGL(CDriverGL_setMode); @@ -1920,6 +2009,10 @@ bool CDriverGL::setMode(const GfxMode& mode) if (!_DestroyWindow) return true; +#if !(HAVE_XRANDR) + const GfxMode &mode = amode; +#endif + #if defined(NL_OS_WINDOWS) // save relative cursor POINT cursorPos; @@ -1929,21 +2022,89 @@ bool CDriverGL::setMode(const GfxMode& mode) BOOL cursorPosOk = isSystemCursorInClientArea() && GetCursorPos(&cursorPos) && ScreenToClient(_win, &cursorPos); + + // FIXME: this probably needs to use _CurrentMode instead of mode sint curX = (sint)cursorPos.x * (sint)mode.Width; sint curY = (sint)cursorPos.y * (sint)mode.Height; #endif +#if HAVE_XRANDR + GfxMode mode = amode; + + if (!mode.Windowed) + { + GfxMode current; + if (!getCurrentScreenMode(current)) + nlinfo("3D: XrandR: Reading active monitor info failed"); + + sint newX = _WindowX; + sint newY = _WindowY; + + // make sure resolution matches requested or currently active monitor's resolution + mode.Width = current.Width; + mode.Height = current.Height; + if (!mode.DisplayDevice.empty()) + { + uint newW = current.Width; + uint newH = current.Height; + if (getMonitorByName(mode.DisplayDevice, newX, newY, newW, newH)) + { + mode.Width = newW; + mode.Height = newH; + } + else + { + nlinfo("3D: XrandR: Reading requested monitor '%s' info failed, using '%s'", mode.DisplayDevice.c_str(), current.DisplayDevice.c_str()); + mode.DisplayDevice = current.DisplayDevice; + } + } + + // switching monitors. + // first move mouse pointer to target monitor and then move window. + // if window is visible, then also restore mouse relative position. + if (!mode.DisplayDevice.empty() && mode.DisplayDevice != current.DisplayDevice) + { + int screen = DefaultScreen(_dpy); + Window root = RootWindow(_dpy, screen); + uint mouseX = mode.Width / 2; + uint mouseY = mode.Height / 2; + + XWindowAttributes xwa; + XGetWindowAttributes(_dpy, _win, &xwa); + if (xwa.map_state != IsUnmapped) + { + Window root_win; + Window child_win; + sint root_x, root_y, win_x, win_y; + uint mask; + + Bool res = XQueryPointer(_dpy, _win, &root_win, &child_win, &root_x, &root_y, &win_x, &win_y, &mask); + if (res) + { + mouseX = (uint)((float)win_x * mode.Width / current.Width); + mouseY = (uint)((float)win_y * mode.Height / current.Height); + } + } + + XWarpPointer(_dpy, None, root, None, None, None, None, newX + mouseX, newY + mouseY); + XMoveWindow(_dpy, _win, newX, newY); + _WindowX = newX; + _WindowY = newY; + } + } +#endif + if (!setScreenMode(mode)) return false; + _CurrentMode.Depth = mode.Depth; + _CurrentMode.Frequency = mode.Frequency; + _CurrentMode.DisplayDevice = mode.DisplayDevice; + // when changing window style, it's possible system change window size too setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen); - - if (!mode.Windowed) - _CurrentMode.Depth = mode.Depth; - - setWindowSize(mode.Width, mode.Height); setWindowPos(_WindowX, _WindowY); + setWindowSize(mode.Width, mode.Height); switch (_CurrentMode.Depth) { @@ -2120,6 +2281,66 @@ bool CDriverGL::getModes(std::vector &modes) int screen = DefaultScreen(_dpy); #if defined(HAVE_XRANDR) + if (_xrandr_version >= 105) + { + int nmonitors = 0; + // virtual monitors + XRRMonitorInfo *monitor = XRRGetMonitors(_dpy, RootWindow(_dpy, screen), 1, &nmonitors); + for(sint i = 0; i < nmonitors; ++i) + { + char * name = XGetAtomName(_dpy, monitor[i].name); + GfxMode mode; + mode.DisplayDevice = name; + mode.Width = monitor[i].width; + mode.Height = monitor[i].height; + mode.Frequency = 0; + modes.push_back(mode); + XFree(name); + } + XRRFreeMonitors(monitor); + } + else + { + XRRScreenResources *resources = XRRGetScreenResourcesCurrent(_dpy, RootWindow(_dpy, screen)); + if (!resources) + resources = XRRGetScreenResources(_dpy, RootWindow(_dpy, screen)); + + std::map resourceModeMap; + for(sint i = 0; i< resources->nmode; ++i) + resourceModeMap.insert(std::make_pair(resources->modes[i].id, i)); + + for(sint i = 0; i < resources->noutput; ++i) + { + XRROutputInfo *output = XRRGetOutputInfo(_dpy, resources, resources->outputs[i]); + if (!output) + continue; + + if (output->crtc && output->connection == RR_Connected) + { + // physical monitor + XRRCrtcInfo *crtc = XRRGetCrtcInfo(_dpy, resources, output->crtc); + if (crtc) + { + std::map::const_iterator it = resourceModeMap.find(crtc->mode); + if (it != resourceModeMap.end()) + { + GfxMode mode; + mode.DisplayDevice = output->name; + mode.Width = resources->modes[it->second].width; + mode.Height = resources->modes[it->second].height; + mode.Frequency = 0; + + modes.push_back(mode); + } + XRRFreeCrtcInfo(crtc); + } + } + XRRFreeOutputInfo(output); + } + + XRRFreeScreenResources(resources); + } + found = modes.size() > 0; if (!found && _xrandr_version >= 100) { XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen)); @@ -2255,6 +2476,120 @@ bool CDriverGL::getCurrentScreenMode(GfxMode &mode) int screen = DefaultScreen(_dpy); #ifdef HAVE_XRANDR + int x = 0; + int y = 0; + Window child; + + // get window position so we can compare monitors (or mouse position if window not visible yet) + XWindowAttributes xwa; + XGetWindowAttributes(_dpy, _win, &xwa); + if (xwa.map_state != IsUnmapped) + { + XTranslateCoordinates(_dpy, _win, xwa.root, xwa.x, xwa.y, &x, &y, &child); + } + else + { + sint rx, ry, wx, wy; + uint mask; + Bool res = XQueryPointer(_dpy, RootWindow(_dpy, screen), &child, &child, &rx, &ry, &wx, &wy, &mask); + if (res) + { + x = rx; + y = ry; + } + } + + if (_xrandr_version >= 105) + { + int nmonitors = 0; + XRRMonitorInfo *monitor = XRRGetMonitors(_dpy, RootWindow(_dpy, screen), 1, &nmonitors); + if (monitor) + { + sint bestMatch = -1; + for(sint i = 0; i< nmonitors; ++i) + { + if ((x >= monitor[i].x && x < (monitor[i].x + monitor[i].width) && + y >= monitor[i].y && y < (monitor[i].y + monitor[i].height)) || + (monitor[i].primary && bestMatch == -1)) + { + bestMatch = i; + } + } + + // best match or primary monitor + if (bestMatch != -1) + { + found = true; + char* pname = XGetAtomName(_dpy, monitor[bestMatch].name); + mode.DisplayDevice = pname; + mode.Width = monitor[bestMatch].width; + mode.Height = monitor[bestMatch].height; + mode.Windowed = _CurrentMode.Windowed; + mode.OffScreen = false; + mode.Depth = (uint) DefaultDepth(_dpy, screen); + mode.Frequency = 0; + XFree(pname); + } + + XRRFreeMonitors(monitor); + } + } + else + { + XRRScreenResources *resources = XRRGetScreenResourcesCurrent(_dpy, RootWindow(_dpy, screen)); + if (!resources) + resources = XRRGetScreenResources(_dpy, RootWindow(_dpy, screen)); + + for(uint i = 0; i < resources->noutput; ++i) + { + XRROutputInfo *output = XRRGetOutputInfo(_dpy, resources, resources->outputs[i]); + if (!output) + continue; + + if (output->crtc && output->connection == RR_Connected) + { + XRRCrtcInfo *crtc = XRRGetCrtcInfo(_dpy, resources, output->crtc); + if (crtc) + { + sint width, height; + bool match = false; + + // TODO: test rotation + if (crtc->rotation == RR_Rotate_0 || crtc->rotation == RR_Rotate_180) + { + width = crtc->width; + height = crtc->height; + } + else + { + width = crtc->height; + height = crtc->width; + } + + if (x >= crtc->x && y >= crtc->y && x < (crtc->x + width) && y < (crtc->y + height)) + { + found = true; + mode.DisplayDevice = output->name; + mode.Width = width; + mode.Height = height; + mode.Windowed = _CurrentMode.Windowed; + mode.OffScreen = false; + mode.Depth = (uint) DefaultDepth(_dpy, screen); + mode.Frequency = 0; + } + + XRRFreeCrtcInfo(crtc); + } + } + + XRRFreeOutputInfo(output); + + if (found) + break; + } + + XRRFreeScreenResources(resources); + } if (!found && _xrandr_version > 0) { @@ -2432,7 +2767,6 @@ void CDriverGL::setWindowPos(sint32 x, sint32 y) _DecorationWidth = -1; _DecorationHeight = -1; } - XMoveWindow(_dpy, _win, x, y); } diff --git a/nel/src/3d/driver_user.cpp b/nel/src/3d/driver_user.cpp index a7bd7a332..757d2183f 100644 --- a/nel/src/3d/driver_user.cpp +++ b/nel/src/3d/driver_user.cpp @@ -331,6 +331,7 @@ bool CDriverUser::getCurrentScreenMode(CMode &mode) GfxMode gfxMode; bool res= _Driver->getCurrentScreenMode(gfxMode); mode.Windowed= gfxMode.Windowed; + mode.DisplayDevice= gfxMode.DisplayDevice; mode.Width= gfxMode.Width; mode.Height= gfxMode.Height; mode.Depth= gfxMode.Depth; diff --git a/nel/src/web/curl_certificates.cpp b/nel/src/web/curl_certificates.cpp index b1017d643..52f04fe25 100644 --- a/nel/src/web/curl_certificates.cpp +++ b/nel/src/web/curl_certificates.cpp @@ -131,15 +131,6 @@ namespace NLWEB // only use OpenSSL callback if not using Windows SSPI and using OpenSSL backend if (useOpenSSLBackend && !(data && data->features & CURL_VERSION_SSPI)) { -#ifdef NL_OS_WINDOWS - // load native Windows CA Certs - /* - addCertificatesFrom("CA"); - addCertificatesFrom("AuthRoot"); - addCertificatesFrom("ROOT"); - */ -#endif - isUsingOpenSSLBackend = true; } else @@ -181,40 +172,6 @@ namespace NLWEB return name; } -#ifdef NL_OS_WINDOWS - void addCertificatesFrom(LPCSTR root) - { - HCERTSTORE hStore; - PCCERT_CONTEXT pContext = NULL; - X509 *x509; - hStore = CertOpenSystemStore(NULL, root); - if (hStore) - { - while (pContext = CertEnumCertificatesInStore(hStore, pContext)) - { - x509 = NULL; - x509 = d2i_X509(NULL, (const unsigned char **)&pContext->pbCertEncoded, pContext->cbCertEncoded); - - if (x509) - { - CertEntry entry; - entry.cert = x509; - entry.file = root; - entry.name = getCertName(x509); - - CertList.push_back(entry); - } - } - - CertFreeCertificateContext(pContext); - CertCloseStore(hStore, 0); - } - - // this is called before debug context is set and log ends up in log.log - //nlinfo("Loaded %d certificates from '%s' certificate store", (int)CertList.size(), root); - } -#endif - void addCertificatesFromFile(const std::string &cert) { if (!isInitialized) diff --git a/ryzom/client/src/client_cfg.cpp b/ryzom/client/src/client_cfg.cpp index 0b6df6a43..629752aec 100644 --- a/ryzom/client/src/client_cfg.cpp +++ b/ryzom/client/src/client_cfg.cpp @@ -302,6 +302,7 @@ CClientConfig::CClientConfig() SelectedSlot = 0; // Default is slot 0 Windowed = false; // Default is windowed mode. + MonitorName = ""; Width = 0; // Default Width for the window (0 = current screen resolution). Height = 0; // Default Height for the window (0 = current screen resolution). Depth = 32; // Default Bit per Pixel. @@ -847,6 +848,8 @@ void CClientConfig::setValues() } else cfgWarning("Default value used for 'Fullscreen'"); + + READ_STRING_FV(MonitorName); // Width READ_INT_FV(Width) // Height @@ -1938,6 +1941,11 @@ void CClientConfig::serial(NLMISC::IStream &f) f.serial(Light); f.xmlPop(); + f.xmlPushBegin("MonitorName"); + f.xmlPushEnd(); + f.serial(MonitorName); + f.xmlPop(); + f.xmlPushBegin("Windowed"); f.xmlPushEnd(); f.serial(Windowed); diff --git a/ryzom/client/src/client_cfg.h b/ryzom/client/src/client_cfg.h index f03cf7152..43ab25437 100644 --- a/ryzom/client/src/client_cfg.h +++ b/ryzom/client/src/client_cfg.h @@ -137,6 +137,8 @@ struct CClientConfig TDriver3D Driver3D; /// Application start in a window or in fullscreen. bool Windowed; + /// Monitor to use for fullscreen + std::string MonitorName; /// Width for the Application. uint16 Width; /// Height for the Application. diff --git a/ryzom/client/src/connection.cpp b/ryzom/client/src/connection.cpp index 7d3c58e53..4aee3c32f 100644 --- a/ryzom/client/src/connection.cpp +++ b/ryzom/client/src/connection.cpp @@ -195,38 +195,9 @@ bool hasPrivilegeEG() { return (UserPrivileges.find(":EG:") != std::string::npos // Restore the video mode (fullscreen for example) after the connection (done in a window) void connectionRestoreVideoMode () { - // Setup full screen if we have to - UDriver::CMode mode; - Driver->getCurrentScreenMode(mode); - - if (mode.Windowed) - { - uint32 width, height; - Driver->getWindowSize(width, height); - mode.Width = width; - mode.Height = height; - } - - // don't allow sizes smaller than 1024x768 - if (ClientCfg.Width < 1024) ClientCfg.Width = 1024; - if (ClientCfg.Height < 768) ClientCfg.Height = 768; - if (StereoDisplay) StereoDisplayAttached = StereoDisplay->attachToDisplay(); - if (!StereoDisplayAttached && ( - (ClientCfg.Windowed != mode.Windowed) || - (ClientCfg.Width != mode.Width) || - (ClientCfg.Height != mode.Height))) - { - mode.Windowed = ClientCfg.Windowed; - mode.Depth = uint8(ClientCfg.Depth); - mode.Width = ClientCfg.Width; - mode.Height = ClientCfg.Height; - mode.Frequency = ClientCfg.Frequency; - setVideoMode(mode); - } - // And setup hardware mouse if we have to InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); SetMouseFreeLook (); @@ -1288,19 +1259,7 @@ TInterfaceState globalMenu() // Restore video mode if (ClientCfg.SelectCharacter == -1) - { - if (ClientCfg.Windowed) - { - // if used changed window resolution in char select - // if we don't update ClientCfg, then UI from icfg is restored wrong - uint32 width, height; - Driver->getWindowSize(width, height); - ClientCfg.Width = width; - ClientCfg.Height = height; - } - connectionRestoreVideoMode (); - } // Skip intro next time ClientCfg.writeBool("SkipIntro", true); diff --git a/ryzom/client/src/init.cpp b/ryzom/client/src/init.cpp index 458e78be2..479642873 100644 --- a/ryzom/client/src/init.cpp +++ b/ryzom/client/src/init.cpp @@ -1063,43 +1063,48 @@ void prelogInit() return; } - // used to determine screen default resolution - if (ClientCfg.Width < 800 || ClientCfg.Height < 600) + UDriver::CMode mode; + // first run (no client.cfg) + if (ClientCfg.Width == 0 || ClientCfg.Height == 0) { - UDriver::CMode mode; - - CConfigFile::CVar *varPtr = NULL; - - if (!ClientCfg.Windowed && Driver->getCurrentScreenMode(mode)) + if (Driver->getCurrentScreenMode(mode)) { + // fullscreen, using monitor resolution + mode.Windowed = false; + + ClientCfg.MonitorName = mode.DisplayDevice; + ClientCfg.Windowed = mode.Windowed; ClientCfg.Width = mode.Width; ClientCfg.Height = mode.Height; ClientCfg.Depth = mode.Depth; ClientCfg.Frequency = mode.Frequency; - - // update client.cfg with detected depth and frequency - varPtr = ClientCfg.ConfigFile.getVarPtr("Depth"); - if(varPtr) - varPtr->forceAsInt(ClientCfg.Depth); - - varPtr = ClientCfg.ConfigFile.getVarPtr("Frequency"); - if(varPtr) - varPtr->forceAsInt(ClientCfg.Frequency); } else { + // fallback + ClientCfg.Windowed = true; ClientCfg.Width = 1024; ClientCfg.Height = 768; } // update client.cfg with detected resolution - varPtr = ClientCfg.ConfigFile.getVarPtr("Width"); - if(varPtr) - varPtr->forceAsInt(ClientCfg.Width); - - varPtr = ClientCfg.ConfigFile.getVarPtr("Height"); - if(varPtr) - varPtr->forceAsInt(ClientCfg.Height); + ClientCfg.writeBool("FullScreen", !ClientCfg.Windowed, true); + ClientCfg.writeString("MonitorName", ClientCfg.MonitorName, true); + ClientCfg.writeInt("Width", ClientCfg.Width, true); + ClientCfg.writeInt("Height", ClientCfg.Height, true); + ClientCfg.writeInt("Depth", ClientCfg.Depth, true); + ClientCfg.writeInt("Frequency", ClientCfg.Frequency, true); + + ClientCfg.ConfigFile.save(); + } + else + { + mode.DisplayDevice = ClientCfg.MonitorName; + mode.Windowed = ClientCfg.Windowed; + mode.Width = ClientCfg.Width; + mode.Height = ClientCfg.Height; + mode.Depth = ClientCfg.Depth; + mode.Frequency = ClientCfg.Frequency; } CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetup, "login_step_video_mode_setup")); @@ -1109,25 +1114,6 @@ void prelogInit() // Check the driver is not is 16 bits checkDriverDepth (); - UDriver::CMode mode; - - if (Driver->getCurrentScreenMode(mode)) - { - // use current mode if its smaller than 1024x768 - // mode should be windowed already, but incase its not, use the mode as is - if (mode.Windowed && (mode.Width > 1024 && mode.Height > 768)) - { - mode.Width = 1024; - mode.Height = 768; - } - } - else - { - mode.Width = 1024; - mode.Height = 768; - mode.Windowed = true; - } - // Disable Hardware Vertex Program. if(ClientCfg.DisableVtxProgram) Driver->disableHardwareVertexProgram(); @@ -1262,10 +1248,11 @@ void prelogInit() else { // position is not saved in config so center the window - if (Driver->getCurrentScreenMode(mode)) + UDriver::CMode tmp; + if (Driver->getCurrentScreenMode(tmp)) { - posX = (mode.Width - Driver->getWindowWidth())/2; - posY = (mode.Height - Driver->getWindowHeight())/2; + posX = (tmp.Width - Driver->getWindowWidth())/2; + posY = (tmp.Height - Driver->getWindowHeight())/2; } } diff --git a/ryzom/client/src/interface_v3/action_handler_game.cpp b/ryzom/client/src/interface_v3/action_handler_game.cpp index 8c9153ca4..75c9ef0e3 100644 --- a/ryzom/client/src/interface_v3/action_handler_game.cpp +++ b/ryzom/client/src/interface_v3/action_handler_game.cpp @@ -3455,6 +3455,7 @@ class CHandlerGameConfigApply : public IActionHandler { // Get W, H sint w = 1024, h = 768; + string name; { CDBGroupComboBox *pCB = dynamic_cast(CWidgetManager::getInstance()->getElementFromId( GAME_CONFIG_VIDEO_MODES_COMBO )); if( pCB != NULL ) @@ -3464,6 +3465,11 @@ class CHandlerGameConfigApply : public IActionHandler fromString(tmp, w); tmp = vidModeStr.substr(vidModeStr.find('x')+2,vidModeStr.size()); fromString(tmp, h); + + // extract monitor "1024x768 (VGA-1)" + string::size_type pos = vidModeStr.find('('); + if (pos != std::string::npos) + name = vidModeStr.substr(pos + 1, vidModeStr.find(")") - pos - 1); } } @@ -3506,6 +3512,7 @@ class CHandlerGameConfigApply : public IActionHandler ClientCfg.Width = w; ClientCfg.Height = h; + ClientCfg.MonitorName = name; // Write the modified client.cfg ClientCfg.writeBool("FullScreen", bFullscreen); @@ -3514,6 +3521,7 @@ class CHandlerGameConfigApply : public IActionHandler if (bFullscreen) { + ClientCfg.writeString("MonitorName", name, true); ClientCfg.writeInt("Depth", screenMode.Depth); ClientCfg.writeInt("Frequency", freq); } diff --git a/ryzom/client/src/interface_v3/interface_manager.cpp b/ryzom/client/src/interface_v3/interface_manager.cpp index 945d8a793..bbd431160 100644 --- a/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/ryzom/client/src/interface_v3/interface_manager.cpp @@ -1907,9 +1907,12 @@ bool CInterfaceManager::loadConfig (const string &filename) // NB: we are typically InGame here (even though the _InGame flag is not yet set) // Use the screen size of the config file. Don't update current UI, just _Modes // - // ClientCfg has W/H set to screen size, but interface expects scaled size - sint32 scaledW = ClientCfg.Width / ClientCfg.InterfaceScale; - sint32 scaledH = ClientCfg.Height / ClientCfg.InterfaceScale; + uint32 width, height; + // get non-scaled width/height + Driver->getWindowSize(width, height); + // convert to scaled width/height for ui + sint32 scaledW = width / ClientCfg.InterfaceScale; + sint32 scaledH = height / ClientCfg.InterfaceScale; CWidgetManager::getInstance()->moveAllWindowsToNewScreenSize(scaledW, scaledH, false); updateDesktops(scaledW, scaledH); } diff --git a/ryzom/client/src/login.cpp b/ryzom/client/src/login.cpp index 7b0377890..da038cdd2 100644 --- a/ryzom/client/src/login.cpp +++ b/ryzom/client/src/login.cpp @@ -2208,6 +2208,7 @@ class CAHLessLod : public IActionHandler REGISTER_ACTION_HANDLER (CAHLessLod, "less_lod"); // *************************************************************************** +// TODO: remove resolution change from login screen class CAHUninitResLod : public IActionHandler { virtual void execute (CCtrlBase * /* pCaller */, const string &/* sParams */) diff --git a/ryzom/client/src/main_loop_utilities.cpp b/ryzom/client/src/main_loop_utilities.cpp index d93e24481..95dcf82c8 100644 --- a/ryzom/client/src/main_loop_utilities.cpp +++ b/ryzom/client/src/main_loop_utilities.cpp @@ -76,7 +76,7 @@ void updateFromClientCfg() // set latest config display mode if not attached if (!StereoDisplayAttached) setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, - ClientCfg.Windowed, ClientCfg.Frequency)); + ClientCfg.Windowed, ClientCfg.Frequency, -1, ClientCfg.MonitorName)); // force software cursor when attached InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached); } @@ -87,12 +87,13 @@ void updateFromClientCfg() (ClientCfg.Width != LastClientCfg.Width) || (ClientCfg.Height != LastClientCfg.Height) || (ClientCfg.Depth != LastClientCfg.Depth) || - (ClientCfg.Frequency != LastClientCfg.Frequency)) + (ClientCfg.Frequency != LastClientCfg.Frequency)|| + (ClientCfg.MonitorName != LastClientCfg.MonitorName)) { if (!StereoDisplayAttached) { setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, - ClientCfg.Windowed, ClientCfg.Frequency)); + ClientCfg.Windowed, ClientCfg.Frequency, -1, ClientCfg.MonitorName)); } } diff --git a/ryzom/client/src/misc.cpp b/ryzom/client/src/misc.cpp index 2653c0e45..7cbeeebc2 100644 --- a/ryzom/client/src/misc.cpp +++ b/ryzom/client/src/misc.cpp @@ -1408,6 +1408,7 @@ bool getRyzomModes(std::vector &videoModes, std::vectorgetModes(videoModes); + // TODO: for resolutions below 1024x768, could use automatic UI scaling like in login/outgame // Remove modes under 1024x768 (outgame ui limitation) and get the unique strings sint i, j; for (i = 0; i < (sint)videoModes.size(); ++i) @@ -1424,6 +1425,9 @@ bool getRyzomModes(std::vector &videoModes, std::vector