diff options
Diffstat (limited to 'src/detection/cursor')
| -rw-r--r-- | src/detection/cursor/cursor.h | 12 | ||||
| -rw-r--r-- | src/detection/cursor/cursor_apple.m | 63 | ||||
| -rw-r--r-- | src/detection/cursor/cursor_linux.c | 101 | ||||
| -rw-r--r-- | src/detection/cursor/cursor_nosupport.c | 5 | ||||
| -rw-r--r-- | src/detection/cursor/cursor_windows.c | 17 |
5 files changed, 198 insertions, 0 deletions
diff --git a/src/detection/cursor/cursor.h b/src/detection/cursor/cursor.h new file mode 100644 index 0000000..34ef86c --- /dev/null +++ b/src/detection/cursor/cursor.h @@ -0,0 +1,12 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/cursor/option.h" + +typedef struct FFCursorResult { + FFstrbuf theme; + FFstrbuf size; + FFstrbuf error; +} FFCursorResult; + +void ffDetectCursor(FFCursorResult* result); diff --git a/src/detection/cursor/cursor_apple.m b/src/detection/cursor/cursor_apple.m new file mode 100644 index 0000000..610bd1e --- /dev/null +++ b/src/detection/cursor/cursor_apple.m @@ -0,0 +1,63 @@ +#include "cursor.h" + +#import <Foundation/Foundation.h> + +static void appendColor(FFstrbuf* str, NSDictionary* dict) +{ + uint32_t r = (uint32_t) (((NSNumber*) dict[@"red"]).doubleValue * 255 + .5); + uint32_t g = (uint32_t) (((NSNumber*) dict[@"green"]).doubleValue * 255 + .5); + uint32_t b = (uint32_t) (((NSNumber*) dict[@"blue"]).doubleValue * 255 + .5); + uint32_t a = (uint32_t) (((NSNumber*) dict[@"alpha"]).doubleValue * 255 + .5); + uint32_t color = (r << 24) | (g << 16) | (b << 8) | a; + + switch (color) + { + case 0x000000FF: ffStrbufAppendS(str, "Black"); return; + case 0x0433FFFF: ffStrbufAppendS(str, "Blue"); return; + case 0xAA7942FF: ffStrbufAppendS(str, "Brown"); return; + case 0x00FDFFFF: ffStrbufAppendS(str, "Cyan"); return; + case 0x00F900FF: ffStrbufAppendS(str, "Green"); return; + case 0xFF40FFFF: ffStrbufAppendS(str, "Magenta"); return; + case 0xFF9300FF: ffStrbufAppendS(str, "Orange"); return; + case 0x942192FF: ffStrbufAppendS(str, "Purple"); return; + case 0xFF2600FF: ffStrbufAppendS(str, "Red"); return; + case 0xFFFB00FF: ffStrbufAppendS(str, "Yellow"); return; + case 0xFFFFFFFF: ffStrbufAppendS(str, "White"); return; + case 0x00000000: ffStrbufAppendS(str, "Transparent"); return; + default: ffStrbufAppendF(str, "#%08X", color); return; + } +} + +void ffDetectCursor(FFCursorResult* result) +{ + NSError* error; + NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/com.apple.universalaccess.plist", instance.state.platform.homeDir.chars]; + NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName] + error:&error]; + if(error) + { + ffStrbufAppendS(&result->error, error.localizedDescription.UTF8String); + return; + } + + NSDictionary* color; + + ffStrbufAppendS(&result->theme, "Fill - "); + if ((color = dict[@"cursorFill"])) + appendColor(&result->theme, color); + else + ffStrbufAppendS(&result->theme, "Black"); + + ffStrbufAppendS(&result->theme, ", Outline - "); + + if ((color = dict[@"cursorOutline"])) + appendColor(&result->theme, color); + else + ffStrbufAppendS(&result->theme, "White"); + + NSNumber* mouseDriverCursorSize = dict[@"mouseDriverCursorSize"]; + if (mouseDriverCursorSize) + ffStrbufAppendF(&result->size, "%d", (int) (mouseDriverCursorSize.doubleValue * 32 + 0.5)); + else + ffStrbufAppendS(&result->size, "32"); +} diff --git a/src/detection/cursor/cursor_linux.c b/src/detection/cursor/cursor_linux.c new file mode 100644 index 0000000..89dabbc --- /dev/null +++ b/src/detection/cursor/cursor_linux.c @@ -0,0 +1,101 @@ +#include "cursor.h" + +#include "detection/gtk_qt/gtk_qt.h" +#include "detection/displayserver/displayserver.h" +#include "common/properties.h" +#include "common/parsing.h" +#include "common/settings.h" +#include "common/strutil.h" + +#include <stdlib.h> + +static bool detectCursorGTK(FFCursorResult* result) { + const FFGTKResult* gtk = ffDetectGTK4(); + + if (gtk->cursor.length == 0) { + gtk = ffDetectGTK3(); + } + + if (gtk->cursor.length == 0) { + gtk = ffDetectGTK2(); + } + + if (gtk->cursor.length == 0) { + return false; + } + + ffStrbufAppend(&result->theme, >k->cursor); + ffStrbufAppend(&result->size, >k->cursorSize); + return true; +} + +static void detectCursorFromConfigFile(const char* relativeFilePath, const char* themeStart, const char* themeDefault, const char* sizeStart, const char* sizeDefault, FFCursorResult* result) { + if (ffParsePropFileConfigValues(relativeFilePath, 2, (FFpropquery[]) { { themeStart, &result->theme }, { sizeStart, &result->size } })) { + if (result->theme.length == 0) { + ffStrbufAppendS(&result->theme, themeDefault); + } + + if (result->size.length == 0) { + ffStrbufAppendS(&result->size, sizeDefault); + } + } + + if (result->theme.length == 0) { + ffStrbufAppendF(&result->error, "Couldn't find cursor in %s", relativeFilePath); + } +} + +static bool detectCursorFromXResources(FFCursorResult* result) { + ffParsePropFileHomeValues(".Xresources", 2, (FFpropquery[]) { { "Xcursor.theme :", &result->theme }, { "Xcursor.size :", &result->size } }); + + return result->theme.length > 0; +} + +static bool detectCursorFromEnv(FFCursorResult* result) { + const char* xcursor_theme = getenv("XCURSOR_THEME"); + + if (!ffStrSet(xcursor_theme)) { + return false; + } + + ffStrbufAppendS(&result->theme, xcursor_theme); + ffStrbufAppendS(&result->size, getenv("XCURSOR_SIZE")); + + return true; +} + +static bool detectCursorHyprcursor(FFCursorResult* result) { + const char* hyprcursor_theme = getenv("HYPRCURSOR_THEME"); + + if (!ffStrSet(hyprcursor_theme)) { + return false; + } + + ffStrbufAppendS(&result->theme, hyprcursor_theme); + ffStrbufAppendS(&result->size, getenv("HYPRCURSOR_SIZE")); + + return true; +} + +void ffDetectCursor(FFCursorResult* result) { + const FFDisplayServerResult* wmde = ffConnectDisplayServer(); + + if (ffStrbufEqualS(&wmde->wmPrettyName, FF_WM_PRETTY_WSLG)) { + ffStrbufAppendS(&result->error, "WSLg uses native windows cursor"); + } else if (ffStrbufIgnCaseEqualS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY)) { + ffStrbufAppendS(&result->error, "Cursor isn't supported in TTY"); + } else if (ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA)) { + detectCursorFromConfigFile("kcminputrc", "cursorTheme =", "Breeze", "cursorSize =", "24", result); + } else if (ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT)) { + detectCursorFromConfigFile("lxqt/session.conf", "cursor_theme =", "Adwaita", "cursor_size =", "24", result); + } else if (ffStrbufIgnCaseEqualS(&wmde->wmPrettyName, FF_WM_PRETTY_HYPRLAND) && detectCursorHyprcursor(result)) { + return; + } else if ( + !detectCursorGTK(result) && + !detectCursorFromEnv(result) && + !ffParsePropFileHome(".icons/default/index.theme", "Inherits =", &result->theme) && + !detectCursorFromXResources(result) && + !ffParsePropFileData("icons/default/index.theme", "Inherits =", &result->theme)) { + ffStrbufAppendS(&result->error, "Couldn't find cursor"); + } +} diff --git a/src/detection/cursor/cursor_nosupport.c b/src/detection/cursor/cursor_nosupport.c new file mode 100644 index 0000000..6413d92 --- /dev/null +++ b/src/detection/cursor/cursor_nosupport.c @@ -0,0 +1,5 @@ +#include "cursor.h" + +void ffDetectCursor(FF_A_UNUSED FFCursorResult* result) { + ffStrbufInitS(&result->error, "Not supported on this platform"); +} diff --git a/src/detection/cursor/cursor_windows.c b/src/detection/cursor/cursor_windows.c new file mode 100644 index 0000000..a6814ec --- /dev/null +++ b/src/detection/cursor/cursor_windows.c @@ -0,0 +1,17 @@ +#include "cursor.h" + +#include "common/io.h" +#include "common/windows/registry.h" + +void ffDetectCursor(FFCursorResult* result) { + FF_AUTO_CLOSE_FD HANDLE hKey = NULL; + if (ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Cursors", &hKey, &result->error)) { + if (ffRegReadStrbuf(hKey, NULL, &result->theme, &result->error)) { + uint32_t cursorBaseSize; + if (ffRegReadUint(hKey, L"CursorBaseSize", &cursorBaseSize, NULL)) { + // Not available on Windows 8.1 + ffStrbufAppendUInt(&result->size, cursorBaseSize); + }; + } + } +} |