summaryrefslogtreecommitdiffstats
path: root/src/detection/terminalsize
diff options
context:
space:
mode:
authorsumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
committersumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
commit76424950e373d3b04ac3dd13019151bfba3e8423 (patch)
tree4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/detection/terminalsize
Add the files
Diffstat (limited to 'src/detection/terminalsize')
-rw-r--r--src/detection/terminalsize/terminalsize.h13
-rw-r--r--src/detection/terminalsize/terminalsize_linux.c38
-rw-r--r--src/detection/terminalsize/terminalsize_windows.c45
3 files changed, 96 insertions, 0 deletions
diff --git a/src/detection/terminalsize/terminalsize.h b/src/detection/terminalsize/terminalsize.h
new file mode 100644
index 0000000..1ad97e1
--- /dev/null
+++ b/src/detection/terminalsize/terminalsize.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "fastfetch.h"
+#include "modules/terminalsize/option.h"
+
+typedef struct FFTerminalSizeResult {
+ uint16_t rows;
+ uint16_t columns;
+ uint16_t width;
+ uint16_t height;
+} FFTerminalSizeResult;
+
+bool ffDetectTerminalSize(FFTerminalSizeResult* result);
diff --git a/src/detection/terminalsize/terminalsize_linux.c b/src/detection/terminalsize/terminalsize_linux.c
new file mode 100644
index 0000000..e06f958
--- /dev/null
+++ b/src/detection/terminalsize/terminalsize_linux.c
@@ -0,0 +1,38 @@
+#include "terminalsize.h"
+#include "common/io.h"
+
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef __sun
+ #include <sys/termios.h>
+#endif
+
+bool ffDetectTerminalSize(FFTerminalSizeResult* result) {
+ struct winsize winsize = {};
+ static int ttyfd = STDOUT_FILENO;
+ if (!isatty(ttyfd)) {
+ ttyfd = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
+ }
+
+ ioctl(ttyfd, TIOCGWINSZ, &winsize);
+
+ if (winsize.ws_row == 0 || winsize.ws_col == 0) {
+ ffGetTerminalResponse("\e[18t", 2, "\e[8;%hu;%hut", &winsize.ws_row, &winsize.ws_col);
+ }
+
+ if (winsize.ws_ypixel == 0 || winsize.ws_xpixel == 0) {
+ ffGetTerminalResponse("\e[14t", 2, "\e[4;%hu;%hut", &winsize.ws_ypixel, &winsize.ws_xpixel);
+ }
+
+ if (winsize.ws_row == 0 && winsize.ws_col == 0) {
+ return false;
+ }
+
+ result->rows = winsize.ws_row;
+ result->columns = winsize.ws_col;
+ result->width = winsize.ws_xpixel;
+ result->height = winsize.ws_ypixel;
+ return true;
+}
diff --git a/src/detection/terminalsize/terminalsize_windows.c b/src/detection/terminalsize/terminalsize_windows.c
new file mode 100644
index 0000000..05888e7
--- /dev/null
+++ b/src/detection/terminalsize/terminalsize_windows.c
@@ -0,0 +1,45 @@
+#include "terminalsize.h"
+#include "common/io.h"
+
+#include <windows.h>
+
+bool ffDetectTerminalSize(FFTerminalSizeResult* result) {
+ HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE;
+ {
+ DWORD outputMode;
+ if (!GetConsoleMode(hOutput, &outputMode)) {
+ hConout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
+ hOutput = hConout;
+ }
+ }
+ {
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(hOutput, &csbi)) {
+ result->columns = (uint16_t) (csbi.srWindow.Right - csbi.srWindow.Left + 1);
+ result->rows = (uint16_t) (csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
+ } else {
+ // Windows Terminal doesn't report `\e` for some reason
+ ffGetTerminalResponse("\e[18t", 2, "%*[^;];%hu;%hut", &result->rows, &result->columns);
+ }
+ }
+
+ if (result->columns == 0 && result->rows == 0) {
+ return false;
+ }
+
+ {
+ CONSOLE_FONT_INFOEX cfi = { .cbSize = sizeof(cfi) };
+ if (GetCurrentConsoleFontEx(hOutput, FALSE, &cfi)) // Only works for ConHost
+ {
+ result->width = result->columns * (uint16_t) cfi.dwFontSize.X;
+ result->height = result->rows * (uint16_t) cfi.dwFontSize.Y;
+ }
+ if (result->width == 0 || result->height == 0) {
+ // Windows Terminal doesn't report `\e` for some reason
+ ffGetTerminalResponse("\e[14t", 2, "%*[^;];%hu;%hut", &result->height, &result->width);
+ }
+ }
+
+ return result->columns > 0 && result->rows > 0;
+}