Skip to content

Commit 4a011f7

Browse files
committed
Install paths, config files.
1 parent 87f6807 commit 4a011f7

9 files changed

+169
-30
lines changed

CMakeLists.txt

+49-3
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,64 @@ set(CMAKE_POSITION_INDEPENDENT_CODE YES)
66

77
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
88

9-
project(projectM-SDL
9+
project(projectMSDL
1010
LANGUAGES C CXX
1111
VERSION 2.0.0
1212
)
1313

1414
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
1515

16+
# Default install layouts.
17+
option(ENABLE_FLAT_PACKAGE "Creates a \"flat\" install layout with files and preset/texture dirs directly in the main dir." OFF)
18+
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT ENABLE_FLAT_PACKAGE)
19+
include(GNUInstallDirs)
20+
21+
set(PROJECTMSDL_BIN_DIR "${CMAKE_INSTALL_BINDIR}" CACHE STRING "Directory to install executables in, relative to the install prefix.")
22+
set(PROJECTMSDL_LIB_DIR "${CMAKE_INSTALL_LIBDIR}" CACHE STRING "Directory to install additional libraries in, relative to the install prefix.")
23+
set(PROJECTMSDL_DATA_DIR "${CMAKE_INSTALL_DATAROOTDIR}/${CMAKE_PROJECT_NAME}" CACHE STRING "Directory to install the config file, presets and texture, relative to the install prefix.")
24+
set(PROJECTMSDL_PRESETS_DIR "${PROJECTMSDL_DATA_DIR}/presets" CACHE STRING "Directory to install optional preset files, relative to the install prefix.")
25+
set(PROJECTMSDL_TEXTURES_DIR "${PROJECTMSDL_DATA_DIR}/textures" CACHE STRING "Directory to install optional texture files, relative to the install prefix.")
26+
27+
# Additional options for desktop integration
28+
option(ENABLE_DESKTOP_ICON "Install a .desktop file and icons" ON)
29+
set(PROJECTMSDL_DESKTOP_DIR "${CMAKE_INSTALL_DATAROOTDIR}/applications" CACHE STRING "Directory to install the .desktop file in, relative to the install prefix.")
30+
set(PROJECTMSDL_ICONS_DIR "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor" CACHE STRING "Directory to install the icons in, relative to the install prefix.")
31+
32+
GNUInstallDirs_get_absolute_install_dir(_config_dir_abs_init PROJECTMSDL_CONFIG_DIR DATAROOTDIR)
33+
set(DEFAULT_CONFIG_PATH "${_config_dir_abs_init}" CACHE STRING "Optional path to look for the configuration file in addition to PROJECTMSDL_BIN_DIR.")
34+
set(DEFAULT_PRESETS_PATH "${_config_dir_abs_init}/presets" CACHE STRING "Default presets path in the configuration file.")
35+
set(DEFAULT_TEXTURES_PATH "${_config_dir_abs_init}/textures" CACHE STRING "Default textures path in the configuration file.")
36+
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT ENABLE_FLAT_PACKAGE)
37+
# Package as .app bundle on macOS
38+
set(BUNDLE_BASE_DIR "projectM.app/Contents")
39+
set(PROJECTMSDL_BIN_DIR "${BUNDLE_BASE_DIR}/MacOS" CACHE STRING "Directory to install executables in, relative to the install prefix.")
40+
set(PROJECTMSDL_LIB_DIR "${BUNDLE_BASE_DIR}/PlugIns" CACHE STRING "Directory to install additional libraries in, relative to the install prefix.")
41+
set(PROJECTMSDL_DATA_DIR "{BUNDLE_BASE_DIR}/Resources" CACHE STRING "Directory to install the config file, presets and texture, relative to the install prefix.")
42+
set(PROJECTMSDL_PRESETS_DIR "${PROJECTMSDL_DATA_DIR}/Presets" CACHE STRING "Directory to install optional preset files, relative to the install prefix.")
43+
set(PROJECTMSDL_TEXTURES_DIR "${PROJECTMSDL_DATA_DIR}/Textures" CACHE STRING "Directory to install optional texture files, relative to the install prefix.")
44+
45+
set(DEFAULT_CONFIG_PATH "\${application.dir}/../Resources" CACHE STRING "Optional path to look for the configuration file in addition to PROJECTMSDL_BIN_DIR.")
46+
set(DEFAULT_PRESETS_PATH "\${application.dir}/../Resources/Presets" CACHE STRING "Default presets path in the configuration file.")
47+
set(DEFAULT_TEXTURES_PATH "\${application.dir}/../Resources/Presets" CACHE STRING "Default textures path in the configuration file.")
48+
else()
49+
# Windows and others: use flat layout.
50+
set(PROJECTMSDL_BIN_DIR "." CACHE STRING "Directory to install executables in, relative to the install prefix.")
51+
set(PROJECTMSDL_LIB_DIR "." CACHE STRING "Directory to install additional libraries in, relative to the install prefix.")
52+
set(PROJECTMSDL_DATA_DIR "." CACHE STRING "Directory to install the config file, presets and texture, relative to the install prefix.")
53+
set(PROJECTMSDL_PRESETS_DIR "${PROJECTMSDL_DATA_DIR}/presets" CACHE STRING "Directory to install optional preset files, relative to the install prefix.")
54+
set(PROJECTMSDL_TEXTURES_DIR "${PROJECTMSDL_DATA_DIR}/textures" CACHE STRING "Directory to install optional texture files, relative to the install prefix.")
55+
56+
set(DEFAULT_CONFIG_PATH "" CACHE STRING "Optional path to look for the configuration file in addition to PROJECTMSDL_BIN_DIR.")
57+
set(DEFAULT_PRESETS_PATH "\${application.dir}/presets" CACHE STRING "Default presets path in the configuration file.")
58+
set(DEFAULT_TEXTURES_PATH "\${application.dir}/textures" CACHE STRING "Default textures path in the configuration file.")
59+
endif()
60+
1661
set(SDL2_LINKAGE "shared" CACHE STRING "Set to either shared or static to specify how libSDL2 should be linked. Defaults to shared.")
1762
option(ENABLE_FREETYPE "Use the Freetype font rendering library instead of the built-in stb_truetype if available" ON)
1863

19-
set(DEFAULT_PRESETS_PATH "\${application.dir}/presets" CACHE STRING "Default presets path in the configuration file.")
20-
set(DEFAULT_TEXTURES_PATH "\${application.dir}/textures" CACHE STRING "Default textures path in the configuration file.")
64+
65+
set(PRESET_DIRS "" CACHE STRING "List of paths with presets. Will be installed in \"presets\" ")
66+
set(TEXTURE_DIRS "" CACHE STRING "List of paths with presets.")
2167

2268
if(NOT SDL2_LINKAGE STREQUAL "shared" AND NOT SDL2_LINKAGE STREQUAL "static")
2369
message(FATAL_ERROR "Invalid libSDL2 linkage provided in SDL2_LINKAGE: \"${SDL2_LINKAGE}\".\n"

README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@ and `sudo make install` [libprojectM](https://github.com/projectM-visualizer/pro
1616

1717
### Dependencies
1818

19-
This project requires two third-party libraries in addition to libprojectM's core library dependencies:
19+
This project requires third-party libraries in addition to libprojectM's core library dependencies:
2020

2121
- SDL2 (version 2.0.16 or higher)
22-
- POCO (version 1.12 or higher)
22+
- POCO (recommended version 1.12 or higher, minimum is 1.9.x)
23+
- Freetype 2 (optional, will provide better looking UI text)
24+
25+
**Important**: projectMSDL will _not compile_ against Poco versions from 1.10.0 up to 1.11.1, as these versions of Poco
26+
include a serious issue that causes the application to crash. Either use Poco 1.9.x, or upgrade to 1.11.2 or higher.
2327

2428
Depending on your needs, you can either build them yourself or install them using your favorite package manager. Here
2529
are some examples for the three major desktop platforms:

install.cmake

+52-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,57 @@
1-
# ToDo: Make directory structure configurable
21
install(TARGETS projectMSDL
3-
RUNTIME DESTINATION .
2+
RUNTIME DESTINATION ${PROJECTMSDL_BIN_DIR}
3+
COMPONENT projectMSDL
44
)
55

66
install(FILES ${PROJECTM_CONFIGURATION_FILE}
7-
DESTINATION .
7+
DESTINATION ${PROJECTMSDL_DATA_DIR}
8+
COMPONENT projectMSDL
89
)
10+
11+
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT ENABLE_FLAT_PACKAGE)
12+
if(ENABLE_DESKTOP_ICON)
13+
install(FILES src/resources/projectMSDL.desktop
14+
DESTINATION ${PROJECTMSDL_DESKTOP_DIR}
15+
COMPONENT projectMSDL
16+
)
17+
18+
macro(INSTALL_ICON size)
19+
install(FILES src/resources/icons/icon_${size}x${size}.png
20+
DESTINATION ${PROJECTMSDL_ICONS_DIR}/${size}x${size}/apps
21+
RENAME projectMSDL.png
22+
COMPONENT projectMSDL
23+
)
24+
endmacro()
25+
26+
foreach(size 16 32 48 64 72 96 128 256)
27+
install_icon(${size})
28+
endforeach()
29+
30+
endif()
31+
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT ENABLE_FLAT_PACKAGE)
32+
set(ICNS_FILE ${CMAKE_BINARY_DIR}/projectMSDL.icns)
33+
execute_process(COMMAND iconutil -c icns -o "${ICNS_FILE}" "${CMAKE_SOURCE_DIR}/src/resources/icons")
34+
35+
install(FILES ${ICNS_FILE}
36+
DESTINATION ${PROJECTMSDL_DATA_DIR}
37+
COMPONENT projectMSDL
38+
)
39+
endif()
40+
41+
# Install optional presets
42+
foreach(preset_dir ${PRESET_DIRS})
43+
install(DIRECTORY ${preset_dir}
44+
DESTINATION "${PROJECTMSDL_PRESETS_DIR}"
45+
COMPONENT projectMSDL
46+
PATTERN *.md EXCLUDE
47+
)
48+
endforeach()
49+
50+
# Install optional textures
51+
foreach(texture_dir ${TEXTURE_DIRS})
52+
install(DIRECTORY ${texture_dir}
53+
DESTINATION "${PROJECTMSDL_TEXTURES_DIR}"
54+
COMPONENT projectMSDL
55+
PATTERN *.md EXCLUDE
56+
)
57+
endforeach()

src/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ else()
4343
)
4444
endif()
4545

46+
set_source_files_properties(ProjectMSDLApplication.cpp PROPERTIES
47+
COMPILE_DEFINITIONS PROJECTMSDL_CONFIG_LOCATION=\"${DEFAULT_CONFIG_PATH}\"
48+
)
49+
4650
target_compile_definitions(projectMSDL
4751
PRIVATE
4852
PROJECTMSDL_VERSION="${PROJECT_VERSION}"

src/ProjectMSDLApplication.cpp

+13-15
Original file line numberDiff line numberDiff line change
@@ -45,26 +45,24 @@ void ProjectMSDLApplication::initialize(Poco::Util::Application& self)
4545

4646
try
4747
{
48-
if (loadConfiguration(PRIO_DEFAULT) == 0)
48+
//if (loadConfiguration(PRIO_DEFAULT) == 0)
4949
{
50-
#ifdef POCO_OS_FAMILY_UNIX
51-
// In macOS bundles, the file may be located in the ../Resources dir, relative to the exe location.
52-
Poco::Path configPath = config().getString("application.dir");
53-
configPath.makeDirectory().makeParent().append("Resources/").setFileName(configFileName);
54-
if (Poco::File(configPath).exists())
50+
// The file may be located in the ../Resources bundle dir on macOS, elsewhere relative
51+
// to the executable or within an absolute path.
52+
// By setting and retrieving the compiled-in default, we can make use of POCO's variable replacement.
53+
// This allows using ${application.dir} etc. in the path.
54+
config().setString("application.defaultConfigurationFile", PROJECTMSDL_CONFIG_LOCATION);
55+
std::string configPath = config().getString("application.defaultConfigurationFile", "");
56+
if (!configPath.empty())
5557
{
56-
loadConfiguration(configPath.toString(), PRIO_DEFAULT);
57-
}
58-
else
59-
{
60-
// On Linux, system-installed packages often put default configs in /usr/share
61-
configPath.assign("/usr/share/projectM/").setFileName(configFileName);
62-
if (Poco::File(configPath).exists())
58+
Poco::Path configFilePath(configPath);
59+
configFilePath.makeDirectory().setFileName(configFileName);
60+
if (Poco::File(configFilePath).exists())
6361
{
64-
loadConfiguration(configPath.toString(), PRIO_DEFAULT);
62+
loadConfiguration(configFilePath.toString(), PRIO_DEFAULT);
6563
}
64+
6665
}
67-
#endif
6866
}
6967
}
7068
catch (Poco::Exception& ex)

src/ProjectMWrapper.cpp

+28-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "notifications/DisplayToastNotification.h"
66

7+
#include <Poco/File.h>
78
#include <Poco/NotificationCenter.h>
89

910
#include <Poco/Util/Application.h>
@@ -66,7 +67,18 @@ void ProjectMWrapper::initialize(Poco::Util::Application& app)
6667

6768
for (const auto& presetPath : presetPaths)
6869
{
69-
projectm_playlist_add_path(_playlist, presetPath.c_str(), true, false);
70+
Poco::File file(presetPath);
71+
if (file.exists() && file.isFile())
72+
{
73+
projectm_playlist_add_preset(_playlist, presetPath.c_str(), false);
74+
}
75+
else
76+
{
77+
// Symbolic links also fall under this. Without complex resolving, we can't
78+
// be sure what the link exactly points to, especially if a trailing slash is missing.
79+
projectm_playlist_add_path(_playlist, presetPath.c_str(), true, false);
80+
}
81+
7082
}
7183
projectm_playlist_sort(_playlist, 0, projectm_playlist_size(_playlist), SORT_PREDICATE_FILENAME_ONLY, SORT_ORDER_ASCENDING);
7284

@@ -114,6 +126,15 @@ void ProjectMWrapper::RenderFrame() const
114126
glClearColor(0.0, 0.0, 0.0, 0.0);
115127
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
116128

129+
size_t currentMeshX{0};
130+
size_t currentMeshY{0};
131+
projectm_get_mesh_size(_projectM, &currentMeshX, &currentMeshY);
132+
if (currentMeshX != _config->getInt("meshX", 220) ||
133+
currentMeshY != _config->getInt("meshY", 125))
134+
{
135+
projectm_set_mesh_size(_projectM, _config->getInt("meshX", 220), _config->getInt("meshY", 125));
136+
}
137+
117138
projectm_opengl_render_frame(_projectM);
118139
}
119140

@@ -144,7 +165,7 @@ void ProjectMWrapper::PresetSwitchedEvent(bool isHardCut, unsigned int index, vo
144165
auto that = reinterpret_cast<ProjectMWrapper*>(context);
145166
auto presetName = projectm_playlist_item(that->_playlist, index);
146167
poco_information_f1(that->_logger, "Displaying preset: %s", std::string(presetName));
147-
projectm_free_string(presetName);
168+
projectm_playlist_free_string(presetName);
148169

149170
Poco::NotificationCenter::defaultCenter().postNotification(new UpdateWindowTitleNotification);
150171
}
@@ -202,7 +223,11 @@ std::vector<std::string> ProjectMWrapper::GetPathListWithDefault(const std::stri
202223
_config->keys(baseKey, subKeys);
203224
for (const auto& key : subKeys)
204225
{
205-
pathList.push_back(_config->getString(baseKey + "." + key, ""));
226+
auto path = _config->getString(baseKey + "." + key, "");
227+
if (!path.empty())
228+
{
229+
pathList.push_back(std::move(path));
230+
}
206231
}
207232
return pathList;
208233
}

src/SDLRenderingWindow.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,13 @@ void SDLRenderingWindow::UpdateWindowTitleNotificationHandler(POCO_UNUSED const
313313

314314
auto presetName = projectm_playlist_item(projectMWrapper.Playlist(), projectm_playlist_get_position(projectMWrapper.Playlist()));
315315

316-
Poco::Path presetFile(presetName);
317-
projectm_free_string(presetName);
316+
if (presetName)
317+
{
318+
Poco::Path presetFile(presetName);
319+
projectm_playlist_free_string(presetName);
318320

319-
newTitle += "" + presetFile.getBaseName();
321+
newTitle += "" + presetFile.getBaseName();
322+
}
320323

321324
if (projectm_get_preset_locked(projectMWrapper.ProjectM()))
322325
{

src/gui/SettingsWindow.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ void SettingsWindow::Draw()
8282

8383
ImGui::TableNextRow();
8484
LabelWithTooltip("Per-Point Mesh Size X/Y", "Size of the per-point transformation grid.\nHigher values produce better quality, but require more CPU time to calculate.");
85-
IntegerSettingVec("projectM.meshX", "projectM.meshY", 200, 125, 8, 250);
85+
IntegerSettingVec("projectM.meshX", "projectM.meshY", 64, 48, 8, 300);
8686

8787
ImGui::EndTable();
8888
}

src/resources/projectMSDL.desktop

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[Desktop Entry]
2+
Type=Application
3+
Name=projectM
4+
GenericName=Milkdrop-compatible Music Visualizer
5+
Icon=projectMSDL
6+
TryExec=projectMSDL
7+
Exec=projectMSDL
8+
Terminal=false
9+
Categories=Audio;Video;AudioVideo
10+
StartupWMClass=projectMSDL

0 commit comments

Comments
 (0)