@@ -628,6 +628,8 @@ void PipelineHandler::cancelRequest(Request *request)
*
* - If libcamera is not installed, the src/libcamera/pipeline/\<subdir\>/data/
* directory within the source tree ; otherwise
+ * - The user configuration (~/.config/libcamera/pipeline/\<subdir\>) directory.
+ * - The system configuration (etc/libcamera/pipeline/\<subdir\>) directory.
* - The system data (share/libcamera/pipeline/\<subdir\>) directory.
*
* The system directories are not searched if libcamera is not installed.
@@ -639,9 +641,8 @@ std::string PipelineHandler::configurationFile(const std::string &subdir,
const std::string &name,
bool silent) const
{
- std::string confPath;
+ std::vector<std::string> confPaths;
struct stat statbuf;
- int ret;
std::string root = utils::libcameraSourcePath();
if (!root.empty()) {
@@ -652,25 +653,46 @@ std::string PipelineHandler::configurationFile(const std::string &subdir,
* subdirectory of the corresponding pipeline handler.
*/
std::string confDir = root + "src/libcamera/pipeline/";
- confPath = confDir + subdir + "/data/" + name;
+ confPaths.push_back(confDir + subdir + "/data/" + name);
LOG(Pipeline, Info)
<< "libcamera is not installed. Loading platform configuration file from '"
- << confPath << "'";
+ << confPaths.front() << "'";
} else {
/* Else look in the system locations. */
- confPath = std::string(LIBCAMERA_DATA_DIR)
- + "/pipeline/" + subdir + '/' + name;
+ std::filesystem::path userConfigurationDirectory;
+ const char *xdgConfigHome = utils::secure_getenv("XDG_CONFIG_HOME");
+ if (xdgConfigHome) {
+ userConfigurationDirectory = xdgConfigHome;
+ } else {
+ const char *home = utils::secure_getenv("HOME");
+ if (home)
+ userConfigurationDirectory =
+ std::filesystem::path(home) / ".config";
+ }
+
+ confPaths.push_back(std::string(userConfigurationDirectory) + "/libcamera");
+ confPaths.push_back(std::string(LIBCAMERA_SYSCONF_DIR));
+ confPaths.push_back(std::string(LIBCAMERA_DATA_DIR));
+
+ for (std::string &confPath : confPaths) {
+ confPath += "/pipeline/" + subdir + '/' + name;
+ }
}
- ret = stat(confPath.c_str(), &statbuf);
- if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
- return confPath;
+ for (const std::string &confPath : confPaths) {
+ int ret = stat(confPath.c_str(), &statbuf);
+ if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG) {
+ LOG(Pipeline, Debug)
+ << "Loading platform configuration file from '"
+ << confPath << "'";
+ return confPath;
+ }
+ }
if (!silent)
LOG(Pipeline, Error)
- << "Configuration file '" << confPath
- << "' not found for pipeline handler '"
+ << "Configuration file not found for pipeline handler '"
<< PipelineHandler::name() << "'";
return std::string();
Similar to the global configuration file - configuration.yaml - check the user- and system-configuration paths for pipeline handlers. This is particularly useful on immutable OSs which typically don't allow writes to /usr/share. Signed-off-by: Robert Mader <robert.mader@collabora.com> Closes https://gitlab.freedesktop.org/camera/libcamera/-/work_items/364 --- src/libcamera/pipeline_handler.cpp | 44 ++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 11 deletions(-)