diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index a9c91b319..538382e5f 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -188,7 +188,7 @@ ENDIF(BUILD_DOCUMENTATION) IF(WITH_NEL_TESTS) ENABLE_TESTING() - ADD_TEST(nel_unit_test ${EXECUTABLE_OUTPUT_PATH}/nel_unit_test --html) + ADD_TEST(nel_unit_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nel_unit_test --html) IF(BUILD_DASHBOARD) INCLUDE(Dart) SET(SVNCOMMAND svn) diff --git a/code/CMakeModules/FindLibwww.cmake b/code/CMakeModules/FindLibwww.cmake index 9239b8e42..52c52f38e 100644 --- a/code/CMakeModules/FindLibwww.cmake +++ b/code/CMakeModules/FindLibwww.cmake @@ -70,7 +70,7 @@ MACRO(FIND_WWW_LIBRARY MYLIBRARY OPTION) ENDIF(NOT LIBWWW_FIND_QUIETLY) ENDIF(${MYLIBRARY}) - MARK_AS_ADVANCED(${MYLIBRARY}) + MARK_AS_ADVANCED(${MYLIBRARY}) ENDMACRO(FIND_WWW_LIBRARY) MACRO(LINK_WWW_LIBRARY MYLIBRARY OTHERLIBRARY SYMBOL) @@ -120,13 +120,14 @@ FIND_WWW_LIBRARY(LIBREGEX_LIBRARY OPTIONAL gnu_regex) # Now link all libs together LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWCACHE_LIBRARY HTLoadCache) +LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWCACHE_LIBRARY HTCacheAppend) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWFTP_LIBRARY HTLoadFTP) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWGOPHER_LIBRARY HTLoadGopher) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWNEWS_LIBRARY HTLoadNews) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWTELNET_LIBRARY HTLoadTelnet) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWSTREAM_LIBRARY HTStreamToChunk) -LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWDIR_LIBRARY HTIcon_addDir) +LINK_WWW_LIBRARY(LIBWWWFILE_LIBRARY LIBWWWDIR_LIBRARY HTDir_new) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWINIT_LIBRARY HTProtocolInit) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWXML_LIBRARY HTXML_new) LINK_WWW_LIBRARY(LIBWWWAPP_LIBRARY LIBWWWZIP_LIBRARY HTZLib_inflate) diff --git a/code/nel/CMakeLists.txt b/code/nel/CMakeLists.txt index 001b50601..bff4ab359 100644 --- a/code/nel/CMakeLists.txt +++ b/code/nel/CMakeLists.txt @@ -58,8 +58,8 @@ ENDIF(WITH_GTK) IF(UNIX) SET(prefix ${CMAKE_INSTALL_PREFIX}) SET(exec_prefix ${CMAKE_INSTALL_PREFIX}/bin) - SET(libdir "${CMAKE_INSTALL_PREFIX}/lib") - SET(includedir "${CMAKE_INSTALL_PREFIX}/include") + SET(libdir ${CMAKE_INSTALL_PREFIX}/lib) + SET(includedir ${CMAKE_INSTALL_PREFIX}/include) SET(enable_ligo ${WITH_LIGO}) SET(enable_logic ${WITH_LOGIC}) SET(enable_georges ${WITH_GEORGES}) @@ -67,7 +67,7 @@ IF(UNIX) SET(enable_3d ${WITH_3D}) SET(enable_pacs ${WITH_PACS}) SET(enable_sound ${WITH_SOUND}) - CONFIGURE_FILE(nel-config.in nel-config) + CONFIGURE_FILE(nel-config.in ${CMAKE_CURRENT_BINARY_DIR}/nel-config) INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/nel-config DESTINATION bin) ENDIF(UNIX) diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h index 04553c2ab..d5460b362 100644 --- a/code/nel/include/nel/misc/common.h +++ b/code/nel/include/nel/misc/common.h @@ -48,6 +48,8 @@ typedef HWND nlWindow; #define EmptyWindow NULL #elif defined(NL_OS_MAC) + // TODO This should be NSView*, but then we would need to include Cocoa.h + // and compile with "-x objective-c++" ... everything including this file. typedef void* nlWindow; #define EmptyWindow NULL #elif defined(NL_OS_UNIX) diff --git a/code/nel/include/nel/misc/i18n.h b/code/nel/include/nel/misc/i18n.h index c3972c088..6778efcc6 100644 --- a/code/nel/include/nel/misc/i18n.h +++ b/code/nel/include/nel/misc/i18n.h @@ -218,10 +218,10 @@ private: // the alternative language that will be used if the sentence is not found in the original language static StrMapContainer _StrMapFallback; - static const std::string _LanguageCodes[]; - static const uint _NbLanguages; + static std::vector _LanguageCodes; + static std::vector _LanguageNames; - static bool _LanguagesNamesLoaded; + static bool _LanguagesNamesLoaded; static std::string _SelectedLanguageCode; static const ucstring _NotTranslatedValue; diff --git a/code/nel/include/nel/misc/mutex.h b/code/nel/include/nel/misc/mutex.h index 009840e3b..e93929ba9 100644 --- a/code/nel/include/nel/misc/mutex.h +++ b/code/nel/include/nel/misc/mutex.h @@ -22,17 +22,19 @@ #include "common.h" #include -#ifdef NL_OS_UNIX -//#include -#include // PThread -#include // PThread POSIX semaphores -#include -#define __forceinline -#elif defined(NL_OS_WINDOWS) +#ifdef NL_OS_WINDOWS # ifdef NL_NO_ASM # include # endif -#endif +#elif defined(NL_OS_UNIX) +# include // PThread +# include // PThread POSIX semaphores +# include +# define __forceinline +# ifdef NL_OS_MAC +# include +# endif +#endif // NL_OS_WINDOWS #undef MUTEX_DEBUG @@ -119,38 +121,38 @@ private: // Tested: works on multi-processor #ifdef HAVE_X86_64 # define ASM_ASWAP_FOR_GCC_XCHG __asm__ volatile( \ - "mov %1, %%rcx;" \ - "mov $1, %%eax;" \ - "xchg %%eax, (%%rcx);" \ - "mov %%eax, %0" \ - : "=m" (result) \ - : "m" (lockPtr) \ - : "eax", "rcx", "memory" ); // force to use registers and memory + "mov %1, %%rcx;" \ + "mov $1, %%eax;" \ + "xchg %%eax, (%%rcx);" \ + "mov %%eax, %0" \ + : "=m" (result) \ + : "m" (lockPtr) \ + : "eax", "rcx", "memory" ); // force to use registers and memory #else # define ASM_ASWAP_FOR_GCC_XCHG __asm__ volatile( \ - "mov %1, %%ecx;" \ - "mov $1, %%eax;" \ - "xchg %%eax, (%%ecx);" \ - "mov %%eax, %0" \ - : "=m" (result) \ - : "m" (lockPtr) \ - : "eax", "ecx", "memory" ); // force to use registers and memory + "mov %1, %%ecx;" \ + "mov $1, %%eax;" \ + "xchg %%eax, (%%ecx);" \ + "mov %%eax, %0" \ + : "=m" (result) \ + : "m" (lockPtr) \ + : "eax", "ecx", "memory" ); // force to use registers and memory #endif */ /* // Tested: does not work (at least on multi-processor)! (with or without 'lock' prefix) #define ASM_ASWAP_FOR_GCC_CMPXCHG __asm__ volatile( \ - "mov $1, %%edx;" \ - "mov %1, %%ecx;" \ - "mov (%%ecx), %%eax;" \ - "1:nop;" \ - "lock cmpxchgl %%edx, (%%ecx);" \ - "jne 1b;" \ - "mov %%eax, %0" \ - : "=m" (result) \ - : "m" (lockPtr) \ - : "eax", "ecx", "edx", "memory" ); // force to use registers and memory + "mov $1, %%edx;" \ + "mov %1, %%ecx;" \ + "mov (%%ecx), %%eax;" \ + "1:nop;" \ + "lock cmpxchgl %%edx, (%%ecx);" \ + "jne 1b;" \ + "mov %%eax, %0" \ + : "=m" (result) \ + : "m" (lockPtr) \ + : "eax", "ecx", "edx", "memory" ); // force to use registers and memory */ // Tested: does not work on hyper-threading processors! @@ -204,6 +206,7 @@ test_again: #ifdef NL_OS_WINDOWS #pragma managed(push, off) #endif + class CFastMutex { public: @@ -245,12 +248,18 @@ public: } # endif // NL_DEBUG # endif // NL_NO_ASM -#else - // GCC implements the same functionality using a builtin function - // http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html - // the macro below crashed on Mac OS X 10.6 in a 64bit build - //ASM_ASWAP_FOR_GCC_XCHG - result = __sync_bool_compare_and_swap(lockPtr, 0, 1); +#elif defined(NL_OS_MAC) + return OSAtomicCompareAndSwap32(0, 1, reinterpret_cast(lockPtr)); +#elif defined(NL_OS_UNIX) + // GCC implements the same functionality using a builtin function + // http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html + // the macro below crashed on Mac OS X 10.6 in a 64bit build +# if (GCC_VERSION > 40100) + // return __sync_bool_compare_and_swap(lockPtr, 0, 1); + result = __sync_val_compare_and_swap(lockPtr, 0, 1); +# else + ASM_ASWAP_FOR_GCC_XCHG +# endif #endif // NL_OS_WINDOWS return result != 0; } @@ -557,7 +566,7 @@ struct TMutexLocks uint32 TimeInMutex; // cumulated time between enter and leave uint32 Nb; // number of calls of enter uint32 WaitingMutex; // number of thread that waiting this mutex - sint32 MutexNum; // identifying a mutex + sint32 MutexNum; // identifying a mutex uint ThreadHavingTheMutex; // thread id of the thread that is in this mutex (0xFFFFFFFF if no thread) bool Dead; // True if the mutex is dead (deleted) std::string MutexName; // Name of the mutex diff --git a/code/nel/include/nel/sound/audio_mixer_user.h b/code/nel/include/nel/sound/audio_mixer_user.h index be5dfb356..7cd0de051 100644 --- a/code/nel/include/nel/sound/audio_mixer_user.h +++ b/code/nel/include/nel/sound/audio_mixer_user.h @@ -148,7 +148,7 @@ public: * for the HighestPri source. * By default, reserve are set for each channel to the number of available tracks. */ - virtual void setPriorityReserve(TSoundPriority priorityChannel, size_t reserve); + virtual void setPriorityReserve(TSoundPriority priorityChannel, uint reserve); /** Set the Low water mark. * This value is use to mute sound source that try to play when there priority * channel is full (see setPriorityReserve). @@ -161,7 +161,7 @@ public: * available tracks (witch is almos alwais the case). But this value will help * the mixer make it's best. */ - virtual void setLowWaterMark(size_t value); + virtual void setLowWaterMark(uint value); virtual void changeMaxTrack(uint maxTrack); diff --git a/code/nel/include/nel/sound/u_audio_mixer.h b/code/nel/include/nel/sound/u_audio_mixer.h index ad3f1ab03..e1c2a274e 100644 --- a/code/nel/include/nel/sound/u_audio_mixer.h +++ b/code/nel/include/nel/sound/u_audio_mixer.h @@ -229,7 +229,7 @@ public: * for the HighestPri source. * By default, reserve are set for each channel to the number of available tracks. */ - virtual void setPriorityReserve(TSoundPriority priorityChannel, size_t reserve) = 0; + virtual void setPriorityReserve(TSoundPriority priorityChannel, uint reserve) = 0; /** Set the Low water mark. * This value is use to mute sound source that try to play when their priority * channel is full (see setPriorityReserve). @@ -242,7 +242,7 @@ public: * available tracks (which is almost always the case). But this value will help * the mixer make its best. */ - virtual void setLowWaterMark(size_t value) = 0; + virtual void setLowWaterMark(uint value) = 0; /** Change the number of tracks in RealTime. If the number is lowered, random tracks are deleted. * Any playing sources of such deleted track will be stopped */ diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp index 4bb65d436..445b52451 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp @@ -2964,7 +2964,7 @@ pixelshader water_diffuse_2_0 = asm \n\ //bias result (include scaling) \n\ mad r0.xy, r0, c1.z, c1; \n\ //add envmap coord \n\ - add r0.xy, r0, t2; \n\ + add r0.xy, r0, t2; \n\ // read envmap \n\ texld r0, r0, s2; \n\ // read diffuse \n\ @@ -3073,7 +3073,7 @@ pixelshader water_no_diffuse_2_0 = asm \n\ //bias result (include scaling) \n\ mad r0.xy, r0, c1.z, c1; \n\ //add envmap coord \n\ - add r0.xy, r0, t2; \n\ + add r0.xy, r0, t2; \n\ //read envmap \n\ texld r0, r0, s2; \n\ mov oC0, r0; \n\ diff --git a/code/nel/src/3d/driver/opengl/CMakeLists.txt b/code/nel/src/3d/driver/opengl/CMakeLists.txt index ea1a0ab31..d4643f465 100644 --- a/code/nel/src/3d/driver/opengl/CMakeLists.txt +++ b/code/nel/src/3d/driver/opengl/CMakeLists.txt @@ -2,6 +2,8 @@ FILE(GLOB SRC *.cpp *.h *.def) IF(APPLE) FILE(GLOB MAC_SRC mac/*.h mac/*.m mac/*.mm mac/*.cpp) SET(SRC ${SRC} ${MAC_SRC}) + SET_SOURCE_FILES_PROPERTIES(${SRC} + PROPERTIES COMPILE_FLAGS "-x objective-c++") ENDIF(APPLE) IF(WIN32) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index f0d816f50..5ab7c7475 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -29,10 +29,6 @@ # include # include #elif defined(NL_OS_MAC) -# define GL_GLEXT_LEGACY -# include -# include "mac/glext.h" -# include "mac/cocoa_adapter.h" #elif defined (NL_OS_UNIX) # include # include @@ -189,8 +185,24 @@ CDriverGL::CDriverGL() #elif defined(NL_OS_MAC) - NL3D::MAC::ctor(); + _ctx = nil; + _glView = nil; + _backBufferHeight = 0; + _backBufferWidth = 0; + + // autorelease pool for memory management + _autoreleasePool = [[NSAutoreleasePool alloc] init]; + + // init the application object + [NSApplication sharedApplication]; + + // create the menu in the top screen bar + setupApplicationMenu(); + + // finish the application launching + [NSApp finishLaunching]; + #elif defined (NL_OS_UNIX) _cursor = None; @@ -329,9 +341,9 @@ CDriverGL::~CDriverGL() { H_AUTO_OGL(CDriverGL_CDriverGLDtor) release(); - + #if defined(NL_OS_MAC) - NL3D::MAC::dtor(); + [_autoreleasePool release]; #endif } @@ -860,7 +872,12 @@ bool CDriverGL::swapBuffers() #elif defined(NL_OS_MAC) - NL3D::MAC::swapBuffers(_win); + // TODO: maybe do this somewhere else? + [_autoreleasePool release]; + _autoreleasePool = [[NSAutoreleasePool alloc] init]; + + [_ctx flushBuffer]; + [containerView() display]; #elif defined (NL_OS_UNIX) @@ -2213,102 +2230,102 @@ void CDriverGL::retrieveATIDriverVersion() H_AUTO_OGL(CDriverGL_retrieveATIDriverVersion) _ATIDriverVersion = 0; // we may need this driver version to fix flaws of previous ati drivers version (fog issue with V.P) - #ifdef NL_OS_WINDOWS - // get from the registry - HKEY parentKey; - // open key about current video card - LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ, &parentKey); - if (result == ERROR_SUCCESS) +#ifdef NL_OS_WINDOWS + // get from the registry + HKEY parentKey; + // open key about current video card + LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ, &parentKey); + if (result == ERROR_SUCCESS) + { + // find last config + DWORD keyIndex = 0; + uint latestConfigVersion = 0; + char subKeyName[256]; + char latestSubKeyName[256] = ""; + DWORD nameBufferSize = sizeof(subKeyName) / sizeof(subKeyName[0]); + FILETIME lastWriteTime; + bool configFound = false; + for(;;) { - // find last config - DWORD keyIndex = 0; - uint latestConfigVersion = 0; - char subKeyName[256]; - char latestSubKeyName[256] = ""; - DWORD nameBufferSize = sizeof(subKeyName) / sizeof(subKeyName[0]); - FILETIME lastWriteTime; - bool configFound = false; - for(;;) + nameBufferSize = sizeof(subKeyName) / sizeof(subKeyName[0]); + result = RegEnumKeyEx(parentKey, keyIndex, subKeyName, &nameBufferSize, NULL, NULL, NULL, &lastWriteTime); + if (result == ERROR_NO_MORE_ITEMS) break; + if (result == ERROR_SUCCESS) { - nameBufferSize = sizeof(subKeyName) / sizeof(subKeyName[0]); - result = RegEnumKeyEx(parentKey, keyIndex, subKeyName, &nameBufferSize, NULL, NULL, NULL, &lastWriteTime); - if (result == ERROR_NO_MORE_ITEMS) break; - if (result == ERROR_SUCCESS) + // see if the name is numerical. + bool isNumerical = true; + for(uint k = 0; k < nameBufferSize; ++k) { - // see if the name is numerical. - bool isNumerical = true; - for(uint k = 0; k < nameBufferSize; ++k) + if (!isdigit(subKeyName[k])) { - if (!isdigit(subKeyName[k])) - { - isNumerical = false; - break; - } + isNumerical = false; + break; } - if (isNumerical) - { - uint configVersion; - fromString((const char*)subKeyName, configVersion); - if (configVersion >= latestConfigVersion) - { - configFound = true; - latestConfigVersion = configVersion; - strcpy(latestSubKeyName, subKeyName); - } - } - ++ keyIndex; } - else + if (isNumerical) { - RegCloseKey(parentKey); - return; + uint configVersion; + fromString((const char*)subKeyName, configVersion); + if (configVersion >= latestConfigVersion) + { + configFound = true; + latestConfigVersion = configVersion; + strcpy(latestSubKeyName, subKeyName); + } } + ++ keyIndex; } - if (configFound) + else { - HKEY subKey; - result = RegOpenKeyEx(parentKey, latestSubKeyName, 0, KEY_READ, &subKey); - if (result == ERROR_SUCCESS) + RegCloseKey(parentKey); + return; + } + } + if (configFound) + { + HKEY subKey; + result = RegOpenKeyEx(parentKey, latestSubKeyName, 0, KEY_READ, &subKey); + if (result == ERROR_SUCCESS) + { + // see if it is a radeon card + DWORD valueType; + char driverDesc[256]; + DWORD driverDescBufSize = sizeof(driverDesc) / sizeof(driverDesc[0]); + result = RegQueryValueEx(subKey, "DriverDesc", NULL, &valueType, (unsigned char *) driverDesc, &driverDescBufSize); + if (result == ERROR_SUCCESS && valueType == REG_SZ) { - // see if it is a radeon card - DWORD valueType; - char driverDesc[256]; - DWORD driverDescBufSize = sizeof(driverDesc) / sizeof(driverDesc[0]); - result = RegQueryValueEx(subKey, "DriverDesc", NULL, &valueType, (unsigned char *) driverDesc, &driverDescBufSize); - if (result == ERROR_SUCCESS && valueType == REG_SZ) + toLower(driverDesc); + if (strstr(driverDesc, "radeon")) // is it a radeon card ? { - toLower(driverDesc); - if (strstr(driverDesc, "radeon")) // is it a radeon card ? + char driverVersion[256]; + DWORD driverVersionBufSize = sizeof(driverVersion) / sizeof(driverVersion[0]); + result = RegQueryValueEx(subKey, "DriverVersion", NULL, &valueType, (unsigned char *) driverVersion, &driverVersionBufSize); + if (result == ERROR_SUCCESS && valueType == REG_SZ) { - char driverVersion[256]; - DWORD driverVersionBufSize = sizeof(driverVersion) / sizeof(driverVersion[0]); - result = RegQueryValueEx(subKey, "DriverVersion", NULL, &valueType, (unsigned char *) driverVersion, &driverVersionBufSize); - if (result == ERROR_SUCCESS && valueType == REG_SZ) + int subVersionNumber[4]; + if (sscanf(driverVersion, "%d.%d.%d.%d", &subVersionNumber[0], &subVersionNumber[1], &subVersionNumber[2], &subVersionNumber[3]) == 4) { - int subVersionNumber[4]; - if (sscanf(driverVersion, "%d.%d.%d.%d", &subVersionNumber[0], &subVersionNumber[1], &subVersionNumber[2], &subVersionNumber[3]) == 4) + _ATIDriverVersion = (uint) subVersionNumber[3]; + /** see if fog range for V.P is bad in that driver version (is so, do a fix during vertex program conversion to EXT_vertex_shader + * In earlier versions of the driver, fog coordinates had to be output in the [0, 1] range + * From the 6.14.10.6343 driver, fog output must be in world units + */ + if (_ATIDriverVersion < 6343) { - _ATIDriverVersion = (uint) subVersionNumber[3]; - /** see if fog range for V.P is bad in that driver version (is so, do a fix during vertex program conversion to EXT_vertex_shader - * In earlier versions of the driver, fog coordinates had to be output in the [0, 1] range - * From the 6.14.10.6343 driver, fog output must be in world units - */ - if (_ATIDriverVersion < 6343) - { - _ATIFogRangeFixed = false; - } + _ATIFogRangeFixed = false; } } } } } - RegCloseKey(subKey); } - RegCloseKey(parentKey); + RegCloseKey(subKey); } + RegCloseKey(parentKey); + } #elif defined(NL_OS_MAC) -# warning "OpenGL Driver: Missing Mac Implementation" - nlwarning("OpenGL Driver: Missing Mac Implementation"); +# warning "OpenGL Driver: Missing Mac Implementation for ATI version retrieval" + nlwarning("OpenGL Driver: Missing Mac Implementation for ATI version retrieval"); #elif defined (NL_OS_UNIX) // TODO for Linux: implement retrieveATIDriverVersion... assuming versions under linux are probably different diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 6410ca65b..cf4f93a22 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -32,8 +32,11 @@ # include # include #elif defined(NL_OS_MAC) -# define GL_GLEXT_LEGACY +# define GL_GLEXT_LEGACY +# import # include +# include "mac/glext.h" +# import "mac/cocoa_opengl_view.h" #elif defined (NL_OS_UNIX) # define GLX_GLXEXT_PROTOTYPES # include @@ -700,7 +703,15 @@ private: #elif defined(NL_OS_MAC) - NLMISC::CCocoaEventEmitter _EventEmitter; + NLMISC::CCocoaEventEmitter _EventEmitter; + NSOpenGLContext* _ctx; + NSOpenGLView* _glView; + NSAutoreleasePool* _autoreleasePool; + uint16 _backBufferHeight; + uint16 _backBufferWidth; + + NSView* containerView() { return (NSView*)_win; } + void setupApplicationMenu(); #elif defined (NL_OS_UNIX) @@ -1388,11 +1399,6 @@ public: CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it); }; -#ifdef NL_OS_MAC - // Specific mac functions - extern bool getMacModes(std::vector &modes); -#endif - } // NL3D #endif // NL_DRIVER_OPENGL_H diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 2aed89013..f82fbe746 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -25,10 +25,6 @@ #ifdef NL_OS_WINDOWS # include #elif defined(NL_OS_MAC) -# define GL_GLEXT_LEGACY -# include -# include "mac/glext.h" -# include "mac/cocoa_adapter.h" #elif defined (NL_OS_UNIX) # include # include @@ -298,11 +294,7 @@ bool CDriverGL::init (uint windowIcon, emptyProc exitFunc) retrieveATIDriverVersion(); #elif defined(NL_OS_MAC) - if(!NL3D::MAC::init(windowIcon, exitFunc)) - { - nldebug("cannot init"); - return false; - } + // nothing to do #elif defined (NL_OS_UNIX) @@ -393,11 +385,7 @@ bool CDriverGL::unInit() #elif defined(NL_OS_MAC) - if(!NL3D::MAC::unInit()) - { - nldebug("cannot uninit"); - return false; - } + // nothing to do #elif defined (NL_OS_UNIX) @@ -478,7 +466,7 @@ void CDriverGL::setWindowIcon(const std::vector &bitmaps) #elif defined(NL_OS_MAC) - // nothing to do + // nothing to do, on Mac OS X, only windows representing a file have icons #elif defined(NL_OS_UNIX) @@ -901,10 +889,67 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re #elif defined(NL_OS_MAC) - _win = NL3D::MAC::setDisplay(wnd, mode, show, resizeable); + if (wnd == EmptyWindow) + { + if (!createWindow(mode)) + return false; + } + else + { + _win = wnd; + } - if(_win != EmptyWindow) - _DestroyWindow = true; + // setup opengl settings + NSOpenGLPixelFormatAttribute att[] = + { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAColorSize, 24, + NSOpenGLPFADepthSize, 24, + NSOpenGLPFAAlphaSize, 8, + NSOpenGLPFAStencilSize, 8, + NSOpenGLPFANoRecovery, + NSOpenGLPFAAccelerated, + NSOpenGLPFABackingStore, + 0 + }; + + // put the settings into a format object + NSOpenGLPixelFormat* format = + [[NSOpenGLPixelFormat alloc] initWithAttributes:att]; + + if(!format) + nlerror("cannot create NSOpenGLPixelFormat"); + + // create a opengl view with the created format + _glView = [[CocoaOpenGLView alloc] + initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat: format]; + + if(!_glView) + nlerror("cannot create view"); + + // make the view automatically fit the super view + [_glView setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; + + // put the open gl view into the dummy view contained in the window + [containerView() addSubview:_glView]; + + // adjust size + [_glView setFrame: [containerView() frame]]; + + // create a opengl context for the view + _ctx = [_glView openGLContext]; + + if(!_ctx) + nlerror("cannot create context"); + + // free the pixel format object + [format release]; + + // let the open gl view handle the input + [[containerView() window] makeFirstResponder:_glView]; + + [_ctx flushBuffer]; + [containerView() display]; #elif defined(NL_OS_UNIX) @@ -1145,7 +1190,8 @@ bool CDriverGL::restoreScreenMode() return res; } -// -------------------------------------------------- +// *************************************************************************** + #ifdef XF86VIDMODE static sint modeInfoToFrequency(XF86VidModeModeInfo *info) { @@ -1153,7 +1199,8 @@ static sint modeInfoToFrequency(XF86VidModeModeInfo *info) } #endif // XF86VIDMODE -// -------------------------------------------------- +// *************************************************************************** + bool CDriverGL::setScreenMode(const GfxMode &mode) { H_AUTO_OGL(CDriverGL_setScreenMode) @@ -1324,11 +1371,45 @@ bool CDriverGL::createWindow(const GfxMode &mode) #elif defined(NL_OS_MAC) - window = NL3D::MAC::createWindow(mode); + // describe how the window should look like and behave + unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask | NSResizableWindowMask; + + // create a cocoa window with the size provided by the mode parameter + NSWindow* cocoa_window = [[NSWindow alloc] + initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height) + styleMask:styleMask backing:NSBackingStoreBuffered defer:NO]; + + if(!cocoa_window) + { + nlerror("cannot create cocoa window"); + return false; + } + + // set the window to non transparent + [cocoa_window setOpaque:YES]; + + // enable mouse move events, NeL wants them + [cocoa_window setAcceptsMouseMovedEvents:YES]; + + // there are no overlapping subviews, can use the magical optimization :) + [cocoa_window useOptimizedDrawing:YES]; + + // put the window to the front and make it the key window + [cocoa_window makeKeyAndOrderFront:nil]; + + // this is our main window + [cocoa_window makeMainWindow]; + + // create a dummy view which works like the window on other platforms + // the open gl view will be created as subview of this one. + window = [[NSView alloc] init]; + + [cocoa_window setContentView: (NSView*)window]; if(window == EmptyWindow) { - nldebug("cannot create window"); + nldebug("cannot create cocoa view for cocoa window"); return false; } @@ -1368,6 +1449,7 @@ bool CDriverGL::createWindow(const GfxMode &mode) } // *************************************************************************** + bool CDriverGL::destroyWindow() { H_AUTO_OGL(CDriverGL_destroyWindow) @@ -1404,12 +1486,11 @@ bool CDriverGL::destroyWindow() if(_DestroyWindow) { - if(!NL3D::MAC::destroyWindow(_win)) - { - nldebug("cannot destroy window"); - return false; - } + [containerView() release]; + [[containerView() window] release]; } + + _ctx = nil; #elif defined (NL_OS_UNIX) @@ -1436,6 +1517,8 @@ bool CDriverGL::destroyWindow() return true; } +// *************************************************************************** + CDriverGL::EWindowStyle CDriverGL::getWindowStyle() const { H_AUTO_OGL(CDriverGL_getWindowStyle) @@ -1446,6 +1529,8 @@ CDriverGL::EWindowStyle CDriverGL::getWindowStyle() const return EWSWindowed; } +// *************************************************************************** + bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) { H_AUTO_OGL(CDriverGL_setWindowStyle) @@ -1500,10 +1585,57 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) #elif defined(NL_OS_MAC) - if(!NL3D::MAC::setWindowStyle(_win, windowStyle == EWSFullscreen)) + // leave fullscreen mode, enter windowed mode + if(windowStyle == EWSWindowed && [containerView() isInFullScreenMode]) { - nldebug("cannot set window style"); - return false; + // disable manual setting of back buffer size, cocoa handles this + // automatically as soon as the view gets resized + CGLError error = CGLDisable((CGLContextObj)[_ctx CGLContextObj], + kCGLCESurfaceBackingSize); + + if(error != kCGLNoError) + nlerror("cannot disable kCGLCESurfaceBackingSize (%s)", + CGLErrorString(error)); + + // pull the view back from fullscreen restoring window options + [containerView() exitFullScreenModeWithOptions:nil]; + + // let the gl view receive key events + [[containerView() window] makeFirstResponder:_glView]; + + // bring the window containing the gl view to the front + [[containerView() window] makeKeyAndOrderFront:nil]; + } + + // enter fullscreen, leave windowed mode + else if(windowStyle == EWSFullscreen && ![containerView() isInFullScreenMode]) + { + // enable manual back buffer size for mode setting in fullscreen + CGLError error = CGLEnable((CGLContextObj)[_ctx CGLContextObj], + kCGLCESurfaceBackingSize); + + if(error != kCGLNoError) + nlerror("cannot enable kCGLCESurfaceBackingSize (%s)", + CGLErrorString(error)); + + // put the view in fullscreen mode, hiding the dock but enabling the menubar + // to pop up if the mouse hits the top screen border. + // NOTE: withOptions:nil disables + application switching! +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + [containerView() enterFullScreenMode:[NSScreen mainScreen] withOptions: + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInt: + NSApplicationPresentationHideDock | + NSApplicationPresentationAutoHideMenuBar], + NSFullScreenModeApplicationPresentationOptions, nil]]; +#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + /* + TODO check if simply using NSView enterFullScreenMode is a good idea. + the context can be set to full screen as well, performance differences? + */ + + // let the gl view receive key events + [[containerView() window] makeFirstResponder:_glView]; } #elif defined(NL_OS_UNIX) @@ -1558,6 +1690,8 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) #endif // NL_OS_WINDOWS + _FullScreen = (windowStyle == EWSFullscreen); + return true; } @@ -1570,19 +1704,54 @@ bool CDriverGL::setMode(const GfxMode& mode) return false; // when changing window style, it's possible system change window size too - setWindowStyle(mode.Windowed ? EWSWindowed:EWSFullscreen); + setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen); if (!mode.Windowed) _Depth = mode.Depth; - _FullScreen = !mode.Windowed; - setWindowSize(mode.Width, mode.Height); setWindowPos(_WindowX, _WindowY); return true; } +#if defined(NL_OS_MAC) && defined(AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER) + +/// helper to extract bits per pixel value from screen mode, only 16 or 32 bits +static int bppFromDisplayMode(CGDisplayModeRef mode) +{ + CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode); + + if(CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels), + kCFCompareCaseInsensitive) == kCFCompareEqualTo) + return 32; + + else if(CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels), + kCFCompareCaseInsensitive) == kCFCompareEqualTo) + return 16; + + return 0; +} + +#elif defined(NL_OS_MAC) && !defined(AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER) + +long GetDictionaryLong(CFDictionaryRef theDict, const void* key) +{ + long value = 0; + CFNumberRef numRef; + numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key); + if (numRef != NULL) + CFNumberGetValue(numRef, kCFNumberLongType, &value); + return value; +} + +// some macros to make code more readable. +#define GetModeWidth(mode) GetDictionaryLong((mode), kCGDisplayWidth) +#define GetModeHeight(mode) GetDictionaryLong((mode), kCGDisplayHeight) +#define GetModeBitsPerPixel(mode) GetDictionaryLong((mode), kCGDisplayBitsPerPixel) + +#endif // defined(NL_OS_MAC) + // -------------------------------------------------- bool CDriverGL::getModes(std::vector &modes) { @@ -1611,7 +1780,71 @@ bool CDriverGL::getModes(std::vector &modes) #elif defined(NL_OS_MAC) - NL3D::MAC::getModes(modes); + static const CGDisplayCount kMaxDisplays = 16; + CGDirectDisplayID display[kMaxDisplays]; + CGDisplayCount numDisplays; + + CGDisplayErr err = CGGetActiveDisplayList(kMaxDisplays, display, &numDisplays); + if(err != CGDisplayNoErr) + { + nlwarning("Cannot get displays (%d)", err); + return false; + } + + // nldebug("3D: %d displays found", (int)numDisplays); + + for (CGDisplayCount i = 0; i < numDisplays; ++i) + { + CGDirectDisplayID dspy = display[i]; + +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + CFArrayRef modeList = CGDisplayCopyAllDisplayModes(dspy, NULL); +#else + CFArrayRef modeList = CGDisplayAvailableModes(dspy); +#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + + if (modeList == NULL) + { + nlwarning("Display is invalid"); + continue; + } + + for (CFIndex j = 0; j < CFArrayGetCount(modeList); ++j) + { +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modeList, j); + uint8 bpp = bppFromDisplayMode(mode); +#else + CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex(modeList, j); + uint8 bpp = (uint8)GetModeBitsPerPixel(mode); +#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + + if (bpp >= 16) + { +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + uint16 w = CGDisplayModeGetWidth(mode); + uint16 h = CGDisplayModeGetHeight(mode); +#else + uint16 w = (uint16)GetModeWidth(mode); + uint16 h = (uint16)GetModeHeight(mode); +#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + + // Add this mode + GfxMode mode; + mode.Width = w; + mode.Height = h; + mode.Depth = bpp; + + // Frequency stays at 0 because on mac cocoa, display resolution + // is never really changed. if rendering res < display res, + // cocoa interpolates and keeps the display at it's original res. + mode.Frequency = 0; + modes.push_back (mode); + + // nldebug(" Display 0x%x: Mode %dx%d, %d BPP", dspy, w, h, bpp); + } + } + } #elif defined (NL_OS_UNIX) @@ -1722,7 +1955,30 @@ bool CDriverGL::getCurrentScreenMode(GfxMode &mode) #elif defined(NL_OS_MAC) - NL3D::MAC::getCurrentScreenMode(_win, mode); + // the sceen with the menu bar + NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + + mode.OffScreen = false; + mode.Frequency = 0; + mode.Depth = NSBitsPerPixelFromDepth([screen depth]); + + // in fullscreen mode + if([containerView() isInFullScreenMode]) + { + // return the size of the back buffer (like having switched monitor mode) + mode.Windowed = false; + mode.Width = _backBufferWidth; + mode.Height = _backBufferHeight; + } + + // in windowed mode + else + { + // return the size of the screen with menu bar + mode.Windowed = true; + mode.Width = (uint16)[screen frame].size.width; + mode.Height = (uint16)[screen frame].size.height; + } #elif defined(NL_OS_UNIX) @@ -1830,7 +2086,8 @@ void CDriverGL::setWindowTitle(const ucstring &title) #elif defined(NL_OS_MAC) - NL3D::MAC::setWindowTitle(_win, title); + [[containerView() window] setTitle: + [NSString stringWithUTF8String:title.toUtf8().c_str()]]; #elif defined (NL_OS_UNIX) @@ -1862,7 +2119,19 @@ void CDriverGL::setWindowPos(sint32 x, sint32 y) #elif defined(NL_OS_MAC) - NL3D::MAC::setWindowPos(_win, x, y); + nldebug("setting window pos to %d %d", x, y); + + // get the rect (position, size) of the screen with menu bar + NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; + + // get the rect (position, size) of the window + NSRect windowRect = [[containerView() window] frame]; + + // convert y from NeL coordinates to cocoa coordinates + y = screenRect.size.height - y; + + // tell cocoa to move the window + [[containerView() window] setFrameTopLeftPoint:NSMakePoint(x, y)]; #elif defined (NL_OS_UNIX) @@ -1895,7 +2164,7 @@ void CDriverGL::showWindow(bool show) #elif defined(NL_OS_MAC) - MAC::showWindow(show); + // TODO implement me #elif defined (NL_OS_UNIX) @@ -1940,11 +2209,8 @@ bool CDriverGL::activate() #elif defined(NL_OS_MAC) - if(!MAC::activate(_win)) - { - nlwarning("cannot activate"); - return false; - } + if([NSOpenGLContext currentContext] != _ctx) + [_ctx makeCurrentContext]; #elif defined (NL_OS_UNIX) @@ -2024,7 +2290,28 @@ void CDriverGL::showCursor(bool b) #elif defined(NL_OS_MAC) - NL3D::MAC::showCursor(b); + // Mac OS manages a show/hide counter for the cursor, so hiding the cursor + // twice requires two calls to "show" to make the cursor visible again. + // Since other platforms seem to not do this, the functionality is masked here + // by only calling hide if the cursor is visible and only calling show if + // the cursor was hidden. + + CGDisplayErr error = kCGErrorSuccess; + static bool visible = true; + + if(b && !visible) + { + error = CGDisplayShowCursor(kCGDirectMainDisplay); + visible = true; + } + else if(!b && visible) + { + error = CGDisplayHideCursor(kCGDirectMainDisplay); + visible = false; + } + + if(error != kCGErrorSuccess) + nlerror("cannot show / hide cursor"); #elif defined (NL_OS_UNIX) @@ -2077,7 +2364,30 @@ void CDriverGL::setMousePos(float x, float y) #elif defined(NL_OS_MAC) - NL3D::MAC::setMousePos(_win, x, y); + // CG wants absolute coordinates related to first screen's top left + + // get the first screen's (conaints menubar) rect (this is not mainScreen) + NSRect firstScreenRect = [[[NSScreen screens] objectAtIndex:0] frame]; + + // get the rect (position, size) of the window + NSRect windowRect; + if([containerView() isInFullScreenMode]) + windowRect = [[[containerView() window] screen] frame]; + else + windowRect = [[containerView() window] frame]; + + // get the view's rect for height and width + NSRect viewRect = [containerView() frame]; + + // set the cursor position + CGDisplayErr error = CGDisplayMoveCursorToPoint( + kCGDirectMainDisplay, CGPointMake( + windowRect.origin.x + (viewRect.size.width * x), + firstScreenRect.size.height - windowRect.origin.y - + viewRect.size.height + ((1.0 - y) * viewRect.size.height))); + + if(error != kCGErrorSuccess) + nlerror("cannot set mouse position"); #elif defined (NL_OS_UNIX) @@ -2092,7 +2402,32 @@ void CDriverGL::getWindowSize(uint32 &width, uint32 &height) #ifdef NL_OS_MAC - NL3D::MAC::getWindowSize(_win, width, height); + // TODO set them in windowproc, so no special impl is needed here + + // A cocoa fullscreen view stays at the native resolution of the display. + // When changing the rendering resolution, the size of the back buffer gets + // changed, but the view still stays at full resolution. So the scaling of + // the image from the rendered resolution to the view's resolution is done + // by cocoa automatically while flushing buffers. + // That's why, in fullscreen mode, return the resolution of the back buffer, + // not the one from the window. + + // in fullscreen mode + if([containerView() isInFullScreenMode]) + { + // use the size stored in setWindowSize() + width = _backBufferWidth; + height = _backBufferHeight; + } + + // in windowed mode + else + { + // use the size of the view + NSRect rect = [containerView() frame]; + width = rect.size.width; + height = rect.size.height; + } #else // NL_OS_MAC @@ -2146,8 +2481,44 @@ void CDriverGL::setWindowSize(uint32 width, uint32 height) #elif defined(NL_OS_MAC) - NL3D::MAC::setWindowSize(_win, width, height); + // for fullscreen mode, adjust the back buffer size to the desired resolution + if([containerView() isInFullScreenMode]) + { + // disable and re-enable fullscreen + // fixes #1062 (http://dev.ryzom.com/issues/1062) + setWindowStyle(EWSWindowed); + setWindowStyle(EWSFullscreen); + + // set the back buffer manually to match the desired rendering resolution + GLint dim[2] = { width, height }; + CGLError error = CGLSetParameter( + (CGLContextObj)[_ctx CGLContextObj], + kCGLCPSurfaceBackingSize, dim); + if(error != kCGLNoError) + nlerror("cannot set kCGLCPSurfaceBackingSize parameter (%s)", + CGLErrorString(error)); + + _backBufferWidth = width; + _backBufferHeight = height; + } + else + { + // only change the window size if the driver created the window itself + if(_DestroyWindow) + { + // get the windows current frame + NSRect rect = [[containerView() window] frame]; + + // convert the desired content size to window size + rect = [[containerView() window] frameRectForContentRect: + NSMakeRect(rect.origin.x, rect.origin.y, width, height)]; + + // update window dimensions + [[containerView() window] setFrame:rect display:YES]; + } + } + #elif defined(NL_OS_UNIX) if (width != _WindowWidth || height != _WindowHeight) @@ -2182,8 +2553,19 @@ void CDriverGL::getWindowPos(sint32 &x, sint32 &y) H_AUTO_OGL(CDriverGL_getWindowPos) #ifdef NL_OS_MAC + // TODO set them in window proc so no special impl is needed here - NL3D::MAC::getWindowPos(_win, x, y); + // get the rect (position, size) of the screen with menu bar + NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; + + // get the rect (position, size) of the window + NSRect windowRect = [[containerView() window] frame]; + + // simply return x + x = windowRect.origin.x; + + // map y from cocoa to NeL coordinates before returning + y = screenRect.size.height - windowRect.size.height - windowRect.origin.y; #else // NL_OS_MAC @@ -2219,9 +2601,7 @@ bool CDriverGL::isActive() res = (IsWindow(_win) != FALSE); #elif defined(NL_OS_MAC) -# warning "OpenGL Driver: Missing Mac Implementation" - // nlwarning("OpenGL Driver: Missing Mac Implementation"); - +# warning "OpenGL Driver: Missing Mac Implementation for isActive" #elif defined (NL_OS_UNIX) #endif // NL_OS_UNIX @@ -2264,7 +2644,7 @@ void CDriverGL::setCapture (bool b) #elif defined(NL_OS_MAC) - NL3D::MAC::setCapture(b); + // no need to capture #elif defined (NL_OS_UNIX) @@ -2316,11 +2696,7 @@ NLMISC::IMouseDevice* CDriverGL::enableLowLevelMouse(bool enable, bool exclusive } #elif defined(NL_OS_MAC) -# warning "OpenGL Driver: Missing Mac Implementation" - nlwarning("OpenGL Driver: Missing Mac Implementation"); - #elif defined (NL_OS_UNIX) - #endif return res; @@ -2358,11 +2734,7 @@ NLMISC::IKeyboardDevice* CDriverGL::enableLowLevelKeyboard(bool enable) } #elif defined(NL_OS_MAC) -# warning "OpenGL Driver: Missing Mac Implementation" - nlwarning("OpenGL Driver: Missing Mac Implementation"); - #elif defined (NL_OS_UNIX) - #endif return res; @@ -2381,11 +2753,7 @@ NLMISC::IInputDeviceManager* CDriverGL::getLowLevelInputDeviceManager() res = NLMISC::safe_cast(_EventEmitter.getEmitter(1)); #elif defined(NL_OS_MAC) -# warning "OpenGL Driver: Missing Mac Implementation" - nlwarning("OpenGL Driver: Missing Mac Implementation"); - #elif defined (NL_OS_UNIX) - #endif return res; @@ -2429,8 +2797,8 @@ uint CDriverGL::getDoubleClickDelay(bool hardwareMouse) } #elif defined(NL_OS_MAC) -# warning "OpenGL Driver: Missing Mac Implementation" - nlwarning("OpenGL Driver: Missing Mac Implementation"); +# warning "OpenGL Driver: Missing Mac Implementation for getDoubleClickDelay" + nlwarning("OpenGL Driver: Missing Mac Implementation for getDoubleClickDelay"); #elif defined (NL_OS_UNIX) @@ -2492,11 +2860,10 @@ bool CDriverGL::setMonitorColorProperties (const CMonitorColorProperties &proper } #elif defined(NL_OS_MAC) -# warning "OpenGL Driver: Missing Mac Implementation" - nlwarning("OpenGL Driver: Missing Mac Implementation"); + // TODO for Mac: implement CDriverGL::setMonitorColorProperties + nlwarning ("CDriverGL::setMonitorColorProperties not implemented"); #elif defined (NL_OS_UNIX) - // TODO for Linux: implement CDriverGL::setMonitorColorProperties nlwarning ("CDriverGL::setMonitorColorProperties not implemented"); @@ -2505,4 +2872,64 @@ bool CDriverGL::setMonitorColorProperties (const CMonitorColorProperties &proper return false; } +#ifdef NL_OS_MAC +void CDriverGL::setupApplicationMenu() +{ + NSMenu* menu; + NSMenuItem* menuItem; + NSString* title; + NSString* appName; + + // get the applications name from it's process info + appName = [[NSProcessInfo processInfo] processName]; + + // create an empty menu object + menu = [[NSMenu alloc] initWithTitle:@""]; + + // add the about menu item + title = [@"About " stringByAppendingString:appName]; + [menu addItemWithTitle:title + action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; + + // separator + [menu addItem:[NSMenuItem separatorItem]]; + + // add the hide application menu item + title = [@"Hide " stringByAppendingString:appName]; + [menu addItemWithTitle:title + action:@selector(hide:) keyEquivalent:@"h"]; + + // add the hide others menu item + menuItem = [menu addItemWithTitle:@"Hide Others" + action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; + + // add the show all menu item + [menu addItemWithTitle:@"Show All" + action:@selector(unhideAllApplications:) keyEquivalent:@""]; + + // separator + [menu addItem:[NSMenuItem separatorItem]]; + + /* + TODO on quit send EventDestroyWindowId + */ + // add the quit menu item + title = [@"Quit " stringByAppendingString:appName]; + [menu addItemWithTitle:title + action:@selector(terminate:) keyEquivalent:@"q"]; + + // create an empty menu item and put the new menu into it as a subitem + menuItem = [[NSMenuItem alloc] initWithTitle:@"" + action:nil keyEquivalent:@""]; + [menuItem setSubmenu:menu]; + + // create a menu for the application + [NSApp setMainMenu:[[NSMenu alloc] initWithTitle:@""]]; + + // attach the new menu to the applications menu + [[NSApp mainMenu] addItem:menuItem]; +} +#endif + } // NL3D diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.h b/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.h index d7e66cfe5..3b389f043 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.h +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.h @@ -16,103 +16,4 @@ // along with this program. If not, see . */ -#ifndef NL_DRIVER_OPENGL_MAC_COCOA_ADAPTER_H -#define NL_DRIVER_OPENGL_MAC_COCOA_ADAPTER_H - -#include "nel/misc/types_nl.h" -#include "nel/misc/event_server.h" -#include "nel/3d/driver.h" - -#include "cocoa_event_emitter.h" - -/* - * this cocoa adapter is a helper to call functions executing obj-c code - * from driver_opengl.cpp - * - * please see this as a temporary solution... there is some stuff concerning - * driver refactoring going on anyway as far as i know - * - * this can as well be seen as a preparation to pull platform specific code - * out of driver_opengl.cpp ;) - * - * btw: we cannot simply use a c++ class here, because then NSWindow* and friends - * would be members, but then we would need to add obj-c code here using an - * include or a forward declaration. this again would break compiling cpp files - * including this one (eg. driver_opengl.cpp) - */ - -namespace NL3D { namespace MAC { - -/// mac specific stuff while calling CDriverGL::CDriverGL() -void ctor(); - -/// mac specific stuff while calling CDriverGL::~CDriverGL() -void dtor(); - -/// mac specific stuff while calling CDriverGL::init() -bool init(uint windowIcon = 0, emptyProc exitFunc = 0); - -/// mac specific stuff while calling CDriverGL::unInit() -bool unInit(); - -/// mac specific stuff while calling CDriverGL::createWindow() -nlWindow createWindow(const GfxMode& mode); - -/// mac specific stuff while calling CDriverGL::destroyWindow() -bool destroyWindow(nlWindow wnd); - -/// mac specific stuff while calling CDriverGL::setDisplay() -nlWindow setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable); - -/// mac specific stuff while calling CDriverGL::setWindowStyle() -bool setWindowStyle(nlWindow wnd, bool fullscreen); - -/// mac specific stuff while calling CDriverGL::getCurrentScreenMode() -void getCurrentScreenMode(nlWindow wnd, GfxMode& mode); - -/// mac specific stuff while calling CDriverGL::getModes() -bool getModes(std::vector &modes); - -/// mac specific stuff while calling CDriverGL::getWindowSize() -void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height); - -/// mac specific stuff while calling CDriverGL::setWindowSize() -void setWindowSize(nlWindow wnd, uint32 width, uint32 height); - -/// mac specific stuff while calling CDriverGL::getWindowPos() -void getWindowPos(nlWindow wnd, sint32 &x, sint32 &y); - -/// mac specific stuff while calling CDriverGL::setWindowPos() -void setWindowPos(nlWindow wnd, sint32 x, sint32 y); - -/// mac specific stuff while calling CDriverGL::setWindowTitle() -void setWindowTitle(nlWindow wnd, const ucstring& title); - -/// mac specific stuff while calling CDriverGL::showWindow() -void showWindow(bool show); - -/// mac specific stuff while calling CDriverGL::activate() -bool activate(nlWindow wnd); - -/// mac specific stuff while calling CDriverGL::swapBuffers() -void swapBuffers(nlWindow wnd); - -/// mac specific stuff while calling CDriverGL::setCapture() -void setCapture(bool capture); - -/// mac specific stuff while calling CDriverGL::showCursor() -void showCursor(bool show); - -/// mac specific stuff while calling CDriverGL::setMousePos() -void setMousePos(nlWindow wnd, float x, float y); - -/// mac specific stuff while calling CCocoaEventEmitter::submitEvents() -void submitEvents(NLMISC::CEventServer& server, - bool allWindows, NLMISC::CCocoaEventEmitter* eventEmitter); - -/// mac specific stuff while calling CCocoaEventEmitter::emulateMouseRawMode() -void emulateMouseRawMode(bool enable); - -}} - -#endif +/* TODO remove this file */ diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.mm b/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.mm index 8898a930c..3b389f043 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.mm +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_adapter.mm @@ -16,1100 +16,4 @@ // along with this program. If not, see . */ -#include "cocoa_adapter.h" - -#include "nel/misc/events.h" -#include "nel/misc/game_device_events.h" -#include "nel/3d/driver.h" - -#include "cocoa_event_emitter.h" -#include "cocoa_opengl_view.h" - -// Virtual key codes are only defined here. Still do not need to link carbon. -// see: http://lists.apple.com/archives/Cocoa-dev/2009/May/msg01180.html -#include - -#import -#import - -namespace NL3D { namespace MAC { - -// This cocoa adapter can be used in two environments: -// First: There is no other code which creates the NSApplication object, so -// NeL is completely in charge of starting and setting up the application. -// In this case, the NSAutoreleasePool needed to handle the cocoa style memory -// management is created by this code. -// Second: There is already a NSApplication set up. This could be the case if -// NeL is used for example in a Qt widget. So Qt already created all the -// NSApplication infrastructure, so it is not set up by this code again! -// -// Thats why, the g_pool variable (containing a pointer to the NSAutoreleasePool -// created by this code) can be used to check whether NeL created the -// NSApplication infrastructure itself or not. -// -// WARNING: -// Currently the NSApplication infrastructure is automatically created with the -// call to createWindow(). So if for example Qt already created NSApplication, -// createWindow() must not be called. Instead, setDisplay() can be provided with -// a window handle (on Mac OS Cocoa Qt this is a NSView*). In this case, this -// cocoa adapter will skip the NSApplication setup and embed itself into the -// provided view running in the already set up application. - -static NSAutoreleasePool* g_pool = nil; -/* - TODO move to event emitter class -*/ -static bool g_emulateRawMode = false; -static int g_bufferSize[2] = { 0, 0 }; - -/// setup an apple style application menu (located at the top bar of the screen) -static void setupApplicationMenu() -{ - NSMenu* menu; - NSMenuItem* menuItem; - NSString* title; - NSString* appName; - - // get the applications name from it's process info - appName = [[NSProcessInfo processInfo] processName]; - - // create an empty menu object - menu = [[NSMenu alloc] initWithTitle:@""]; - - // add the about menu item - title = [@"About " stringByAppendingString:appName]; - [menu addItemWithTitle:title - action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - // separator - [menu addItem:[NSMenuItem separatorItem]]; - - // add the hide application menu item - title = [@"Hide " stringByAppendingString:appName]; - [menu addItemWithTitle:title - action:@selector(hide:) keyEquivalent:@"h"]; - - // add the hide others menu item - menuItem = [menu addItemWithTitle:@"Hide Others" - action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - // add the show all menu item - [menu addItemWithTitle:@"Show All" - action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - // separator - [menu addItem:[NSMenuItem separatorItem]]; - - /* - TODO on quit send EventDestroyWindowId - */ - // add the quit menu item - title = [@"Quit " stringByAppendingString:appName]; - [menu addItemWithTitle:title - action:@selector(terminate:) keyEquivalent:@"q"]; - - // create an empty menu item and put the new menu into it as a subitem - menuItem = [[NSMenuItem alloc] initWithTitle:@"" - action:nil keyEquivalent:@""]; - [menuItem setSubmenu:menu]; - - // create a menu for the application - [NSApp setMainMenu:[[NSMenu alloc] initWithTitle:@""]]; - - // attach the new menu to the applications menu - [[NSApp mainMenu] addItem:menuItem]; -} - -/// set up the basic NSApplication and NSAutoreleasePool needed for Cocoa -static bool setupNSApplication() -{ - // if the pool was already created, return an error - if(g_pool) - return false; - - // create a pool, cocoa code would leak memory otherwise - g_pool = [[NSAutoreleasePool alloc] init]; - - // init the application object - [NSApplication sharedApplication]; - - // create the menu in the top screen bar - setupApplicationMenu(); - - // finish the application launching - [NSApp finishLaunching]; - - return true; -} - -/// setup an open gl view and embed it in the provided parent view -static void setupGLView(NSView* superview) -{ - /* - TODO use mode.Depth - TODO NSOpenGLPFAOffScreen - */ - - // setup opengl settings - NSOpenGLPixelFormatAttribute att[] = - { - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAColorSize, 24, - NSOpenGLPFADepthSize, 24, - NSOpenGLPFAAlphaSize, 8, - NSOpenGLPFAStencilSize, 8, - NSOpenGLPFANoRecovery, - NSOpenGLPFAAccelerated, - NSOpenGLPFABackingStore, - 0 - }; - - // put the settings into a format object - NSOpenGLPixelFormat* format = - [[NSOpenGLPixelFormat alloc] initWithAttributes:att]; - - if(!format) - nlerror("cannot create NSOpenGLPixelFormat"); - - // create a opengl view with the created format - NSOpenGLView* view = [[CocoaOpenGLView alloc] - initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat: format]; - - if(!view) - nlerror("cannot create view"); - - // make the view automatically fit the super view - [view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; - - // put the view into the superview - [superview addSubview:view]; - - [view setFrame: [superview frame]]; - - // create a opengl context for the view - NSOpenGLContext* ctx = [view openGLContext]; - - if(!ctx) - nlerror("cannot create context"); - - // free the pixel format object - [format release]; -} - -void ctor() -{ -} - -void dtor() -{ -} - -bool init(uint windowIcon, emptyProc exitFunc) -{ - return true; -} - -bool unInit() -{ - return true; -} - -/// setup the basic cocoa app infrastructure and create a window -nlWindow createWindow(const GfxMode& mode) -{ - if(!setupNSApplication()) - nlerror("createWindow must not be called before the old window was " - "destroyed using destroyWindow()!"); - - // describe how the window should look like and behave - unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask | NSResizableWindowMask; - - // create a cocoa window with the size provided by the mode parameter - NSWindow* window = [[NSWindow alloc] - initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height) - styleMask:styleMask backing:NSBackingStoreBuffered defer:NO]; - - if(!window) - nlerror("cannot create window"); - - // set the window to non transparent - [window setOpaque:YES]; - - // enable mouse move events, NeL wants them - [window setAcceptsMouseMovedEvents:YES]; - - // there are no overlapping subviews, can use the magical optimization :) - [window useOptimizedDrawing:YES]; - - // put the window to the front and make it the key window - [window makeKeyAndOrderFront:nil]; - - // this is our main window - [window makeMainWindow]; - - NSView* view = [[NSView alloc] init]; - - [window setContentView: view]; - - return view; -} - -/// destroy the given window -bool destroyWindow(nlWindow wnd) -{ - NSView* view = (NSView*)wnd; - - // release the window - [[view window] release]; - - // release the pool - [g_pool release]; - g_pool = nil; - - return true; -} - -/// set the displays settings, if no win is provided, a new one will be created -nlWindow setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable) -{ - NSView* view = (NSView*)wnd; - - if(view == EmptyWindow) - view = (NSView*)createWindow(mode); - - setupGLView(view); - - [[view window] makeFirstResponder:[[view subviews] lastObject]]; - - return view; -} - -/// switch between fullscreen and windowed mode -bool setWindowStyle(nlWindow wnd, bool fullscreen) -{ - if(wnd == EmptyWindow) - { - nlwarning("cannot set window style on an empty window"); - return false; - } - - NSView* superview = (NSView*)wnd; - NSOpenGLView* view = [[superview subviews] lastObject]; - - // leave fullscreen mode, enter windowed mode - if(!fullscreen && [superview isInFullScreenMode]) - { - // disable manual setting of back buffer size, cocoa handles this - // automatically as soon as the view gets resized - CGLError error = CGLDisable( - (CGLContextObj)[[view openGLContext] CGLContextObj], - kCGLCESurfaceBackingSize); - - if(error != kCGLNoError) - nlerror("cannot disable kCGLCESurfaceBackingSize (%s)", - CGLErrorString(error)); - - // pull the view back from fullscreen restoring window options - [superview exitFullScreenModeWithOptions:nil]; - - // let the gl view receive key events - [[view window] makeFirstResponder:view]; - - // bring the window containing the gl view to the front - [[view window] makeKeyAndOrderFront:nil]; - } - - // enter fullscreen, leave windowed mode - else if(fullscreen && ![superview isInFullScreenMode]) - { - // enable manual back buffer size for mode setting in fullscreen - CGLError error = CGLEnable( - (CGLContextObj)[[view openGLContext] CGLContextObj], - kCGLCESurfaceBackingSize); - - if(error != kCGLNoError) - nlerror("cannot enable kCGLCESurfaceBackingSize (%s)", - CGLErrorString(error)); - - // put the view in fullscreen mode, hiding the dock but enabling the menubar - // to pop up if the mouse hits the top screen border. - // NOTE: withOptions:nil disables + application switching! -#ifdef MAC_OS_X_VERSION_10_6 - [superview enterFullScreenMode:[NSScreen mainScreen] withOptions: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt: - NSApplicationPresentationHideDock | - NSApplicationPresentationAutoHideMenuBar], - NSFullScreenModeApplicationPresentationOptions, nil]]; -#endif // MAC_OS_X_VERSION_10_6 - /* - TODO check if simply using NSView enterFullScreenMode is a good idea. - the context can be set to full screen as well, performance differences? - */ - - // let the gl view receive key events - [[view window] makeFirstResponder:view]; - } - - return true; -} - -/// get the current mode of the screen -void getCurrentScreenMode(nlWindow wnd, GfxMode& mode) -{ - NSView* superview = (NSView*)wnd; - NSOpenGLView* view = [[superview subviews] lastObject]; - - // the sceen with the menu bar - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; - - mode.OffScreen = false; - mode.Frequency = 0; - mode.Depth = NSBitsPerPixelFromDepth([screen depth]); - - // in fullscreen mode - if([superview isInFullScreenMode]) - { - // return the size of the back buffer (like having switched monitor mode) - mode.Windowed = false; - mode.Width = (uint16)g_bufferSize[0]; - mode.Height = (uint16)g_bufferSize[1]; - } - - // in windowed mode - else - { - // return the size of the screen with menu bar - mode.Windowed = true; - mode.Width = (uint16)[screen frame].size.width; - mode.Height = (uint16)[screen frame].size.height; - } -} - -#ifdef MAC_OS_X_VERSION_10_6 -/// helper to extract bits per pixel value from screen mode, only 16 or 32 bits -static int bppFromDisplayMode(CGDisplayModeRef mode) -{ - CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode); - - if(CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels), - kCFCompareCaseInsensitive) == kCFCompareEqualTo) - return 32; - - else if(CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels), - kCFCompareCaseInsensitive) == kCFCompareEqualTo) - return 16; - - return 0; -} -#endif // MAC_OS_X_VERSION_10_6 - -/// get the list of available screen modes -bool getModes(std::vector &modes) -{ - static const CGDisplayCount kMaxDisplays = 16; - CGDirectDisplayID display[kMaxDisplays]; - CGDisplayCount numDisplays; - - CGDisplayErr err = CGGetActiveDisplayList(kMaxDisplays, display, &numDisplays); - if(err != CGDisplayNoErr) - { - nlwarning("Cannot get displays (%d)", err); - return false; - } - - nldebug("3D: %d displays found", (int)numDisplays); - -#ifdef MAC_OS_X_VERSION_10_6 - for (CGDisplayCount i = 0; i < numDisplays; ++i) - { - CGDirectDisplayID dspy = display[i]; - CFArrayRef modeList = CGDisplayCopyAllDisplayModes(dspy, NULL); - - if (modeList == NULL) - { - nlwarning("Display is invalid"); - continue; - } - - for (CFIndex j = 0; j < CFArrayGetCount(modeList); ++j) - { - CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modeList, j); - uint8 bpp = bppFromDisplayMode(mode); - - if (bpp >= 16) - { - uint16 w = CGDisplayModeGetWidth(mode); - uint16 h = CGDisplayModeGetHeight(mode); - - // Add this mode - GfxMode mode; - mode.Width = w; - mode.Height = h; - mode.Depth = bpp; - - // Frequency stays at 0 because on mac cocoa, display resolution - // is never really changed. if rendering res < display res, - // cocoa interpolates and keeps the display at it's original res. - mode.Frequency = 0; - modes.push_back (mode); - - nldebug(" Display 0x%x: Mode %dx%d, %d BPP", dspy, w, h, bpp); - } - } - } -#endif // MAC_OS_X_VERSION_10_6 - - return true; -} - -/// get the size of the window's content area -void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height) -{ - NSView* superview = (NSView*)wnd; - NSOpenGLView* view = [[superview subviews] lastObject]; - - // A cocoa fullscreen view stays at the native resolution of the display. - // When changing the rendering resolution, the size of the back buffer gets - // changed, but the view still stays at full resolution. So the scaling of - // the image from the rendered resolution to the view's resolution is done - // by cocoa automatically while flushing buffers. - // That's why, in fullscreen mode, return the resolution of the back buffer, - // not the one from the window. - - // in fullscreen mode - if([superview isInFullScreenMode]) - { - // use the size stored in setWindowSize() - width = g_bufferSize[0]; - height = g_bufferSize[1]; - } - - // in windowed mode - else - { - // use the size of the view - NSRect rect = [view frame]; - width = rect.size.width; - height = rect.size.height; - } -} - -/// set the size of the window's content area -void setWindowSize(nlWindow wnd, uint32 width, uint32 height) -{ - NSView* superview = (NSView*)wnd; - NSOpenGLView* view = [[superview subviews] lastObject]; - - // for fullscreen mode, adjust the back buffer size to the desired resolution - if([superview isInFullScreenMode]) - { - // disable and re-enable fullscreen - // fixes #1062 (http://dev.ryzom.com/issues/1062) - setWindowStyle(wnd, false); - setWindowStyle(wnd, true); - - // set the back buffer manually to match the desired rendering resolution - GLint dim[2] = { width, height }; - CGLError error = CGLSetParameter( - (CGLContextObj)[[view openGLContext] CGLContextObj], - kCGLCPSurfaceBackingSize, dim); - - if(error != kCGLNoError) - nlerror("cannot set kCGLCPSurfaceBackingSize parameter (%s)", - CGLErrorString(error)); - } - else - { - // there is only a pool if NeL created the window itself - // else, the window is not NeL's, so it must not be changed - if(g_pool) - { - NSWindow* window = [view window]; - - // get the windows current frame - NSRect rect = [window frame]; - - // convert the desired content size to window size - rect = [window frameRectForContentRect: - NSMakeRect(rect.origin.x, rect.origin.y, width, height)]; - - // update window dimensions - [window setFrame:rect display:YES]; - } - } - - // store the size - g_bufferSize[0] = width; - g_bufferSize[1] = height; -} - -/// get the position of the window -void getWindowPos(nlWindow wnd, sint32 &x, sint32 &y) -{ - NSView* superview = (NSView*)wnd; - NSOpenGLView* view = [[superview subviews] lastObject]; - NSWindow* window = [view window]; - - // for IDriver conformity - if([superview isInFullScreenMode]) - { - x = y = 0; - return; - } - - // get the rect (position, size) of the screen with menu bar - NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; - - // get the rect (position, size) of the window - NSRect windowRect = [window frame]; - - // simply return x - x = windowRect.origin.x; - - // map y from cocoa to NeL coordinates before returning - y = screenRect.size.height - windowRect.size.height - windowRect.origin.y; -} - -/// set the position of the window -void setWindowPos(nlWindow wnd, sint32 x, sint32 y) -{ - NSView* superview = (NSView*)wnd; - NSWindow* window = [superview window]; - - // get the rect (position, size) of the screen with menu bar - NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame]; - - // get the rect (position, size) of the window - NSRect windowRect = [window frame]; - - // convert y from NeL coordinates to cocoa coordinates - y = screenRect.size.height - y; - - // tell cocoa to move the window - [window setFrameTopLeftPoint:NSMakePoint(x, y)]; -} - -/// set the windows title (not the title of the application) -void setWindowTitle(nlWindow wnd, const ucstring& title) -{ - NSView* superview = (NSView*)wnd; - NSWindow* window = [superview window]; - - // well... set the title of the window - [window setTitle:[NSString stringWithUTF8String:title.toUtf8().c_str()]]; -} - -void showWindow(bool show) -{ - nldebug("show: %d - implement me!", show); -} - -/// make the opengl context the current one -bool activate(nlWindow wnd) -{ - NSView* superview = (NSView*)wnd; - NSOpenGLView* view = [[superview subviews] lastObject]; - NSOpenGLContext* ctx = [view openGLContext]; - - // if our context is not the current one, make it the current - if([NSOpenGLContext currentContext] != ctx) - [ctx makeCurrentContext]; - - return true; -} - -/// flush current back buffer to screen -void swapBuffers(nlWindow wnd) -{ - NSView* superview = (NSView*)wnd; - NSOpenGLView* view = [[superview subviews] lastObject]; - NSOpenGLContext* ctx = [view openGLContext]; - - // make cocoa draw buffer contents to the view - [ctx flushBuffer]; - [view display]; -} - -void setCapture(bool capture) -{ - // no need to capture -} - -/// show or hide the mouse cursor -void showCursor(bool show) -{ - // Mac OS manages a show/hide counter for the cursor, so hiding the cursor - // twice requires two calls to "show" to make the cursor visible again. - // Since other platforms seem to not do this, the functionality is masked here - // by only calling hide if the cursor is visible and only calling show if - // the cursor was hidden. - - CGDisplayErr error = kCGErrorSuccess; - static bool visible = true; - - if(show && !visible) - { - error = CGDisplayShowCursor(kCGDirectMainDisplay); - visible = true; - } - else if(!show && visible) - { - error = CGDisplayHideCursor(kCGDirectMainDisplay); - visible = false; - } - - if(error != kCGErrorSuccess) - nlerror("cannot show / hide cursor"); -} - -/// set the mouse position -void setMousePos(nlWindow wnd, float x, float y) -{ - NSView* superview = (NSView*)wnd; - NSOpenGLView* view = [[superview subviews] lastObject]; - NSWindow* window = [view window]; - - // CG wants absolute coordinates related to first screen's top left - - // get the first screen's (conaints menubar) rect (this is not mainScreen) - NSRect firstScreenRect = [[[NSScreen screens] objectAtIndex:0] frame]; - - // get the rect (position, size) of the window - NSRect windowRect; - if([superview isInFullScreenMode]) - windowRect = [[window screen] frame]; - else - windowRect = [window frame]; - - // get the gl view's rect for height and width - NSRect viewRect = [view frame]; - - // set the cursor position - CGDisplayErr error = CGDisplayMoveCursorToPoint( - kCGDirectMainDisplay, CGPointMake( - windowRect.origin.x + (viewRect.size.width * x), - firstScreenRect.size.height - windowRect.origin.y - - viewRect.size.height + ((1.0 - y) * viewRect.size.height))); - - if(error != kCGErrorSuccess) - nlerror("cannot set mouse position"); -} - -/* - TODO: this function has to be moved to a more central place to handle key - mapping on mac x11 as well -*/ -/// map from virtual key code to nel internal key code -static NLMISC::TKey virtualKeycodeToNelKey(unsigned short keycode) -{ - switch(keycode) - { - case kVK_ANSI_0: return NLMISC::Key0; - case kVK_ANSI_1: return NLMISC::Key1; - case kVK_ANSI_2: return NLMISC::Key2; - case kVK_ANSI_3: return NLMISC::Key3; - case kVK_ANSI_4: return NLMISC::Key4; - case kVK_ANSI_5: return NLMISC::Key5; - case kVK_ANSI_6: return NLMISC::Key6; - case kVK_ANSI_7: return NLMISC::Key7; - case kVK_ANSI_8: return NLMISC::Key8; - case kVK_ANSI_9: return NLMISC::Key9; - case kVK_ANSI_A: return NLMISC::KeyA; - case kVK_ANSI_B: return NLMISC::KeyB; - case kVK_ANSI_C: return NLMISC::KeyC; - case kVK_ANSI_D: return NLMISC::KeyD; - case kVK_ANSI_E: return NLMISC::KeyE; - case kVK_ANSI_F: return NLMISC::KeyF; - case kVK_ANSI_G: return NLMISC::KeyG; - case kVK_ANSI_H: return NLMISC::KeyH; - case kVK_ANSI_I: return NLMISC::KeyI; - case kVK_ANSI_J: return NLMISC::KeyJ; - case kVK_ANSI_K: return NLMISC::KeyK; - case kVK_ANSI_L: return NLMISC::KeyL; - case kVK_ANSI_M: return NLMISC::KeyM; - case kVK_ANSI_N: return NLMISC::KeyN; - case kVK_ANSI_O: return NLMISC::KeyO; - case kVK_ANSI_P: return NLMISC::KeyP; - case kVK_ANSI_Q: return NLMISC::KeyQ; - case kVK_ANSI_R: return NLMISC::KeyR; - case kVK_ANSI_S: return NLMISC::KeyS; - case kVK_ANSI_T: return NLMISC::KeyT; - case kVK_ANSI_U: return NLMISC::KeyU; - case kVK_ANSI_V: return NLMISC::KeyV; - case kVK_ANSI_W: return NLMISC::KeyW; - case kVK_ANSI_X: return NLMISC::KeyX; - case kVK_ANSI_Y: return NLMISC::KeyY; - case kVK_ANSI_Z: return NLMISC::KeyZ; - case kVK_ANSI_Equal: return NLMISC::KeyEQUALS; - case kVK_ANSI_Minus: return NLMISC::KeySUBTRACT; - case kVK_ANSI_RightBracket: return NLMISC::KeyRBRACKET; - case kVK_ANSI_LeftBracket: return NLMISC::KeyLBRACKET; - case kVK_ANSI_Quote: return NLMISC::KeyAPOSTROPHE; - case kVK_ANSI_Grave: return NLMISC::KeyPARAGRAPH; - case kVK_ANSI_Slash: return NLMISC::KeySLASH; - case kVK_ANSI_Backslash: return NLMISC::KeyBACKSLASH; - case kVK_ANSI_Comma: return NLMISC::KeyCOMMA; - case kVK_ANSI_Period: return NLMISC::KeyPERIOD; - case kVK_ANSI_Semicolon: return NLMISC::KeySEMICOLON; - case kVK_ANSI_KeypadDecimal: return NLMISC::KeyDECIMAL; - case kVK_ANSI_KeypadMultiply: return NLMISC::KeyMULTIPLY; - case kVK_ANSI_KeypadPlus: return NLMISC::KeyADD; - case kVK_ANSI_KeypadClear: return NLMISC::KeyDELETE; - case kVK_ANSI_KeypadDivide: return NLMISC::KeyDIVIDE; - case kVK_ANSI_KeypadEnter: return NLMISC::KeyRETURN; - case kVK_ANSI_KeypadMinus: return NLMISC::KeySUBTRACT; - case kVK_ANSI_KeypadEquals: return NLMISC::KeySEPARATOR; - case kVK_ANSI_Keypad0: return NLMISC::KeyNUMPAD0; - case kVK_ANSI_Keypad1: return NLMISC::KeyNUMPAD1; - case kVK_ANSI_Keypad2: return NLMISC::KeyNUMPAD2; - case kVK_ANSI_Keypad3: return NLMISC::KeyNUMPAD3; - case kVK_ANSI_Keypad4: return NLMISC::KeyNUMPAD4; - case kVK_ANSI_Keypad5: return NLMISC::KeyNUMPAD5; - case kVK_ANSI_Keypad6: return NLMISC::KeyNUMPAD6; - case kVK_ANSI_Keypad7: return NLMISC::KeyNUMPAD7; - case kVK_ANSI_Keypad8: return NLMISC::KeyNUMPAD8; - case kVK_ANSI_Keypad9: return NLMISC::KeyNUMPAD9; - case kVK_Return: return NLMISC::KeyRETURN; - case kVK_Tab: return NLMISC::KeyTAB; - case kVK_Space: return NLMISC::KeySPACE; - case kVK_Delete: return NLMISC::KeyBACK; - case kVK_ForwardDelete: return NLMISC::KeyDELETE; - case kVK_Escape: return NLMISC::KeyESCAPE; - case kVK_Shift: return NLMISC::KeySHIFT; - case kVK_RightShift: return NLMISC::KeyRSHIFT; - case kVK_CapsLock: return NLMISC::KeyCAPITAL; - case kVK_Control: return NLMISC::KeyCONTROL; - case kVK_RightControl: return NLMISC::KeyRCONTROL; - case kVK_F1: return NLMISC::KeyF1; - case kVK_F2: return NLMISC::KeyF2; - case kVK_F3: return NLMISC::KeyF3; - case kVK_F4: return NLMISC::KeyF4; - case kVK_F5: return NLMISC::KeyF5; - case kVK_F6: return NLMISC::KeyF6; - case kVK_F7: return NLMISC::KeyF7; - case kVK_F8: return NLMISC::KeyF8; - case kVK_F9: return NLMISC::KeyF9; - case kVK_F11: return NLMISC::KeyF11; - case kVK_F13: return NLMISC::KeyF13; - case kVK_F16: return NLMISC::KeyF16; - case kVK_F14: return NLMISC::KeyF14; - case kVK_F10: return NLMISC::KeyF10; - case kVK_F12: return NLMISC::KeyF12; - case kVK_F15: return NLMISC::KeyF15; - case kVK_F17: return NLMISC::KeyF17; - case kVK_F18: return NLMISC::KeyF18; - case kVK_F19: return NLMISC::KeyF19; - case kVK_F20: return NLMISC::KeyF20; - case kVK_Home: return NLMISC::KeyHOME; - case kVK_End: return NLMISC::KeyEND; - case kVK_PageUp: return NLMISC::KeyPRIOR; - case kVK_PageDown: return NLMISC::KeyNEXT; - case kVK_LeftArrow: return NLMISC::KeyLEFT; - case kVK_RightArrow: return NLMISC::KeyRIGHT; - case kVK_DownArrow: return NLMISC::KeyDOWN; - case kVK_UpArrow: return NLMISC::KeyUP; - case kVK_Command:break; - case kVK_Option:break; - case kVK_RightOption:break; - case kVK_Function:break; - case kVK_VolumeUp:break; - case kVK_VolumeDown:break; - case kVK_Mute:break; - case kVK_Help:break; - case kVK_ISO_Section:break; - case kVK_JIS_Yen:break; - case kVK_JIS_Underscore:break; - case kVK_JIS_KeypadComma:break; - case kVK_JIS_Eisu:break; - case kVK_JIS_Kana:break; - default:break; - } - return NLMISC::KeyNOKEY; -} - -/* - TODO: this function has to be moved to a more central place to handle key - mapping on mac x11 as well -*/ -/// convert modifier key state to nel internal modifier key state -static NLMISC::TKeyButton modifierFlagsToNelKeyButton(unsigned int modifierFlags) -{ - unsigned int buttons = 0; - if (modifierFlags & NSControlKeyMask) buttons |= NLMISC::ctrlKeyButton; - if (modifierFlags & NSShiftKeyMask) buttons |= NLMISC::shiftKeyButton; - if (modifierFlags & NSAlternateKeyMask) buttons |= NLMISC::altKeyButton; - return (NLMISC::TKeyButton)buttons; -} - -/// check whether a given event represents input text -static bool isTextKeyEvent(NSEvent* event) -{ - // if there are no characters provided with this event, it is not a text event - if([[event characters] length] == 0) - return false; - - NLMISC::TKey nelKey = virtualKeycodeToNelKey([event keyCode]); - - // ryzom ui wants to have "escape key string" to leave text box - if(nelKey == NLMISC::KeyESCAPE) - return true; - - // ryzom ui wants to have "return key string" to submit text box (send chat) - if(nelKey == NLMISC::KeyRETURN) - return true; - - // get the character reported by cocoa - unsigned int character = [[event characters] characterAtIndex:0]; - - // printable ascii characters - if(isprint(character)) - return true; - - /* - TODO check why iswprint(character) does not solve it. - it always returns false, even for π, é, ... - */ - // characters > 127 but not printable - if( nelKey == NLMISC::KeyF1 || nelKey == NLMISC::KeyF2 || - nelKey == NLMISC::KeyF3 || nelKey == NLMISC::KeyF4 || - nelKey == NLMISC::KeyF5 || nelKey == NLMISC::KeyF6 || - nelKey == NLMISC::KeyF7 || nelKey == NLMISC::KeyF8 || - nelKey == NLMISC::KeyF9 || nelKey == NLMISC::KeyF10 || - nelKey == NLMISC::KeyF11 || nelKey == NLMISC::KeyF12 || - nelKey == NLMISC::KeyF13 || nelKey == NLMISC::KeyF14 || - nelKey == NLMISC::KeyF15 || nelKey == NLMISC::KeyF16 || - nelKey == NLMISC::KeyF17 || nelKey == NLMISC::KeyF18 || - nelKey == NLMISC::KeyF19 || nelKey == NLMISC::KeyF20 || - nelKey == NLMISC::KeyUP || nelKey == NLMISC::KeyDOWN || - nelKey == NLMISC::KeyLEFT || nelKey == NLMISC::KeyRIGHT || - nelKey == NLMISC::KeyHOME || nelKey == NLMISC::KeyEND || - nelKey == NLMISC::KeyPRIOR || nelKey == NLMISC::KeyNEXT || - nelKey == NLMISC::KeyDELETE) - return false; - - // all the fancy wide characters - if(character > 127) - return true; - - return false; -} - -/// switch between raw mode emulation, see IEventEmitter::emulateMouseRawMode() -void emulateMouseRawMode(bool enable) -{ - g_emulateRawMode = enable; -} - -/// submit events provided by the application to an event server -void submitEvents(NLMISC::CEventServer& server, - bool allWindows, NLMISC::CCocoaEventEmitter* eventEmitter) -{ - // if there is a pool, NeL needs to clean it up - // otherwise, other code must have created it (for example Qt) - if(g_pool) - { - // cocoa style memory cleanup - [g_pool release]; - g_pool = [[NSAutoreleasePool alloc] init]; - } - - // break if there was no event to handle - /* TODO maximum number of events processed in one update? */ - while(true) - { - // get the next event to handle - NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:nil /*[NSDate distantFuture]*/ - inMode:NSDefaultRunLoopMode dequeue:YES]; - - // stop, if there was no event - if(!event) - break; - - NSView* glView = [[[[event window] contentView] subviews] lastObject]; - NSRect viewRect = [glView frame]; - - // TODO this code assumes, that the view fills the window - // convert the mouse position to NeL style (relative) - float mouseX = event.locationInWindow.x / (float)viewRect.size.width; - float mouseY = event.locationInWindow.y / (float)viewRect.size.height; - - // if the mouse event was placed outside the view, don't tell NeL :) - if((mouseX < 0.0 || mouseX > 1.0 || mouseY < 0.0 || mouseY > 1.0) && - event.type != NSKeyDown && event.type != NSKeyUp) - { - [NSApp sendEvent:event]; - continue; - } - - // convert the modifiers for nel to pass them with the events - NLMISC::TKeyButton modifiers = - modifierFlagsToNelKeyButton([event modifierFlags]); - - switch(event.type) - { - case NSLeftMouseDown: - { - server.postEvent(new NLMISC::CEventMouseDown( - mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), - eventEmitter)); - } - break; - case NSLeftMouseUp: - { - server.postEvent(new NLMISC::CEventMouseUp( - mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), - eventEmitter)); - break; - } - case NSRightMouseDown: - { - server.postEvent(new NLMISC::CEventMouseDown( - mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), - eventEmitter)); - break; - } - case NSRightMouseUp: - { - server.postEvent(new NLMISC::CEventMouseUp( - mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), - eventEmitter)); - break; - } - case NSMouseMoved: - { - NLMISC::CEvent* nelEvent; - - // when emulating raw mode, send the delta in a CGDMouseMove event - if(g_emulateRawMode) - nelEvent = new NLMISC::CGDMouseMove( - eventEmitter, NULL /* no mouse device */, event.deltaX, -event.deltaY); - - // normally send position in a CEventMouseMove - else - nelEvent = new NLMISC::CEventMouseMove( - mouseX, mouseY, (NLMISC::TMouseButton)modifiers, eventEmitter); - - server.postEvent(nelEvent); - break; - } - case NSLeftMouseDragged: - { - NLMISC::CEvent* nelEvent; - - // when emulating raw mode, send the delta in a CGDMouseMove event - if(g_emulateRawMode) - nelEvent = new NLMISC::CGDMouseMove( - eventEmitter, NULL /* no mouse device */, event.deltaX, -event.deltaY); - - // normally send position in a CEventMouseMove - else - nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), - eventEmitter); - - server.postEvent(nelEvent); - break; - } - case NSRightMouseDragged: - { - NLMISC::CEvent* nelEvent; - - // when emulating raw mode, send the delta in a CGDMouseMove event - if(g_emulateRawMode) - nelEvent = new NLMISC::CGDMouseMove( - eventEmitter, NULL /* no mouse device */, event.deltaX, -event.deltaY); - - // normally send position in a CEventMouseMove - else - nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY, - (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), - eventEmitter); - - server.postEvent(nelEvent); - break; - } - case NSMouseEntered:break; - case NSMouseExited:break; - case NSKeyDown: - { - // push the key press event to the event server - server.postEvent(new NLMISC::CEventKeyDown( - virtualKeycodeToNelKey([event keyCode]), - modifierFlagsToNelKeyButton([event modifierFlags]), - [event isARepeat] == NO, - eventEmitter)); - - // if this was a text event - if(isTextKeyEvent(event)) - { - ucstring ucstr; - - // get the string associated with the key press event - ucstr.fromUtf8([[event characters] UTF8String]); - - // push the text event to event server as well - server.postEvent(new NLMISC::CEventChar( - ucstr[0], - NLMISC::noKeyButton, - eventEmitter)); - } - break; - } - case NSKeyUp: - { - // push the key release event to the event server - server.postEvent(new NLMISC::CEventKeyUp( - virtualKeycodeToNelKey([event keyCode]), - modifierFlagsToNelKeyButton([event modifierFlags]), - eventEmitter)); - break; - } - case NSFlagsChanged:break; - case NSAppKitDefined:break; - case NSSystemDefined:break; - case NSApplicationDefined:break; - case NSPeriodic:break; - case NSCursorUpdate:break; - case NSScrollWheel: - { - if(fabs(event.deltaY) > 0.1) - server.postEvent(new NLMISC::CEventMouseWheel( - mouseX, mouseY, (NLMISC::TMouseButton)modifiers, - (event.deltaY > 0), eventEmitter)); - - break; - } - case NSTabletPoint:break; - case NSTabletProximity:break; - case NSOtherMouseDown:break; - case NSOtherMouseUp:break; - case NSOtherMouseDragged:break; -#ifdef MAC_OS_X_VERSION_10_6 - case NSEventTypeGesture:break; - case NSEventTypeMagnify:break; - case NSEventTypeSwipe:break; - case NSEventTypeRotate:break; - case NSEventTypeBeginGesture:break; - case NSEventTypeEndGesture:break; -#endif // MAC_OS_X_VERSION_10_6 - default: - { - nlwarning("Unknown event type. dropping."); - // NSLog(@"%@", event); - break; - } - } - - [NSApp sendEvent:event]; - } -} - -}} +/* TODO remove this file */ diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp index 81225ab9a..86014e6cb 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.cpp @@ -16,21 +16,397 @@ #include "cocoa_event_emitter.h" -#include "cocoa_adapter.h" +#include "nel/misc/event_server.h" +#include "nel/misc/events.h" +#include "nel/misc/game_device_events.h" + +#include +#import namespace NLMISC { -void CCocoaEventEmitter::submitEvents(CEventServer & server, bool allWindows) +/// map from virtual key code to nel internal key code +static NLMISC::TKey virtualKeycodeToNelKey(unsigned short keycode) { - // just forwarding to our cocoa adapter - NL3D::MAC::submitEvents(server, allWindows, this); + switch(keycode) + { + case kVK_ANSI_0: return NLMISC::Key0; + case kVK_ANSI_1: return NLMISC::Key1; + case kVK_ANSI_2: return NLMISC::Key2; + case kVK_ANSI_3: return NLMISC::Key3; + case kVK_ANSI_4: return NLMISC::Key4; + case kVK_ANSI_5: return NLMISC::Key5; + case kVK_ANSI_6: return NLMISC::Key6; + case kVK_ANSI_7: return NLMISC::Key7; + case kVK_ANSI_8: return NLMISC::Key8; + case kVK_ANSI_9: return NLMISC::Key9; + case kVK_ANSI_A: return NLMISC::KeyA; + case kVK_ANSI_B: return NLMISC::KeyB; + case kVK_ANSI_C: return NLMISC::KeyC; + case kVK_ANSI_D: return NLMISC::KeyD; + case kVK_ANSI_E: return NLMISC::KeyE; + case kVK_ANSI_F: return NLMISC::KeyF; + case kVK_ANSI_G: return NLMISC::KeyG; + case kVK_ANSI_H: return NLMISC::KeyH; + case kVK_ANSI_I: return NLMISC::KeyI; + case kVK_ANSI_J: return NLMISC::KeyJ; + case kVK_ANSI_K: return NLMISC::KeyK; + case kVK_ANSI_L: return NLMISC::KeyL; + case kVK_ANSI_M: return NLMISC::KeyM; + case kVK_ANSI_N: return NLMISC::KeyN; + case kVK_ANSI_O: return NLMISC::KeyO; + case kVK_ANSI_P: return NLMISC::KeyP; + case kVK_ANSI_Q: return NLMISC::KeyQ; + case kVK_ANSI_R: return NLMISC::KeyR; + case kVK_ANSI_S: return NLMISC::KeyS; + case kVK_ANSI_T: return NLMISC::KeyT; + case kVK_ANSI_U: return NLMISC::KeyU; + case kVK_ANSI_V: return NLMISC::KeyV; + case kVK_ANSI_W: return NLMISC::KeyW; + case kVK_ANSI_X: return NLMISC::KeyX; + case kVK_ANSI_Y: return NLMISC::KeyY; + case kVK_ANSI_Z: return NLMISC::KeyZ; + case kVK_ANSI_Equal: return NLMISC::KeyEQUALS; + case kVK_ANSI_Minus: return NLMISC::KeySUBTRACT; + case kVK_ANSI_RightBracket: return NLMISC::KeyRBRACKET; + case kVK_ANSI_LeftBracket: return NLMISC::KeyLBRACKET; + case kVK_ANSI_Quote: return NLMISC::KeyAPOSTROPHE; + case kVK_ANSI_Grave: return NLMISC::KeyPARAGRAPH; + case kVK_ANSI_Slash: return NLMISC::KeySLASH; + case kVK_ANSI_Backslash: return NLMISC::KeyBACKSLASH; + case kVK_ANSI_Comma: return NLMISC::KeyCOMMA; + case kVK_ANSI_Period: return NLMISC::KeyPERIOD; + case kVK_ANSI_Semicolon: return NLMISC::KeySEMICOLON; + case kVK_ANSI_KeypadDecimal: return NLMISC::KeyDECIMAL; + case kVK_ANSI_KeypadMultiply: return NLMISC::KeyMULTIPLY; + case kVK_ANSI_KeypadPlus: return NLMISC::KeyADD; + case kVK_ANSI_KeypadClear: return NLMISC::KeyDELETE; + case kVK_ANSI_KeypadDivide: return NLMISC::KeyDIVIDE; + case kVK_ANSI_KeypadEnter: return NLMISC::KeyRETURN; + case kVK_ANSI_KeypadMinus: return NLMISC::KeySUBTRACT; + case kVK_ANSI_KeypadEquals: return NLMISC::KeySEPARATOR; + case kVK_ANSI_Keypad0: return NLMISC::KeyNUMPAD0; + case kVK_ANSI_Keypad1: return NLMISC::KeyNUMPAD1; + case kVK_ANSI_Keypad2: return NLMISC::KeyNUMPAD2; + case kVK_ANSI_Keypad3: return NLMISC::KeyNUMPAD3; + case kVK_ANSI_Keypad4: return NLMISC::KeyNUMPAD4; + case kVK_ANSI_Keypad5: return NLMISC::KeyNUMPAD5; + case kVK_ANSI_Keypad6: return NLMISC::KeyNUMPAD6; + case kVK_ANSI_Keypad7: return NLMISC::KeyNUMPAD7; + case kVK_ANSI_Keypad8: return NLMISC::KeyNUMPAD8; + case kVK_ANSI_Keypad9: return NLMISC::KeyNUMPAD9; + case kVK_Return: return NLMISC::KeyRETURN; + case kVK_Tab: return NLMISC::KeyTAB; + case kVK_Space: return NLMISC::KeySPACE; + case kVK_Delete: return NLMISC::KeyBACK; + case kVK_ForwardDelete: return NLMISC::KeyDELETE; + case kVK_Escape: return NLMISC::KeyESCAPE; + case kVK_Shift: return NLMISC::KeySHIFT; + case kVK_RightShift: return NLMISC::KeyRSHIFT; + case kVK_CapsLock: return NLMISC::KeyCAPITAL; + case kVK_Control: return NLMISC::KeyCONTROL; + case kVK_RightControl: return NLMISC::KeyRCONTROL; + case kVK_F1: return NLMISC::KeyF1; + case kVK_F2: return NLMISC::KeyF2; + case kVK_F3: return NLMISC::KeyF3; + case kVK_F4: return NLMISC::KeyF4; + case kVK_F5: return NLMISC::KeyF5; + case kVK_F6: return NLMISC::KeyF6; + case kVK_F7: return NLMISC::KeyF7; + case kVK_F8: return NLMISC::KeyF8; + case kVK_F9: return NLMISC::KeyF9; + case kVK_F11: return NLMISC::KeyF11; + case kVK_F13: return NLMISC::KeyF13; + case kVK_F16: return NLMISC::KeyF16; + case kVK_F14: return NLMISC::KeyF14; + case kVK_F10: return NLMISC::KeyF10; + case kVK_F12: return NLMISC::KeyF12; + case kVK_F15: return NLMISC::KeyF15; + case kVK_F17: return NLMISC::KeyF17; + case kVK_F18: return NLMISC::KeyF18; + case kVK_F19: return NLMISC::KeyF19; + case kVK_F20: return NLMISC::KeyF20; + case kVK_Home: return NLMISC::KeyHOME; + case kVK_End: return NLMISC::KeyEND; + case kVK_PageUp: return NLMISC::KeyPRIOR; + case kVK_PageDown: return NLMISC::KeyNEXT; + case kVK_LeftArrow: return NLMISC::KeyLEFT; + case kVK_RightArrow: return NLMISC::KeyRIGHT; + case kVK_DownArrow: return NLMISC::KeyDOWN; + case kVK_UpArrow: return NLMISC::KeyUP; + case kVK_Command:break; + case kVK_Option:break; + case kVK_RightOption:break; + case kVK_Function:break; + case kVK_VolumeUp:break; + case kVK_VolumeDown:break; + case kVK_Mute:break; + case kVK_Help:break; + case kVK_ISO_Section:break; + case kVK_JIS_Yen:break; + case kVK_JIS_Underscore:break; + case kVK_JIS_KeypadComma:break; + case kVK_JIS_Eisu:break; + case kVK_JIS_Kana:break; + default:break; + } + return NLMISC::KeyNOKEY; +} + +/// convert modifier key state to nel internal modifier key state +static NLMISC::TKeyButton modifierFlagsToNelKeyButton(unsigned int modifierFlags) +{ + unsigned int buttons = 0; + if (modifierFlags & NSControlKeyMask) buttons |= NLMISC::ctrlKeyButton; + if (modifierFlags & NSShiftKeyMask) buttons |= NLMISC::shiftKeyButton; + if (modifierFlags & NSAlternateKeyMask) buttons |= NLMISC::altKeyButton; + return (NLMISC::TKeyButton)buttons; +} + +/// check whether a given event represents input text +static bool isTextKeyEvent(NSEvent* event) +{ + // if there are no characters provided with this event, it is not a text event + if([[event characters] length] == 0) + return false; + + NLMISC::TKey nelKey = virtualKeycodeToNelKey([event keyCode]); + + // ryzom ui wants to have "escape key string" to leave text box + if(nelKey == NLMISC::KeyESCAPE) + return true; + + // ryzom ui wants to have "return key string" to submit text box (send chat) + if(nelKey == NLMISC::KeyRETURN) + return true; + + // get the character reported by cocoa + unsigned int character = [[event characters] characterAtIndex:0]; + + // printable ascii characters + if(isprint(character)) + return true; + + /* + TODO check why iswprint(character) does not solve it. + it always returns false, even for π, é, ... + */ + // characters > 127 but not printable + if( nelKey == NLMISC::KeyF1 || nelKey == NLMISC::KeyF2 || + nelKey == NLMISC::KeyF3 || nelKey == NLMISC::KeyF4 || + nelKey == NLMISC::KeyF5 || nelKey == NLMISC::KeyF6 || + nelKey == NLMISC::KeyF7 || nelKey == NLMISC::KeyF8 || + nelKey == NLMISC::KeyF9 || nelKey == NLMISC::KeyF10 || + nelKey == NLMISC::KeyF11 || nelKey == NLMISC::KeyF12 || + nelKey == NLMISC::KeyF13 || nelKey == NLMISC::KeyF14 || + nelKey == NLMISC::KeyF15 || nelKey == NLMISC::KeyF16 || + nelKey == NLMISC::KeyF17 || nelKey == NLMISC::KeyF18 || + nelKey == NLMISC::KeyF19 || nelKey == NLMISC::KeyF20 || + nelKey == NLMISC::KeyUP || nelKey == NLMISC::KeyDOWN || + nelKey == NLMISC::KeyLEFT || nelKey == NLMISC::KeyRIGHT || + nelKey == NLMISC::KeyHOME || nelKey == NLMISC::KeyEND || + nelKey == NLMISC::KeyPRIOR || nelKey == NLMISC::KeyNEXT || + nelKey == NLMISC::KeyDELETE) + return false; + + // all the fancy wide characters + if(character > 127) + return true; + + return false; +} + +void CCocoaEventEmitter::submitEvents(CEventServer& server, bool /* allWins */) +{ + // break if there was no event to handle + while(true) + { + // get the next event to handle + NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:nil /*[NSDate distantFuture]*/ + inMode:NSDefaultRunLoopMode dequeue:YES]; + + // stop, if there was no event + if(!event) + break; + + NSView* glView = [[[[event window] contentView] subviews] lastObject]; + NSRect viewRect = [glView frame]; + + // TODO this code assumes, that the view fills the window + // convert the mouse position to NeL style (relative) + float mouseX = event.locationInWindow.x / (float)viewRect.size.width; + float mouseY = event.locationInWindow.y / (float)viewRect.size.height; + + // if the mouse event was placed outside the view, don't tell NeL :) + if((mouseX < 0.0 || mouseX > 1.0 || mouseY < 0.0 || mouseY > 1.0) && + event.type != NSKeyDown && event.type != NSKeyUp) + { + [NSApp sendEvent:event]; + continue; + } + + // convert the modifiers for nel to pass them with the events + NLMISC::TKeyButton modifiers = + modifierFlagsToNelKeyButton([event modifierFlags]); + + switch(event.type) + { + case NSLeftMouseDown: + { + server.postEvent(new NLMISC::CEventMouseDown( + mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this)); + } + break; + case NSLeftMouseUp: + { + server.postEvent(new NLMISC::CEventMouseUp( + mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this)); + break; + } + case NSRightMouseDown: + { + server.postEvent(new NLMISC::CEventMouseDown( + mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this)); + break; + } + case NSRightMouseUp: + { + server.postEvent(new NLMISC::CEventMouseUp( + mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this)); + break; + } + case NSMouseMoved: + { + NLMISC::CEvent* nelEvent; + + // when emulating raw mode, send the delta in a CGDMouseMove event + if(_emulateRawMode) + nelEvent = new NLMISC::CGDMouseMove( + this, NULL /* no mouse device */, event.deltaX, -event.deltaY); + + // normally send position in a CEventMouseMove + else + nelEvent = new NLMISC::CEventMouseMove( + mouseX, mouseY, (NLMISC::TMouseButton)modifiers, this); + + server.postEvent(nelEvent); + break; + } + case NSLeftMouseDragged: + { + NLMISC::CEvent* nelEvent; + + // when emulating raw mode, send the delta in a CGDMouseMove event + if(_emulateRawMode) + nelEvent = new NLMISC::CGDMouseMove( + this, NULL /* no mouse device */, event.deltaX, -event.deltaY); + + // normally send position in a CEventMouseMove + else + nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::leftButton | modifiers), this); + + server.postEvent(nelEvent); + break; + } + case NSRightMouseDragged: + { + NLMISC::CEvent* nelEvent; + + // when emulating raw mode, send the delta in a CGDMouseMove event + if(_emulateRawMode) + nelEvent = new NLMISC::CGDMouseMove( + this, NULL /* no mouse device */, event.deltaX, -event.deltaY); + + // normally send position in a CEventMouseMove + else + nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY, + (NLMISC::TMouseButton)(NLMISC::rightButton | modifiers), this); + + server.postEvent(nelEvent); + break; + } + case NSMouseEntered:break; + case NSMouseExited:break; + case NSKeyDown: + { + // push the key press event to the event server + server.postEvent(new NLMISC::CEventKeyDown( + virtualKeycodeToNelKey([event keyCode]), + modifierFlagsToNelKeyButton([event modifierFlags]), + [event isARepeat] == NO, this)); + + // if this was a text event + if(isTextKeyEvent(event)) + { + ucstring ucstr; + + // get the string associated with the key press event + ucstr.fromUtf8([[event characters] UTF8String]); + + // push the text event to event server as well + server.postEvent(new NLMISC::CEventChar( + ucstr[0], NLMISC::noKeyButton, this)); + } + break; + } + case NSKeyUp: + { + // push the key release event to the event server + server.postEvent(new NLMISC::CEventKeyUp( + virtualKeycodeToNelKey([event keyCode]), + modifierFlagsToNelKeyButton([event modifierFlags]), this)); + break; + } + case NSFlagsChanged:break; + case NSAppKitDefined:break; + case NSSystemDefined:break; + case NSApplicationDefined:break; + case NSPeriodic:break; + case NSCursorUpdate:break; + case NSScrollWheel: + { + if(fabs(event.deltaY) > 0.1) + server.postEvent(new NLMISC::CEventMouseWheel( + mouseX, mouseY, (NLMISC::TMouseButton)modifiers, + (event.deltaY > 0), this)); + + break; + } + case NSTabletPoint:break; + case NSTabletProximity:break; + case NSOtherMouseDown:break; + case NSOtherMouseUp:break; + case NSOtherMouseDragged:break; +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + case NSEventTypeGesture:break; + case NSEventTypeMagnify:break; + case NSEventTypeSwipe:break; + case NSEventTypeRotate:break; + case NSEventTypeBeginGesture:break; + case NSEventTypeEndGesture:break; +#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + default: + { + nlwarning("Unknown event type. dropping."); + // NSLog(@"%@", event); + break; + } + } + + [NSApp sendEvent:event]; + } } void CCocoaEventEmitter::emulateMouseRawMode(bool enable) { - // just forwarding to our cocoa adapter - NL3D::MAC::emulateMouseRawMode(enable); + _emulateRawMode = enable; } } diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h index b31272b8f..72bfbb718 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_event_emitter.h @@ -24,7 +24,11 @@ namespace NLMISC class CCocoaEventEmitter : public IEventEmitter { + bool _emulateRawMode; + public: + CCocoaEventEmitter() : _emulateRawMode(false) { } + virtual void submitEvents(CEventServer & server, bool allWindows); virtual void emulateMouseRawMode(bool enable); }; diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.h b/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.h index 11bb87cc7..1a4bc76f0 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.h +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.h @@ -18,9 +18,6 @@ #import -/** - * derived to configure the NSOpenGLView - */ @interface CocoaOpenGLView : NSOpenGLView { NSMutableAttributedString* characterStorage; diff --git a/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.m b/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.m index fbb43f5fc..cc0a83800 100644 --- a/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.m +++ b/code/nel/src/3d/driver/opengl/mac/cocoa_opengl_view.m @@ -22,7 +22,7 @@ -(id)initWithFrame:(NSRect)frame { - if(self = [super initWithFrame:frame]) + if((self = [super initWithFrame:frame])) { characterStorage = [[NSMutableAttributedString alloc] initWithString:@""]; return self; @@ -38,7 +38,9 @@ -(void)keyDown:(NSEvent*)event { +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER [[self inputContext] handleEvent:event]; +#endif // AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER } /******************************************************************************/ @@ -74,7 +76,8 @@ else { markedRange = NSMakeRange(replacementRange.location, [aString length]); - [characterStorage replaceCharactersInRange:replacementRange withString:aString]; + [characterStorage replaceCharactersInRange:replacementRange + withString:aString]; } } @@ -102,7 +105,8 @@ if(replacementRange.location == NSNotFound) replacementRange = markedRange; - [characterStorage replaceCharactersInRange:replacementRange withString:aString]; + [characterStorage replaceCharactersInRange:replacementRange + withString:aString]; } -(NSUInteger)characterIndexForPoint:(NSPoint)aPoint diff --git a/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp b/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp index abc07dba3..f5de38371 100644 --- a/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp +++ b/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp @@ -29,7 +29,7 @@ typedef bool (*x11Proc)(NL3D::IDriver *drv, XEvent *e); namespace NLMISC { -CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _PreviousKey(KeyNOKEY), _emulateRawMode(false), _driver(NULL) +CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _emulateRawMode(false), _driver(NULL) { _im = 0; _ic = 0; @@ -111,7 +111,7 @@ void CUnixEventEmitter::submitEvents(CEventServer & server, bool allWindows) static Bool isMouseMoveEvent(Display *display, XEvent *event, XPointer arg) { - return (event->type == MotionNotify); + return (event->type == MotionNotify); } void CUnixEventEmitter::emulateMouseRawMode(bool enable) @@ -124,9 +124,9 @@ void CUnixEventEmitter::emulateMouseRawMode(bool enable) XGetWindowAttributes(_dpy, _win, &xwa); XWarpPointer(_dpy, None, _win, None, None, None, None, (xwa.width / 2), (xwa.height / 2)); - + // remove all outstanding mouse move events, they happened before the mouse - // was pulled back to 0.5 / 0.5, so a wrong movement delta would be + // was pulled back to 0.5 / 0.5, so a wrong movement delta would be // reported otherwise XEvent event; while(XCheckIfEvent(_dpy, &event, &isMouseMoveEvent, NULL)) { }; @@ -533,8 +533,14 @@ bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server) if(key == KeyNOKEY) key = getKeyFromKeycode(keyCode); - server->postEvent (new CEventKeyDown (key, getKeyButton(event.xbutton.state), _PreviousKey != key, this)); - _PreviousKey = key; + // search for key in map + std::map::const_iterator it = _PressedKeys.find(key); + + // if key is not found or value is false, that's the first time + bool firstTime = (it == _PressedKeys.end()) || !it->second; + + server->postEvent (new CEventKeyDown (key, getKeyButton(event.xbutton.state), firstTime, this)); + _PressedKeys[key] = true; // don't send a control character when deleting if (key == KeyDELETE) @@ -568,7 +574,7 @@ bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server) key = getKeyFromKeycode(event.xkey.keycode); server->postEvent (new CEventKeyUp (key, getKeyButton(event.xbutton.state), this)); - _PreviousKey = KeyNOKEY; + _PressedKeys[key] = false; } break; } diff --git a/code/nel/src/3d/driver/opengl/unix_event_emitter.h b/code/nel/src/3d/driver/opengl/unix_event_emitter.h index 2c5dc2de1..c6232330a 100644 --- a/code/nel/src/3d/driver/opengl/unix_event_emitter.h +++ b/code/nel/src/3d/driver/opengl/unix_event_emitter.h @@ -89,14 +89,14 @@ private: void createIM(); - Display* _dpy; - Window _win; - TKey _PreviousKey; - XIM _im; - XIC _ic; - bool _emulateRawMode; - NL3D::IDriver* _driver; - CUnixEventServer _InternalServer; + Display* _dpy; + Window _win; + std::map _PressedKeys; + XIM _im; + XIC _ic; + bool _emulateRawMode; + NL3D::IDriver* _driver; + CUnixEventServer _InternalServer; }; diff --git a/code/nel/src/3d/texture_far.cpp b/code/nel/src/3d/texture_far.cpp index bb3773f3f..151c97a8e 100644 --- a/code/nel/src/3d/texture_far.cpp +++ b/code/nel/src/3d/texture_far.cpp @@ -545,6 +545,10 @@ void CTextureFar::rebuildPatch (const CVector2s texturePos, const CPatchIdent &p // ** Fill the struct for the tile fill method for each layers NL3D_CComputeTileFar TileFar; + TileFar.SrcDiffusePixels = NULL; + TileFar.SrcAdditivePixels = NULL; + TileFar.SrcDeltaX = 0; + TileFar.SrcDeltaY = 0; TileFar.AsmMMX= false; #if defined(NL_OS_WINDOWS) && !defined(NL_NO_ASM) TileFar.AsmMMX= NLMISC::CSystemInfo::hasMMX(); diff --git a/code/nel/src/3d/zone.cpp b/code/nel/src/3d/zone.cpp index 38d6584c8..6e5763441 100644 --- a/code/nel/src/3d/zone.cpp +++ b/code/nel/src/3d/zone.cpp @@ -1411,7 +1411,7 @@ void CZone::setTileColor(bool monochrome, float factor) void CZone::debugBinds(FILE *f) { fprintf(f, "*****************************\n"); - fprintf(f, "ZoneId: %d. NPatchs:%zu\n", ZoneId, PatchConnects.size()); + fprintf(f, "ZoneId: %d. NPatchs:%u\n", ZoneId, (uint)PatchConnects.size()); sint i; for(i=0;i<(sint)PatchConnects.size();i++) { @@ -1420,10 +1420,10 @@ void CZone::debugBinds(FILE *f) for(sint j=0;j<4;j++) { CPatchInfo::CBindInfo &bd= pc.BindEdges[j]; - fprintf(f, " edge%d: Zone:%d. NPatchs:%d. ", j, bd.ZoneId, bd.NPatchs); + fprintf(f, " edge%d: Zone:%u. NPatchs:%u. ", j, (uint)bd.ZoneId, (uint)bd.NPatchs); for(sint k=0;k (zone %d) vertex %d\n",BorderVertices[i].CurrentVertex, - BorderVertices[i].NeighborZoneId, - BorderVertices[i].NeighborVertex); + fprintf(f,"current : %u -> (zone %u) vertex %u\n", (uint)BorderVertices[i].CurrentVertex, + (uint)BorderVertices[i].NeighborZoneId, + (uint)BorderVertices[i].NeighborVertex); } } diff --git a/code/nel/src/misc/i18n.cpp b/code/nel/src/misc/i18n.cpp index 093da073a..94e41a06a 100644 --- a/code/nel/src/misc/i18n.cpp +++ b/code/nel/src/misc/i18n.cpp @@ -31,13 +31,52 @@ const ucstring CI18N::_NotTranslatedValue(""); bool CI18N::_LanguagesNamesLoaded = false; string CI18N::_SelectedLanguageCode; CI18N::ILoadProxy *CI18N::_LoadProxy = 0; - +vector CI18N::_LanguageCodes; +vector CI18N::_LanguageNames; void CI18N::setLoadProxy(ILoadProxy *loadProxy) { _LoadProxy = loadProxy; } +const std::vector &CI18N::getLanguageNames() +{ + return _LanguageNames; +} + +const std::vector &CI18N::getLanguageCodes() +{ + if (!_LanguagesNamesLoaded) + { + std::vector files; + + // search all .uxt files + CPath::getFileList("uxt", files); + + // if not uxt found, use default languages + if (files.empty()) + { + _LanguageCodes.clear(); + _LanguageCodes.push_back("en"); + _LanguageCodes.push_back("fr"); + _LanguageCodes.push_back("de"); + _LanguageCodes.push_back("ru"); + } + else + { + // add all languages found + for(uint i = 0; i < files.size(); ++i) + { + _LanguageCodes.push_back(toLower(CFile::getFilenameWithoutExtension(files[i]))); + } + + _LanguagesNamesLoaded = true; + } + } + + return _LanguageCodes; +} + void CI18N::load (const string &languageCode, const string &fallbackLanguageCode) { if (_StrMapLoaded) _StrMap.clear (); diff --git a/code/nel/src/sound/audio_mixer_user.cpp b/code/nel/src/sound/audio_mixer_user.cpp index e124a09cc..7f17f9d35 100644 --- a/code/nel/src/sound/audio_mixer_user.cpp +++ b/code/nel/src/sound/audio_mixer_user.cpp @@ -177,14 +177,14 @@ void CAudioMixerUser::initClusteredSound(NL3D::CScene *scene, float minGain, flo } -void CAudioMixerUser::setPriorityReserve(TSoundPriority priorityChannel, size_t reserve) +void CAudioMixerUser::setPriorityReserve(TSoundPriority priorityChannel, uint reserve) { - _PriorityReserve[priorityChannel] = (uint32)min(_Tracks.size(), reserve); + _PriorityReserve[priorityChannel] = (uint32)min((uint)_Tracks.size(), reserve); } -void CAudioMixerUser::setLowWaterMark(size_t value) +void CAudioMixerUser::setLowWaterMark(uint value) { - _LowWaterMark = (uint32)min(_Tracks.size(), value); + _LowWaterMark = (uint32)min((uint)_Tracks.size(), value); } diff --git a/code/ryzom/client/src/interface_v3/action_handler_game.cpp b/code/ryzom/client/src/interface_v3/action_handler_game.cpp index 98decfedd..11703d5fa 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_game.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_game.cpp @@ -489,7 +489,7 @@ public: void execute (CCtrlBase * /* pCaller */, const std::string &sParams) { std::string id = getParam(sParams, "id"); - int intId; + sint intId; if (!fromString(id, intId)) return; //nlinfo("intId = %d", intId); CBotChatManager::getInstance()->incrementSessionID(); @@ -1089,7 +1089,7 @@ public: void execute (CCtrlBase * /* pCaller */, const std::string &sParams) { std::string id = getParam(sParams, "id"); - int idInDb; + sint idInDb; if (!fromString(id, idInDb)) return; CInterfaceManager *pIM= CInterfaceManager::getInstance(); diff --git a/code/ryzom/client/src/interface_v3/bot_chat_page_dynamic_mission.cpp b/code/ryzom/client/src/interface_v3/bot_chat_page_dynamic_mission.cpp index fbddbbc49..a9f9624fd 100644 --- a/code/ryzom/client/src/interface_v3/bot_chat_page_dynamic_mission.cpp +++ b/code/ryzom/client/src/interface_v3/bot_chat_page_dynamic_mission.cpp @@ -287,7 +287,7 @@ class CAHChangeDMOption : public IActionHandler virtual void execute (CCtrlBase * /* pCaller */, const string ¶ms) { //get id of choice - int id; + sint id; if (!NLMISC::fromString(getParam(params, "id"), id)) { nlwarning("Bad choice list id"); diff --git a/code/ryzom/client/src/interface_v3/group_html.cpp b/code/ryzom/client/src/interface_v3/group_html.cpp index 3ea937fa3..baad72f30 100644 --- a/code/ryzom/client/src/interface_v3/group_html.cpp +++ b/code/ryzom/client/src/interface_v3/group_html.cpp @@ -138,8 +138,10 @@ void CGroupHTML::checkImageDownload() // check msg CURLMsg *msg; int msgs_left; - while ((msg = curl_multi_info_read(MultiCurl, &msgs_left))) { - if (msg->msg == CURLMSG_DONE) { + while ((msg = curl_multi_info_read(MultiCurl, &msgs_left))) + { + if (msg->msg == CURLMSG_DONE) + { for (vector::iterator it=Curls.begin(); iteasy_handle == it->curl) @@ -2597,9 +2599,10 @@ static int timer_called = 0; static int timer_callback(HTTimer * const timer , void * const user_data , - HTEventType const event ) { + HTEventType const event ) +{ /*---------------------------------------------------------------------------- - A handy timer callback which cancels the running event loop. + A handy timer callback which cancels the running event loop. -----------------------------------------------------------------------------*/ nlassert(event == HTEvent_TIMEOUT); timer_called = 1; @@ -2610,7 +2613,8 @@ timer_callback(HTTimer * const timer , return HT_OK; } -static void handleLibwwwEvents() { +static void handleLibwwwEvents() +{ HTTimer *timer; timer_called = 0; timer = HTTimer_new(NULL, &timer_callback, NULL, diff --git a/code/ryzom/client/src/interface_v3/group_html_webig.cpp b/code/ryzom/client/src/interface_v3/group_html_webig.cpp index 393b690b6..ac866830b 100644 --- a/code/ryzom/client/src/interface_v3/group_html_webig.cpp +++ b/code/ryzom/client/src/interface_v3/group_html_webig.cpp @@ -110,7 +110,8 @@ struct CWebigNotificationThread : public NLMISC::IRunnable ~CWebigNotificationThread() { - if(Curl) { + if(Curl) + { curl_easy_cleanup(Curl); Curl = 0; } @@ -189,7 +190,8 @@ struct CWebigNotificationThread : public NLMISC::IRunnable { std::string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; std::string s; - for (int i = 0; i < 32; i++) { + for (int i = 0; i < 32; i++) + { s += chars[uint(frand(float(chars.size())))]; } return s; diff --git a/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp b/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp index 4da5550ad..cfce12775 100644 --- a/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp +++ b/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp @@ -111,7 +111,7 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity) // NB: fauna can be friend too (kami!!!) bool npcFriendAndNeutral = (entity->canHaveMissionIcon() || entity->isFauna()) && entity->isFriend (); // if the npc is an ally (outpost squad for instance) still display its bar - if(npcFriendAndNeutral) + if (npcFriendAndNeutral) npcFriendAndNeutral= npcFriendAndNeutral && !entity->isAlly(); // Window id diff --git a/code/ryzom/client/src/interface_v3/group_menu.cpp b/code/ryzom/client/src/interface_v3/group_menu.cpp index 41e150184..0c0bce9a8 100644 --- a/code/ryzom/client/src/interface_v3/group_menu.cpp +++ b/code/ryzom/client/src/interface_v3/group_menu.cpp @@ -733,8 +733,8 @@ void CGroupSubMenu::updateCoords () sint32 limY = refElmYReal + refElmHReal/2 - _GroupList->getYReal(); // Setup the arrow at the right pos - if(_GroupList->getMaxH()>=limY && limY>=0){ - + if(_GroupList->getMaxH()>=limY && limY>=0) + { pVB->setY(refElmYReal + (refElmHReal - pVB->getHReal()) / 2 - _GroupList->getYReal()); pVB->setActive(_Lines[CBLineNb].ViewText->getActive()); } diff --git a/code/ryzom/client/src/interface_v3/group_tab.cpp b/code/ryzom/client/src/interface_v3/group_tab.cpp index 8a90bfe47..33588cbb9 100644 --- a/code/ryzom/client/src/interface_v3/group_tab.cpp +++ b/code/ryzom/client/src/interface_v3/group_tab.cpp @@ -392,7 +392,8 @@ int CGroupTab::luaGetTabButton(CLuaState &ls) CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CCtrlTabButton* tab = getTabButton((uint) ls.toNumber(1)); - if(tab != NULL){ + if(tab != NULL) + { CLuaIHM::pushUIOnStack(ls, tab); return 1; } @@ -722,7 +723,8 @@ int CGroupTab::luaGetGroup(CLuaState &ls) CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CInterfaceGroup* group = getGroup((uint) ls.toNumber(1)); - if(group != NULL){ + if(group != NULL) + { CLuaIHM::pushUIOnStack(ls, group); return 1; } diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index 19bf7aa59..4247fd46a 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -2633,7 +2633,8 @@ bool CInterfaceManager::handleEvent (const CEventDescriptor& event) // Hide menu (or popup menu) is ESCAPE pressed if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == KeyESCAPE ) { - if(_ModalStack.size() > 0) { + if(_ModalStack.size() > 0) + { CModalWndInfo mwi = _ModalStack.back(); if (mwi.ModalExitKeyPushed) disableModalWindow(); @@ -5571,6 +5572,7 @@ public: { ucstr = ucstring("&EMT&") + UserEntity->getDisplayName() + ucstring(" ") + ucstr; } + out.serialEnum(behavToSend); out.serial(ucstr); NetMngr.push(out); diff --git a/code/ryzom/client/src/interface_v3/libwww_nel_stream.cpp b/code/ryzom/client/src/interface_v3/libwww_nel_stream.cpp index 4667f4c17..e89a58909 100644 --- a/code/ryzom/client/src/interface_v3/libwww_nel_stream.cpp +++ b/code/ryzom/client/src/interface_v3/libwww_nel_stream.cpp @@ -89,7 +89,8 @@ PRIVATE int FileCleanup (HTRequest *req, int status) HTStream * input = HTRequest_inputStream(req); /* Free stream with data TO Local file system */ - if (input) { + if (input) + { if (status == HT_INTERRUPTED) (*input->isa->abort)(input, NULL); else @@ -100,16 +101,19 @@ PRIVATE int FileCleanup (HTRequest *req, int status) /* ** Remove if we have registered a timer function as a callback */ - if (file->timer) { - HTTimer_delete(file->timer); - file->timer = NULL; + if (file->timer) + { + HTTimer_delete(file->timer); + file->timer = NULL; } - if (file) { - HT_FREE(file->local); - HT_FREE(file); + if (file) + { + HT_FREE(file->local); + HT_FREE(file); } - HTNet_delete(net, status); + + HTNet_delete(net, status); return YES; } @@ -181,32 +185,37 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) HTRequest * request = HTNet_request(net); HTParentAnchor * anchor = HTRequest_anchor(request); - if (type == HTEvent_CLOSE) { /* Interrupted */ - HTRequest_addError(request, ERR_FATAL, NO, HTERR_INTERRUPTED, - NULL, 0, "HTLoadFile"); - FileCleanup(request, HT_INTERRUPTED); - return HT_OK; + if (type == HTEvent_CLOSE) + { + /* Interrupted */ + HTRequest_addError(request, ERR_FATAL, NO, HTERR_INTERRUPTED, + NULL, 0, "HTLoadFile"); + FileCleanup(request, HT_INTERRUPTED); + return HT_OK; } /* Now jump into the machine. We know the state from the previous run */ - for(;;) { - switch (file->state) { + for(;;) + { + switch (file->state) + { case FS_BEGIN: /* We only support safe (GET, HEAD, etc) methods for the moment */ if (!HTMethod_isSafe(HTRequest_method(request))) { HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_ALLOWED, - NULL, 0, "HTLoadFile"); + NULL, 0, (char*)"HTLoadFile"); file->state = FS_ERROR; break; } /* Check whether we have access to local disk at all */ - if (HTLib_secure()) { - HTTRACE(PROT_TRACE, "LoadFile.... No access to local file system\n"); - file->state = FS_TRY_FTP; - break; + if (HTLib_secure()) + { + HTTRACE(PROT_TRACE, "LoadFile.... No access to local file system\n"); + file->state = FS_TRY_FTP; + break; } /*file->local = HTWWWToLocal(HTAnchor_physical(anchor), "", @@ -220,15 +229,16 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) StrAllocCopy(file->local, tmp.c_str()); } - if (!file->local) { - file->state = FS_TRY_FTP; - break; + if (!file->local) + { + file->state = FS_TRY_FTP; + break; } /* Create a new host object and link it to the net object */ { HTHost * host = NULL; - if ((host = HTHost_new("localhost", 0)) == NULL) return HT_ERROR; + if ((host = HTHost_new((char*)"localhost", 0)) == NULL) return HT_ERROR; HTNet_setHost(net, host); if (HTHost_addNet(host, net) == HT_PENDING) { HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n"); @@ -243,7 +253,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) case FS_PENDING: { HTHost * host = NULL; - if ((host = HTHost_new("localhost", 0)) == NULL) return HT_ERROR; + if ((host = HTHost_new((char*)"localhost", 0)) == NULL) return HT_ERROR; HTNet_setHost(net, host); if (HTHost_addNet(host, net) == HT_PENDING) { HTTRACE(PROT_TRACE, "HTLoadFile.. Pending...\n"); @@ -265,7 +275,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) if (HT_STAT(file->local, &file->stat_info) == -1) { HTTRACE(PROT_TRACE, "Load File... Not found `%s\'\n" _ file->local); HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_FOUND, - NULL, 0, "HTLoadFile"); + NULL, 0, (char*)"HTLoadFile"); file->state = FS_ERROR; break; } @@ -276,7 +286,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) file->state = FS_PARSE_DIR; else { HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT, - NULL, 0, "HTLoadFile"); + NULL, 0, (char*)"HTLoadFile"); file->state = FS_NO_DATA; } break; @@ -305,7 +315,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) /* Check to see if we can edit it */ if (!editable && !file->stat_info.st_size) { HTRequest_addError(request, ERR_INFO, NO, HTERR_NO_CONTENT, - NULL, 0, "HTLoadFile"); + NULL, 0, (char*)"HTLoadFile"); file->state = FS_NO_DATA; } else { file->state = (HTRequest_method(request)==METHOD_GET) ? @@ -334,7 +344,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) if (HTRequest_isSource(request) && !HTRequest_destinationsReady(request)) return HT_OK; HTRequest_addError(request, ERR_INFO, NO, HTERR_OK, NULL, 0, - "HTLoadFile"); + (char*)"HTLoadFile"); file->state = FS_NEED_BODY; if (HTEvent_isCallbacksRegistered()) { @@ -354,7 +364,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) return HT_OK; else { HTRequest_addError(request, ERR_INFO, NO, HTERR_INTERNAL, - NULL, 0, "HTLoadFile"); + NULL, 0, (char*)"HTLoadFile"); file->state = FS_ERROR; /* Error or interrupt */ } break; @@ -367,7 +377,7 @@ PRIVATE int FileEvent (SOCKET /* soc */, void * pVoid, HTEventType type) file->state = FS_GOT_DATA; } else { HTRequest_addError(request, ERR_INFO, NO, HTERR_FORBIDDEN, - NULL, 0, "HTLoadFile"); + NULL, 0, (char*)"HTLoadFile"); file->state = FS_ERROR; } break; @@ -550,7 +560,7 @@ PRIVATE int HTNeLReader_abort (HTInputStream * me, HTList * /* e */) PRIVATE const HTInputStreamClass HTNeLReader = { - "SocketReader", + (char*)"SocketReader", HTNeLReader_flush, HTNeLReader_free, HTNeLReader_abort, diff --git a/code/ryzom/client/src/interface_v3/people_list.h b/code/ryzom/client/src/interface_v3/people_list.h index fd7ffbbcd..caa7167cd 100644 --- a/code/ryzom/client/src/interface_v3/people_list.h +++ b/code/ryzom/client/src/interface_v3/people_list.h @@ -167,4 +167,4 @@ private: virtual void childrenMoved(uint srcIndex, uint destIndex, CGroupContainer *children); }; -#endif \ No newline at end of file +#endif diff --git a/code/ryzom/client/src/seven_zip/LzmaDecode.cpp b/code/ryzom/client/src/seven_zip/LzmaDecode.cpp index d66ec3589..97c02fa98 100644 --- a/code/ryzom/client/src/seven_zip/LzmaDecode.cpp +++ b/code/ryzom/client/src/seven_zip/LzmaDecode.cpp @@ -581,4 +581,4 @@ int LzmaDecode(CLzmaDecoderState *vs, #endif *outSizeProcessed = nowPos; return LZMA_RESULT_OK; -} \ No newline at end of file +} diff --git a/code/ryzom/client/src/string_manager_client.cpp b/code/ryzom/client/src/string_manager_client.cpp index 38482c6d7..72604df73 100644 --- a/code/ryzom/client/src/string_manager_client.cpp +++ b/code/ryzom/client/src/string_manager_client.cpp @@ -115,12 +115,11 @@ namespace STRING_MANAGER { try { - std::string filename(_ShardId.substr(0, _ShardId.find(":")) + ".string_cache"); + _CacheFilename = std::string("save/") + _ShardId.substr(0, _ShardId.find(":")) + ".string_cache"; - nlinfo("SM : Try to open the string cache : %s", filename.c_str()); + nlinfo("SM : Try to open the string cache : %s", _CacheFilename.c_str()); - _CacheFilename = NLMISC::CPath::lookup(filename, false, false); - if (!_CacheFilename .empty()) + if (CFile::fileExists(_CacheFilename)) { // there is a cache file, check date reset it if needed { @@ -143,7 +142,6 @@ namespace STRING_MANAGER else { nlinfo("SM: Creating string cache"); - _CacheFilename = std::string("data/")+filename; // cache file don't exist, create it with the timestamp NLMISC::COFile file(_CacheFilename); file.serial(timestamp); diff --git a/code/ryzom/client/src/user_entity.cpp b/code/ryzom/client/src/user_entity.cpp index 57031e84b..cfc661620 100644 --- a/code/ryzom/client/src/user_entity.cpp +++ b/code/ryzom/client/src/user_entity.cpp @@ -1994,7 +1994,7 @@ void CUserEntity::updatePos(const TTime &t, CEntityCL *target) // Compute the Time Step. double frameTimeRemaining = computeTimeStep(((double)t)*0.001); // Do not update animation if Client Light - if(ClientCfg.Light == false) + if (!ClientCfg.Light) { // Attack Animation. if(_AnimAttackOn) diff --git a/code/ryzom/server/src/entities_game_service/entities_game_service.vcproj b/code/ryzom/server/src/entities_game_service/entities_game_service.vcproj index f4dedb73d..c75454117 100644 --- a/code/ryzom/server/src/entities_game_service/entities_game_service.vcproj +++ b/code/ryzom/server/src/entities_game_service/entities_game_service.vcproj @@ -1,7 +1,7 @@ maxLength) + { + ucstr = ucstr.luabind_substr(length - maxLength - 3); + nstr = std::string("...") + ucstr.toUtf8(); + length = maxLength; + } } else { - length = (uint)str.length(); + length = (uint)nstr.length(); + if (length > maxLength) + { + nstr = std::string("...") + nstr.substr(length - maxLength - 3); + length = maxLength; + } } - sint diff = length - previousLength; - - if (diff > 0 && length < maxLength) - { - memset(spaces, ' ', length); - spaces[length] = '\0'; - - // "erase" previous line - printf("%s\r", spaces); - fflush(stdout); - } + // add padding with spaces + memset(spaces, ' ', maxLength); + spaces[maxLength - length] = '\0'; // display download in purple if (useEsc) { - printf("\033[1;35m%s\033[0m\r", str.c_str()); + printf("\033[1;35m%s%s\033[0m\r", nstr.c_str(), spaces); } else { @@ -120,17 +134,15 @@ void printDownload(const std::string &str) SetConsoleTextAttribute(hStdout, FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY); #endif - printf("%s\r", str.c_str()); + printf("%s%s\r", nstr.c_str(), spaces); #ifdef NL_OS_WINDOWS if (hStdout != INVALID_HANDLE_VALUE && hStdout) SetConsoleTextAttribute(hStdout, attributes); #endif } - - fflush(stdout); - previousLength = length; + fflush(stdout); } int main(int argc, char *argv[]) @@ -168,7 +180,7 @@ int main(int argc, char *argv[]) std::string lang = toLower(std::string(setlocale(LC_CTYPE, ""))); useUtf8 = (lang.find("utf8") != string::npos || lang.find("utf-8") != string::npos); lang = lang.substr(0, 2); - + // check if console supports colors std::string term = toLower(std::string(getenv("TERM") ? getenv("TERM"):"")); useEsc = (term.find("xterm") != string::npos || term.find("linux") != string::npos);