diff options
Diffstat (limited to 'src/detection/wallpaper')
| -rw-r--r-- | src/detection/wallpaper/wallpaper.h | 5 | ||||
| -rw-r--r-- | src/detection/wallpaper/wallpaper_apple.m | 72 | ||||
| -rw-r--r-- | src/detection/wallpaper/wallpaper_haiku.cpp | 54 | ||||
| -rw-r--r-- | src/detection/wallpaper/wallpaper_linux.c | 102 | ||||
| -rw-r--r-- | src/detection/wallpaper/wallpaper_nosupport.c | 5 | ||||
| -rw-r--r-- | src/detection/wallpaper/wallpaper_windows.c | 15 |
6 files changed, 253 insertions, 0 deletions
diff --git a/src/detection/wallpaper/wallpaper.h b/src/detection/wallpaper/wallpaper.h new file mode 100644 index 0000000..96fead9 --- /dev/null +++ b/src/detection/wallpaper/wallpaper.h @@ -0,0 +1,5 @@ +#pragma once + +#include "fastfetch.h" + +const char* ffDetectWallpaper(FFstrbuf* result); diff --git a/src/detection/wallpaper/wallpaper_apple.m b/src/detection/wallpaper/wallpaper_apple.m new file mode 100644 index 0000000..800aee9 --- /dev/null +++ b/src/detection/wallpaper/wallpaper_apple.m @@ -0,0 +1,72 @@ +#include "wallpaper.h" +#include "common/settings.h" +#include "common/apple/osascript.h" + +#import <Foundation/Foundation.h> + +const char* ffDetectWallpaper(FFstrbuf* result) +{ + { + // For Sonoma + // https://github.com/JohnCoates/Aerial/issues/1332 + NSError* error; + NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Application Support/com.apple.wallpaper/Store/Index.plist", instance.state.platform.homeDir.chars]; + NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName] + error:&error]; + if (!error) + { + NSArray* choices = [dict valueForKeyPath:@"SystemDefault.Desktop.Content.Choices"]; + if (choices.count > 0) + { + NSDictionary* choice = choices[0]; + NSArray* files = choice[@"Files"]; + if (files.count > 0) + { + NSString* file = files[0][@"relative"]; + ffStrbufAppendS(result, [NSURL URLWithString:file].path.UTF8String); + } + else + { + NSString* provider = choice[@"Provider"]; + NSString* builtinPrefix = @"com.apple.wallpaper.choice."; + if ([provider hasPrefix:builtinPrefix]) + provider = [provider substringFromIndex:builtinPrefix.length]; + if ([provider isEqualToString:@"sonoma"]) + ffStrbufSetStatic(result, "macOS Sonoma"); + else if ([provider isEqualToString:@"aerials"]) // Most builtin aerial wallpapers are private + ffStrbufSetStatic(result, "Built-in aerial photography"); + else + ffStrbufAppendF(result, "Built-in %s wallpaper", provider.UTF8String); + } + } + if (result->length > 0) + return NULL; + } + } + + #ifdef FF_HAVE_SQLITE3 + + { + // For Ventura + // https://stackoverflow.com/questions/301215/getting-desktop-background-on-mac + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(&instance.state.platform.homeDir); + ffStrbufAppendS(&path, "Library/Application Support/Dock/desktoppicture.db"); + if (ffSettingsGetSQLite3String(path.chars, + "SELECT value\n" + "FROM preferences\n" + "JOIN data ON preferences.data_id=data.ROWID\n" + "JOIN pictures ON preferences.picture_id=pictures.ROWID\n" + "JOIN displays ON pictures.display_id=displays.ROWID\n" + "JOIN spaces ON pictures.space_id=spaces.ROWID\n" + "WHERE display_id=1 AND space_id=1 AND key=1", result) + ) + return NULL; + } + + #endif + + if (ffOsascript("tell application \"Finder\" to get POSIX path of (get desktop picture as alias)", result)) + return NULL; + + return "All detection methods failed"; +} diff --git a/src/detection/wallpaper/wallpaper_haiku.cpp b/src/detection/wallpaper/wallpaper_haiku.cpp new file mode 100644 index 0000000..0bfad62 --- /dev/null +++ b/src/detection/wallpaper/wallpaper_haiku.cpp @@ -0,0 +1,54 @@ +extern "C" { +#include "wallpaper.h" +#include "common/mallocHelper.h" +} + +#include <Application.h> +#include <FindDirectory.h> +#include <InterfaceDefs.h> +#include <Node.h> +#include <Path.h> +#include <Screen.h> +#include <fs_attr.h> +#include <be_apps/Tracker/Background.h> + +const char* ffDetectWallpaper(FFstrbuf* result) { + BMessage backgrounds; + BPath pDesktop; + BString path; + + if (find_directory(B_DESKTOP_DIRECTORY, &pDesktop) < B_OK) { + return "find_directory(B_DESKTOP_DIRECTORY) failed"; + } + + // We need a valid be_app to query the app_server here. + BApplication app("application/x-vnd.fastfetch-cli-fastfetch"); + + BNode nDesktop(pDesktop.Path()); + if (nDesktop.InitCheck() == B_OK) { + struct attr_info ai; + if (nDesktop.GetAttrInfo(B_BACKGROUND_INFO, &ai) == B_OK && ai.size > 0) { + FF_AUTO_FREE char* pAttr = (char*) malloc(ai.size); + if (nDesktop.ReadAttr(B_BACKGROUND_INFO, ai.type, 0LL, pAttr, (size_t) ai.size) >= B_OK) { + if (backgrounds.Unflatten(pAttr) == B_OK) { + for (int i = 0; backgrounds.FindString(B_BACKGROUND_IMAGE, i, &path) == B_OK; i++) { + int32 ws; + if (backgrounds.FindInt32(B_BACKGROUND_WORKSPACES, i, &ws) == B_OK) { + if (ws & (1 << current_workspace())) { + // We try to match the one for the current workspace + break; + } + } + } + } + } + } + } + + if (path.Length() < 1) { + return "Failed to detect the current wallpaper path"; + } + + ffStrbufAppendS(result, path.String()); + return NULL; +} diff --git a/src/detection/wallpaper/wallpaper_linux.c b/src/detection/wallpaper/wallpaper_linux.c new file mode 100644 index 0000000..f5ad4ec --- /dev/null +++ b/src/detection/wallpaper/wallpaper_linux.c @@ -0,0 +1,102 @@ +#include "wallpaper.h" +#include "common/io.h" +#include "common/settings.h" +#include "detection/displayserver/displayserver.h" +#include "detection/gtk_qt/gtk_qt.h" + +static const char* detectCosmicComp(FFstrbuf* result) { + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(FF_LIST_FIRST(FFstrbuf, instance.state.platform.configDirs)); + ffStrbufAppendS(&path, "cosmic/com.system76.CosmicBackground/v1/"); + uint32_t basePathLength = path.length; + + FF_STRBUF_AUTO_DESTROY backgrounds = ffStrbufCreate(); + ffStrbufAppendS(&path, "backgrounds"); + bool sharedWallpaper = true; + FF_STRBUF_AUTO_DESTROY monitorName = ffStrbufCreate(); + if (ffReadFileBuffer(path.chars, &backgrounds)) { + FF_STRBUF_AUTO_DESTROY cleaned = ffStrbufCreateCopy(&backgrounds); + ffStrbufRemoveStrings(&cleaned, 4, (const char*[]){ " ", "\n", "\r", "\t" }); + + if (!ffStrbufEqualS(&cleaned, "[]")) { + const char* firstQuote = strchr(backgrounds.chars, '"'); + if (firstQuote != NULL) { + const char* secondQuote = strchr(firstQuote + 1, '"'); + if (secondQuote != NULL && secondQuote > firstQuote + 1) { + ffStrbufAppendNS(&monitorName, (uint32_t) (secondQuote - firstQuote - 1), firstQuote + 1); + sharedWallpaper = false; + } + } + } + } + ffStrbufSubstrBefore(&path, basePathLength); + + if (sharedWallpaper) { + ffStrbufAppendS(&path, "all"); + } else { + ffStrbufAppendS(&path, "output."); + ffStrbufAppend(&path, &monitorName); + } + + FF_STRBUF_AUTO_DESTROY output = ffStrbufCreate(); + if (!ffReadFileBuffer(path.chars, &output)) { + return "Failed to read COSMIC wallpaper config"; + } + + const char* sourceStart = strstr(output.chars, "source:"); + if (sourceStart == NULL) { + return "COSMIC wallpaper config doesn't contain source"; + } + + const char* pathStart = strstr(sourceStart, "Path("); + if (pathStart == NULL) { + return "COSMIC wallpaper source is not a Path value"; + } + + pathStart += strlen("Path("); + while (*pathStart == ' ' || *pathStart == '\t') { + ++pathStart; + } + + if (*pathStart != '\'' && *pathStart != '"') { + return "COSMIC wallpaper Path format is invalid"; + } + + char quote = *pathStart; + ++pathStart; + const char* pathEnd = strchr(pathStart, quote); + if (pathEnd == NULL || pathEnd == pathStart) { + return "COSMIC wallpaper path is empty"; + } + + ffStrbufAppendNS(result, (uint32_t) (pathEnd - pathStart), pathStart); + return NULL; +} + +const char* ffDetectWallpaper(FFstrbuf* result) { + const FFDisplayServerResult* wm = ffConnectDisplayServer(); + if (ffStrbufIgnCaseEqualS(&wm->wmPrettyName, FF_WM_PRETTY_COSMIC_COMP)) { + return detectCosmicComp(result); + } + + const FFstrbuf* wallpaper = NULL; + const FFGTKResult* gtk = ffDetectGTK4(); + if (gtk->wallpaper.length) { + wallpaper = >k->wallpaper; + } else { + const FFQtResult* qt = ffDetectQt(); + if (qt->wallpaper.length) { + wallpaper = &qt->wallpaper; + } + } + + if (!wallpaper) { + return "Failed to detect the current wallpaper path"; + } + + if (ffStrbufStartsWithS(wallpaper, "file:///")) { + ffStrbufAppendS(result, wallpaper->chars + strlen("file://")); + } else { + ffStrbufAppend(result, wallpaper); + } + return NULL; +} diff --git a/src/detection/wallpaper/wallpaper_nosupport.c b/src/detection/wallpaper/wallpaper_nosupport.c new file mode 100644 index 0000000..9be8e91 --- /dev/null +++ b/src/detection/wallpaper/wallpaper_nosupport.c @@ -0,0 +1,5 @@ +#include "wallpaper.h" + +const char* ffDetectWallpaper(FF_A_UNUSED FFstrbuf* result) { + return "Not supported on this platform"; +} diff --git a/src/detection/wallpaper/wallpaper_windows.c b/src/detection/wallpaper/wallpaper_windows.c new file mode 100644 index 0000000..2adf083 --- /dev/null +++ b/src/detection/wallpaper/wallpaper_windows.c @@ -0,0 +1,15 @@ +#include "wallpaper.h" +#include "common/windows/registry.h" + +const char* ffDetectWallpaper(FFstrbuf* result) { + FF_AUTO_CLOSE_FD HANDLE hKey = NULL; + if (!ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Desktop", &hKey, NULL)) { + return "ffRegOpenKeyForRead(Control Panel\\Desktop) failed"; + } + + if (!ffRegReadStrbuf(hKey, L"WallPaper", result, NULL)) { + return "ffRegReadStrbuf(WallPaper) failed"; + } + + return NULL; +} |