152 lines
5.0 KiB
Plaintext
152 lines
5.0 KiB
Plaintext
platform_load_platform_information :: () {
|
|
}
|
|
|
|
platform_get_path_program_data :: inline () -> string {
|
|
return XDG.get_path(.DATA_HOME);
|
|
}
|
|
|
|
platform_get_path_config_data :: inline () -> string {
|
|
return XDG.get_path(.CONFIG_HOME);
|
|
}
|
|
|
|
// $TMPDIR, else /tmp, without a separator at the end. Temp.
|
|
platform_temporary_folder :: () -> string {
|
|
folder := posix_getenv("TMPDIR");
|
|
if !folder return "/tmp";
|
|
return trim_right(copy_string(folder,, temp), "/");
|
|
}
|
|
|
|
// A tag such as ja-JP from the locale variables, or "". Temp.
|
|
platform_preferred_language :: () -> string {
|
|
for string.["LC_ALL", "LC_MESSAGES", "LANG"] {
|
|
value := posix_getenv(it);
|
|
if !value || value == "C" || value == "POSIX" continue;
|
|
tag := copy_string(value,, temp);
|
|
dot := find_index_from_left(tag, #char "."); // ja_JP.UTF-8
|
|
if dot >= 0 tag.count = dot;
|
|
return replace(tag, "_", "-",, temp);
|
|
}
|
|
return "";
|
|
}
|
|
|
|
// Temp. Noto Sans CJK's collection holds every script: JP, KR, SC, TC in that order.
|
|
platform_cjk_font_candidates :: () -> [] Cjk_Font {
|
|
list: [..] Cjk_Font;
|
|
list.allocator = temp;
|
|
for folder: string.["/usr/share/fonts/opentype/noto", "/usr/share/fonts/noto-cjk"] {
|
|
path := tprint("%/NotoSansCJK-Regular.ttc", folder);
|
|
cjk_candidate(*list, .JAPANESE, path, "Noto Sans CJK JP", face = 0);
|
|
cjk_candidate(*list, .KOREAN, path, "Noto Sans CJK KR", face = 1);
|
|
cjk_candidate(*list, .SIMPLIFIED, path, "Noto Sans CJK SC", face = 2);
|
|
cjk_candidate(*list, .TRADITIONAL, path, "Noto Sans CJK TC", face = 3);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
// Wayland has no global hotkey API, and X11 key grabs are not implemented, so none are registered.
|
|
// A desktop's own shortcut settings can run the executable instead: a second launch brings the
|
|
// running instance forward over the IPC channel.
|
|
platform_apply_global_hotkeys :: (actions: [] Hotkey_Action) {
|
|
bound := false;
|
|
for actions if it.hotkey.binding_count bound = true;
|
|
if bound log("[hotkeys] Global hotkeys are not supported on Linux; [global_hotkeys] is ignored.");
|
|
}
|
|
|
|
platform_unregister_global_hotkeys :: () {}
|
|
|
|
// Resident and virtual sizes, and their peaks, from /proc/self/status.
|
|
platform_update_memory_usage_metrics :: () { using perf.memory_usage;
|
|
data, ok := read_entire_file("/proc/self/status", log_errors = false,, temp);
|
|
if !ok return;
|
|
|
|
kilobytes :: (data: string, key: string) -> s64 {
|
|
index := find_index_from_left(data, key);
|
|
if index < 0 return -1;
|
|
rest := slice(data, index + key.count, data.count - index - key.count);
|
|
value, ok := string_to_int(trim_left(rest));
|
|
return ifx ok then value else -1;
|
|
}
|
|
|
|
rss := kilobytes(data, "VmRSS:");
|
|
hwm := kilobytes(data, "VmHWM:");
|
|
size := kilobytes(data, "VmSize:");
|
|
peak := kilobytes(data, "VmPeak:");
|
|
if rss >= 0 working_set = rss * 1024;
|
|
if hwm >= 0 peak_working_set = hwm * 1024;
|
|
if size >= 0 virtual_memory = size * 1024;
|
|
if peak >= 0 peak_virtual_memory = peak * 1024;
|
|
}
|
|
|
|
linux_get_desktop_environment :: () -> Linux_Desktop_Environment {
|
|
push_allocator(temp);
|
|
result := to_string(SDL_getenv("XDG_CURRENT_DESKTOP"));
|
|
log("XDG_CURRENT_DESKTOP: %", result);
|
|
// Some desktops list several names, as in ubuntu:GNOME.
|
|
for name: split(to_lower_copy(result), ":") {
|
|
if name == {
|
|
case "xfce"; return .XFCE;
|
|
case "gnome"; return .GNOME;
|
|
case "kde"; return .KDE;
|
|
case "hyprland"; return .Hyprland;
|
|
case "sway"; return .sway;
|
|
case "unity"; return .Unity;
|
|
case "lxqt"; return .LXQt;
|
|
case "mate"; return .MATE;
|
|
}
|
|
}
|
|
return .UNKNOWN;
|
|
}
|
|
|
|
Linux_Desktop_Environment :: enum s32 {
|
|
UNKNOWN :: 0;
|
|
XFCE :: 1;
|
|
GNOME :: 2;
|
|
KDE :: 3;
|
|
Hyprland :: 4;
|
|
sway :: 5;
|
|
Unity :: 6;
|
|
LXQt :: 7;
|
|
MATE :: 8;
|
|
}
|
|
|
|
Linux_Display_Backend :: enum s32 {
|
|
X11 :: 0;
|
|
WAYLAND :: 1;
|
|
OTHER :: -1;
|
|
}
|
|
|
|
linux_get_SDL3_backend :: () -> Linux_Display_Backend {
|
|
driver := to_string(SDL_GetCurrentVideoDriver());
|
|
if driver == "x11"
|
|
return .X11;
|
|
if driver == "wayland"
|
|
return .WAYLAND;
|
|
|
|
return .OTHER;
|
|
}
|
|
|
|
linux_platform_setup :: () { using platform;
|
|
desktop_environment = linux_get_desktop_environment();
|
|
display_backend = linux_get_SDL3_backend();
|
|
log("[linux] Desktop environment: %, display backend: %.", desktop_environment, display_backend);
|
|
}
|
|
|
|
os_clear_unused_pages :: () {
|
|
log("[os_clear_unused_pages] Not implemented on Linux.");
|
|
}
|
|
|
|
platform_set_thread_affinity_all :: #bake_arguments platform_set_thread_affinity(affinity=.All);
|
|
platform_set_thread_affinity :: (thread: *Thread, affinity: CPUID_Type) {
|
|
}
|
|
|
|
XDG :: #import "XDG";
|
|
|
|
// Drops what the page cache holds of the file, so the next read comes from the disk (-cold). Clean
|
|
// pages go at once; pages not yet written back stay. False when it cannot be opened.
|
|
platform_evict_file_cache :: (path: string) -> bool {
|
|
fd := POSIX.open(temp_c_string(path), POSIX.O_RDONLY | POSIX.O_CLOEXEC);
|
|
if fd < 0 return false;
|
|
defer POSIX.close(fd);
|
|
return POSIX.posix_fadvise(fd, 0, 0, POSIX.POSIX_FADV_DONTNEED) == 0;
|
|
}
|