From e3347276b5aa8197162954b9006296320c858eb5 Mon Sep 17 00:00:00 2001 From: Martin Natano Date: Sat, 19 Mar 2022 20:28:15 +0100 Subject: [PATCH] Build LoadingWindow_Gtk as an object module CMake object modules have the advantage of allowing to set additional compile flags for the involved files, but it's linked into the main binary with the rest of the object files. This removes GtkModule.so and the dynamic loading code that goes with it. --- .gitignore | 1 - Build/INSTALL.md | 4 +- Utils/install-stepmania.pl | 4 - src/CMakeData-arch.cmake | 7 +- src/CMakeData-gtk.cmake | 51 ++---- src/CMakeLists.txt | 5 - src/arch/LoadingWindow/LoadingWindow_Gtk.cpp | 155 +++++++++++------- .../LoadingWindow/LoadingWindow_GtkModule.cpp | 153 ----------------- .../LoadingWindow/LoadingWindow_GtkModule.h | 39 ----- 9 files changed, 116 insertions(+), 303 deletions(-) delete mode 100644 src/arch/LoadingWindow/LoadingWindow_GtkModule.cpp delete mode 100644 src/arch/LoadingWindow/LoadingWindow_GtkModule.h diff --git a/.gitignore b/.gitignore index 92bf5a7fe8..9c154549b6 100644 --- a/.gitignore +++ b/.gitignore @@ -107,7 +107,6 @@ src/Makefile src/config.h src/config.h.in src/stamp-h1 -GtkModule.so StepMania core diff --git a/Build/INSTALL.md b/Build/INSTALL.md index 9b051cecd8..43b5351aca 100644 --- a/Build/INSTALL.md +++ b/Build/INSTALL.md @@ -17,8 +17,8 @@ Using Xcode, simply build in Xcode and it will place the .app file in the correc Linux === -Using the command line, simply type make and it will place stepmania and GtkModule.so -(if requested) in the root StepMania directory. There is no more need to symlink the files. +Using the command line, simply type make and it will place stepmania in the root StepMania +directory. There is no more need to symlink the files. Installing StepMania == diff --git a/Utils/install-stepmania.pl b/Utils/install-stepmania.pl index 92528d1f07..03945e73cd 100644 --- a/Utils/install-stepmania.pl +++ b/Utils/install-stepmania.pl @@ -240,7 +240,3 @@ $FoundSection || print "warning: SectionEnd not found\n"; close F; system("cp -vp \"" . $bin_path . "stepmania5\" \"$instdir\""); -if( -e $bin_path . "GtkModule.so" ) -{ - system("cp -vp \"" . $bin_path . "GtkModule.so\" \"$instdir\""); -} diff --git a/src/CMakeData-arch.cmake b/src/CMakeData-arch.cmake index 3d695d8397..c0e31a7f0a 100644 --- a/src/CMakeData-arch.cmake +++ b/src/CMakeData-arch.cmake @@ -185,12 +185,7 @@ else() list(APPEND SMDATA_ARCH_LOADING_HPP "arch/LoadingWindow/LoadingWindow_MacOSX.h") elseif(LINUX) - if(GTK3_FOUND) - list(APPEND SMDATA_ARCH_LOADING_SRC - "arch/LoadingWindow/LoadingWindow_Gtk.cpp") - list(APPEND SMDATA_ARCH_LOADING_HPP - "arch/LoadingWindow/LoadingWindow_Gtk.h") - endif() + include(CMakeData-gtk.cmake) endif() endif() diff --git a/src/CMakeData-gtk.cmake b/src/CMakeData-gtk.cmake index 80a3817f20..3483157727 100644 --- a/src/CMakeData-gtk.cmake +++ b/src/CMakeData-gtk.cmake @@ -2,40 +2,25 @@ if(NOT GTK3_FOUND) return() endif() -add_library("GtkModule" - SHARED - "arch/LoadingWindow/LoadingWindow_GtkModule.cpp" - "arch/LoadingWindow/LoadingWindow_GtkModule.h") +add_library("LoadingWindowGtk" + OBJECT + "arch/LoadingWindow/LoadingWindow_Gtk.cpp" + "arch/LoadingWindow/LoadingWindow_Gtk.h") -sm_add_compile_flag("GtkModule" "-std=${SM_CPP_STANDARD}") +set_property(TARGET "LoadingWindowGtk" PROPERTY FOLDER "Internal Libraries") +set_property(TARGET "LoadingWindowGtk" PROPERTY CXX_STANDARD 11) +set_property(TARGET "LoadingWindowGtk" PROPERTY CXX_STANDARD_REQUIRED ON) +set_property(TARGET "LoadingWindowGtk" PROPERTY CXX_EXTENSIONS ON) -# It is normally not appropriate to set the prefix to the empty string. This is -# to maintain compatibility with the current source. At some point, it may be -# worth being more flexible. -set_target_properties("GtkModule" PROPERTIES PREFIX "") -set_target_properties("GtkModule" PROPERTIES OUTPUT_NAME "GtkModule") -set_target_properties("GtkModule" - PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${SM_ROOT_DIR}") -set_target_properties("GtkModule" - PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE - "${SM_ROOT_DIR}") -set_target_properties( - "GtkModule" - PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG "${SM_ROOT_DIR}") -set_target_properties("GtkModule" - PROPERTIES LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL - "${SM_ROOT_DIR}") -set_target_properties("GtkModule" - PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO - "${SM_ROOT_DIR}") -target_link_libraries("GtkModule" ${GTK3_LIBRARIES}) -set_property(TARGET "GtkModule" PROPERTY FOLDER "Internal Libraries") -list(APPEND SM_GTK_INCLUDE_DIRS - "${SM_SRC_DIR}" - "${SM_SRC_DIR}/generated" - "${SM_SRC_DIR}/arch/LoadingWindow" - "${GTK3_INCLUDE_DIRS}") +target_include_directories("LoadingWindowGtk" PRIVATE "${SM_SRC_DIR}" + "${SM_SRC_DIR}/generated" + "${SM_SRC_DIR}/arch/LoadingWindow" + "${GTK3_INCLUDE_DIRS}") -sm_add_compile_definition("GtkModule" CMAKE_POWERED) +target_link_libraries("LoadingWindowGtk" ${GTK3_LIBRARIES}) -target_include_directories("GtkModule" PUBLIC ${SM_GTK_INCLUDE_DIRS}) +target_compile_definitions("LoadingWindowGtk" PRIVATE CMAKE_POWERED) + +list(APPEND SMDATA_LINK_LIB "LoadingWindowGtk") +list(APPEND SMDATA_ARCH_LOADING_HPP + "arch/LoadingWindow/LoadingWindow_Gtk.h") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 286a6c0986..66f052ef00 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,7 +22,6 @@ include(CMakeData-os.cmake) include(CMakeData-actor.cmake) include(CMakeData-screen.cmake) include(CMakeData-data.cmake) -include(CMakeData-gtk.cmake) include(CMakeData-file-types.cmake) include(CMakeData-globals.cmake) include(CMakeData-singletons.cmake) @@ -766,10 +765,6 @@ if(NOT APPLE) else() install(TARGETS "${SM_EXE_NAME}" DESTINATION "${SM_INSTALL_DESTINATION}") endif() - if(UNIX OR LINUX) - install(FILES "${SM_ROOT_DIR}/GtkModule.so" - LIBRARY DESTINATION "${SM_INSTALL_DESTINATION}" OPTIONAL) - endif() install(DIRECTORY "${SM_ROOT_DIR}/Announcers" DESTINATION "${SM_INSTALL_DESTINATION}") install(DIRECTORY "${SM_ROOT_DIR}/BGAnimations" diff --git a/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp b/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp index 4fb976fc98..546be7e1f9 100644 --- a/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp +++ b/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp @@ -1,114 +1,149 @@ #include "global.h" -#include "RageLog.h" -#include "RageFileManager.h" #include "RageUtil.h" +#include "RageSurface.h" +#include "RageSurfaceUtils.h" +#include "RageSurface_Load.h" #include "LoadingWindow_Gtk.h" -#include "LoadingWindow_GtkModule.h" -#include +#include -static void *Handle = nullptr; -static INIT Module_Init; -static SHUTDOWN Module_Shutdown; -static SETTEXT Module_SetText; -static SETICON Module_SetIcon; -static SETSPLASH Module_SetSplash; -static SETPROGRESS Module_SetProgress; -static SETINDETERMINATE Module_SetIndeterminate; +static GtkWidget *label; +static GtkWidget *window; +static GtkWidget *splash; +static GtkWidget *progressBar; LoadingWindow_Gtk::LoadingWindow_Gtk() { } -static RString ModuleError( const RString s ) -{ - return ssprintf( "Couldn't load symbol Module_%s", s.c_str() ); -} - RString LoadingWindow_Gtk::Init() { - ASSERT( Handle == nullptr ); + // Need to use external library to load this image. Native loader seems broken :/ + const gchar *splash_image_path = "Data/splash.png"; + GtkWidget *vbox; - Handle = dlopen( RageFileManagerUtil::sDirOfExecutable + "/" + "GtkModule.so", RTLD_NOW ); - if( Handle == nullptr ) - return ssprintf( "dlopen(): %s", dlerror() ); + gtk_disable_setlocale(); + if( !gtk_init_check(&g_argc, &g_argv) ) + return "Couldn't initialize gtk (cannot open display)"; - Module_Init = (INIT) dlsym(Handle, "Init"); - if( !Module_Init ) - return ModuleError("Init"); + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_position( GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS ); + gtk_widget_set_size_request(window,-1,-1); + gtk_window_set_deletable( GTK_WINDOW(window), FALSE ); + gtk_window_set_resizable(GTK_WINDOW(window),FALSE); + gtk_window_set_role( GTK_WINDOW(window), "sm-startup" ); + //gtk_window_set_icon( GTK_WINDOW(window), ); + gtk_widget_realize(window); - Module_Shutdown = (SHUTDOWN) dlsym(Handle, "Shutdown"); - if( !Module_Shutdown ) - return ModuleError("Shutdown"); + splash = gtk_image_new_from_pixbuf( + gdk_pixbuf_new_from_file (splash_image_path, nullptr) + ); - Module_SetText = (SETTEXT) dlsym(Handle, "SetText"); - if( !Module_SetText ) - return ModuleError("SetText"); + label = gtk_label_new(nullptr); + gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_CENTER); + gtk_label_set_ellipsize(GTK_LABEL(label),PANGO_ELLIPSIZE_END); + gtk_label_set_line_wrap(GTK_LABEL(label),FALSE); - Module_SetIcon = (SETICON) dlsym(Handle, "SetIcon"); - if( !Module_SetIcon ) - return ModuleError("SetIcon"); + progressBar = gtk_progress_bar_new(); + gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), 0.0 ); - Module_SetSplash = (SETSPLASH) dlsym(Handle, "SetSplash"); - if( !Module_SetSplash ) - return ModuleError("SetSplash"); + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add(GTK_CONTAINER(window),vbox); + gtk_box_pack_start(GTK_BOX(vbox),splash,FALSE,FALSE,0); + gtk_box_pack_end(GTK_BOX(vbox),progressBar,FALSE,FALSE,0); + gtk_box_pack_end(GTK_BOX(vbox),label,TRUE,TRUE,0); - Module_SetProgress = (SETPROGRESS) dlsym(Handle, "SetProgress"); - if( !Module_SetProgress ) - return ModuleError("SetProgress"); - - Module_SetIndeterminate = (SETINDETERMINATE) dlsym(Handle, "SetIndeterminate"); - if( !Module_SetIndeterminate ) - return ModuleError("SetIndeterminate"); - - const char *ret = Module_Init( &g_argc, &g_argv ); - if( ret != nullptr ) - return ret; + gtk_widget_show_all(window); + gtk_main_iteration_do(FALSE); return ""; } LoadingWindow_Gtk::~LoadingWindow_Gtk() { - if( Module_Shutdown != nullptr ) - Module_Shutdown(); - Module_Shutdown = nullptr; - - if( Handle ) - dlclose( Handle ); - Handle = nullptr; + gtk_widget_hide(window); + g_signal_emit_by_name (G_OBJECT (window), "destroy"); + while( gtk_events_pending() ) + gtk_main_iteration_do(FALSE); } void LoadingWindow_Gtk::SetText( RString s ) { - Module_SetText( s ); + gtk_label_set_text(GTK_LABEL(label), s); + gtk_widget_show(label); + gtk_main_iteration_do(FALSE); +} + +static void DeletePixels( guchar *pixels, gpointer data ) +{ + delete[] (uint8_t *)pixels; +} + +static GdkPixbuf *MakePixbuf( const RageSurface *pSrc ) +{ + RageSurface *pSurface = CreateSurface( pSrc->w, pSrc->h, 32, + 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 ); + RageSurfaceUtils::Blit( pSrc, pSurface , -1, -1 ); + + GdkPixbuf *pBuf = gdk_pixbuf_new_from_data( pSurface->pixels, GDK_COLORSPACE_RGB, + true, 8, pSurface->w, pSurface->h , pSurface->pitch, DeletePixels, nullptr); + + if( pBuf != nullptr ) + pSurface->pixels_owned = false; + + delete pSurface; + return pBuf; } void LoadingWindow_Gtk::SetIcon( const RageSurface *pIcon ) { - Module_SetIcon( pIcon ); + GdkPixbuf *pBuf = MakePixbuf( pIcon ); + if( pBuf != nullptr ) + { + gtk_window_set_icon( GTK_WINDOW(window), pBuf ); + g_object_unref(pBuf); + } + gtk_main_iteration_do(FALSE); } void LoadingWindow_Gtk::SetSplash( const RageSurface *pSplash ) { - Module_SetSplash( pSplash ); + GdkPixbuf *pBuf = MakePixbuf( pSplash ); + if( pBuf != nullptr ) + { + gtk_image_set_from_pixbuf(GTK_IMAGE(splash), pBuf); + g_object_unref(pBuf); + } + gtk_main_iteration_do(FALSE); +} + +static void UpdateProgress( int progress, int totalWork ) +{ + gdouble fraction = ( totalWork > 0 ? progress / (gdouble)totalWork : 0 ); + if( fraction > 1.0 ) fraction = 1.0; + if( fraction < 0.0 ) fraction = 0.0; + gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), fraction ); + gtk_main_iteration_do(FALSE); } void LoadingWindow_Gtk::SetProgress( const int progress ) { LoadingWindow::SetProgress( progress ); - Module_SetProgress( m_progress, m_totalWork ); + UpdateProgress( m_progress, m_totalWork ); } void LoadingWindow_Gtk::SetTotalWork( const int totalWork ) { LoadingWindow::SetTotalWork( totalWork ); - Module_SetProgress( m_progress, m_totalWork ); + UpdateProgress( m_progress, m_totalWork ); + } void LoadingWindow_Gtk::SetIndeterminate( bool indeterminate ) { LoadingWindow::SetIndeterminate( indeterminate ); - Module_SetIndeterminate( m_indeterminate ); + + gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progressBar)); + gtk_main_iteration_do(FALSE); } /* diff --git a/src/arch/LoadingWindow/LoadingWindow_GtkModule.cpp b/src/arch/LoadingWindow/LoadingWindow_GtkModule.cpp deleted file mode 100644 index af0cce7ed0..0000000000 --- a/src/arch/LoadingWindow/LoadingWindow_GtkModule.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include "global.h" -#include "LoadingWindow_GtkModule.h" -#include "RageUtil.h" -#include "RageSurface.h" -#include "RageSurfaceUtils.h" -#include "RageSurface_Load.h" - -#include - -static GtkWidget *label; -static GtkWidget *window; -static GtkWidget *splash; -static GtkWidget *progressBar; - -extern "C" const char *Init( int *argc, char ***argv ) -{ - // Need to use external library to load this image. Native loader seems broken :/ - const gchar *splash_image_path = "Data/splash.png"; - GtkWidget *vbox; - - gtk_disable_setlocale(); - if( !gtk_init_check(argc,argv) ) - return "Couldn't initialize gtk (cannot open display)"; - - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_position( GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS ); - gtk_widget_set_size_request(window,-1,-1); - gtk_window_set_deletable( GTK_WINDOW(window), FALSE ); - gtk_window_set_resizable(GTK_WINDOW(window),FALSE); - gtk_window_set_role( GTK_WINDOW(window), "sm-startup" ); - //gtk_window_set_icon( GTK_WINDOW(window), ); - gtk_widget_realize(window); - - splash = gtk_image_new_from_pixbuf( - gdk_pixbuf_new_from_file (splash_image_path, nullptr) - ); - - label = gtk_label_new(nullptr); - gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_CENTER); - gtk_label_set_ellipsize(GTK_LABEL(label),PANGO_ELLIPSIZE_END); - gtk_label_set_line_wrap(GTK_LABEL(label),FALSE); - - progressBar = gtk_progress_bar_new(); - gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), 0.0 ); - - vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - gtk_container_add(GTK_CONTAINER(window),vbox); - gtk_box_pack_start(GTK_BOX(vbox),splash,FALSE,FALSE,0); - gtk_box_pack_end(GTK_BOX(vbox),progressBar,FALSE,FALSE,0); - gtk_box_pack_end(GTK_BOX(vbox),label,TRUE,TRUE,0); - - gtk_widget_show_all(window); - gtk_main_iteration_do(FALSE); - return nullptr; -} - -extern "C" void Shutdown() -{ - gtk_widget_hide(window); - g_signal_emit_by_name (G_OBJECT (window), "destroy"); - while( gtk_events_pending() ) - gtk_main_iteration_do(FALSE); -} - -extern "C" void SetText( const char *s ) -{ - gtk_label_set_text(GTK_LABEL(label), s); - gtk_widget_show(label); - gtk_main_iteration_do(FALSE); -} - -void DeletePixels( guchar *pixels, gpointer data ) -{ - delete[] (uint8_t *)pixels; -} - -GdkPixbuf *MakePixbuf( const RageSurface *pSrc ) -{ - RageSurface *pSurface = CreateSurface( pSrc->w, pSrc->h, 32, - 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 ); - RageSurfaceUtils::Blit( pSrc, pSurface , -1, -1 ); - - GdkPixbuf *pBuf = gdk_pixbuf_new_from_data( pSurface->pixels, GDK_COLORSPACE_RGB, - true, 8, pSurface->w, pSurface->h , pSurface->pitch, DeletePixels, nullptr); - - if( pBuf != nullptr ) - pSurface->pixels_owned = false; - - delete pSurface; - return pBuf; -} - -extern "C" void SetIcon( const RageSurface *pSrcImg ) -{ - GdkPixbuf *pBuf = MakePixbuf( pSrcImg ); - if( pBuf != nullptr ) - { - gtk_window_set_icon( GTK_WINDOW(window), pBuf ); - g_object_unref(pBuf); - } - gtk_main_iteration_do(FALSE); -} - -extern "C" void SetSplash( const RageSurface *pSplash ) -{ - GdkPixbuf *pBuf = MakePixbuf( pSplash ); - if( pBuf != nullptr ) - { - gtk_image_set_from_pixbuf(GTK_IMAGE(splash), pBuf); - g_object_unref(pBuf); - } - gtk_main_iteration_do(FALSE); -} - -extern "C" void SetProgress( int progress, int totalWork ) -{ - gdouble fraction = ( totalWork > 0 ? progress / (gdouble)totalWork : 0 ); - if( fraction > 1.0 ) fraction = 1.0; - if( fraction < 0.0 ) fraction = 0.0; - gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), fraction ); - gtk_main_iteration_do(FALSE); -} - -extern "C" void SetIndeterminate( bool indeterminate ) -{ - gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progressBar)); - gtk_main_iteration_do(FALSE); -} - -/* - * (c) 2003-2004 Glenn Maynard, Sean Burke - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ diff --git a/src/arch/LoadingWindow/LoadingWindow_GtkModule.h b/src/arch/LoadingWindow/LoadingWindow_GtkModule.h deleted file mode 100644 index 2dcbfbd69f..0000000000 --- a/src/arch/LoadingWindow/LoadingWindow_GtkModule.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef LOADING_WINDOW_MODULE_GTK -#define LOADING_WINDOW_MODULE_GTK - -struct RageSurface; - -typedef const char *(*INIT)(int *argc, char ***argv); -typedef void (*SHUTDOWN)(); -typedef void (*SETTEXT)( const char *s ); -typedef void (*SETICON)( const RageSurface *pSrcImg ); -typedef void (*SETSPLASH)( const RageSurface *pSplash ); -typedef void (*SETPROGRESS)( int progress, int totalWork ); -typedef void (*SETINDETERMINATE)( bool indeterminate ); - -#endif - -/* - * (c) 2003-2004 Glenn Maynard, Sean Burke - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */