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. - */