master ohmu/fastfetch-openbsd / src / detection / displayserver / linux / displayserver_linux.c
ohmu  ·  2026-10-15
 1#include "displayserver_linux.h"
 2#include "common/io.h"
 3#include "common/strutil.h"
 4
 5#ifdef __FreeBSD__
 6    #include "common/settings.h"
 7#endif
 8
 9static void getWMProtocolNameFromEnv(FFDisplayServerResult* result) {
10    const char* env = getenv("XDG_SESSION_TYPE");
11    if (env) {
12        if (ffStrEqualsIgnCase(env, "wayland")) {
13            ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_WAYLAND);
14        } else if (ffStrEqualsIgnCase(env, "x11") || ffStrEqualsIgnCase(env, "xorg")) {
15            ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
16        } else if (ffStrEqualsIgnCase(env, "tty")) {
17            ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
18        } else {
19            ffStrbufSetS(&result->wmProtocolName, env);
20        }
21
22        return;
23    }
24
25    if (getenv("WAYLAND_DISPLAY") != nullptr || getenv("WAYLAND_SOCKET") != nullptr) {
26        ffStrbufSetStatic(&result->wmProtocolName, FF_WM_PROTOCOL_WAYLAND);
27        return;
28    }
29
30    if (getenv("DISPLAY") != nullptr) // XWayland also set this
31    {
32        ffStrbufSetStatic(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
33        return;
34    }
35
36    env = getenv("TERM");
37    if (ffStrSet(env) && ffStrEqualsIgnCase(env, "linux")) {
38        ffStrbufSetStatic(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
39        return;
40    }
41}
42
43void ffConnectDisplayServerImpl(FFDisplayServerResult* ds) {
44    if (instance.config.general.dsForceDrm == FF_DS_FORCE_DRM_TYPE_FALSE) {
45        // We try wayland as our preferred display server, as it supports the most features.
46        // This method can't detect the name of our WM / DE
47        ffdsConnectWayland(ds);
48
49        // Try the x11 libs, from most feature rich to least.
50        // We use the display list to detect if a connection is needed.
51        // They respect wmProtocolName, and only detect display if it is set.
52        if (ds->displays.length == 0) {
53            ffdsConnectXcbRandr(ds);
54        }
55
56        if (ds->displays.length == 0) {
57            ffdsConnectXrandr(ds);
58        }
59    }
60
61    // This display detection method is display server independent.
62    // Use it if all connections failed
63    if (ds->displays.length == 0) {
64        ffdsConnectDrm(ds);
65    }
66
67#ifdef __FreeBSD__
68    if (ds->displays.length == 0) {
69        FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
70        if (ffSettingsGetFreeBSDKenv("screen.width", &buf)) {
71            uint32_t width = (uint32_t) ffStrbufToUInt(&buf, 0);
72            if (width) {
73                ffStrbufClear(&buf);
74                if (ffSettingsGetFreeBSDKenv("screen.height", &buf)) {
75                    uint32_t height = (uint32_t) ffStrbufToUInt(&buf, 0);
76                    ffdsAppendDisplay(ds, width, height, 0, 0, 0, 0, 0, 0, nullptr, FF_DISPLAY_TYPE_UNKNOWN, false, 0, 0, 0, "kenv");
77                }
78            }
79        }
80    }
81#endif
82
83    if (ds->wmProtocolName.length == 0) {
84        getWMProtocolNameFromEnv(ds);
85    }
86
87    if (!ffStrbufEqualS(&ds->wmProtocolName, FF_WM_PROTOCOL_TTY)) {
88        // This fills in missing information about WM / DE by using env vars and iterating processes
89        ffdsDetectWMDE(ds);
90    }
91}