diff options
Diffstat (limited to 'src/detection/terminalsize')
| -rw-r--r-- | src/detection/terminalsize/terminalsize.h | 13 | ||||
| -rw-r--r-- | src/detection/terminalsize/terminalsize_linux.c | 38 | ||||
| -rw-r--r-- | src/detection/terminalsize/terminalsize_windows.c | 45 |
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; +} |