ArKanjo 0.5.1
A tool for find code duplicated functions in codebases
windows_utils.cpp
Go to the documentation of this file.
2
3#include <iostream>
4#include <string>
5
6#ifdef _WIN32
7#include <windows.h>
8#include <process.h>
9
10#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
11#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
12#endif
13
14std::tuple<int, int, int> UtilsOSDependable::parse_terminal_color_response(const std::string& response) {
15 // Parse RGB from response
16 size_t start = response.find("rgb:");
17 if (start == std::string::npos)
18 return {0,0,0};
19 start += 4;
20
21 size_t end = response.find("/", start);
22 if (end == std::string::npos)
23 return {0,0,0};
24 std::string rStr = response.substr(start, end - start);
25
26 start = end + 1;
27 end = response.find("/", start);
28 if (end == std::string::npos)
29 return {0,0,0};
30 std::string gStr = response.substr(start, end - start);
31
32 start = end + 1;
33 end = response.find("\x1b", start);
34 if (end == std::string::npos)
35 return {0,0,0};
36 std::string bStr = response.substr(start, end - start);
37
38 try {
39 auto r = std::stoi(rStr, nullptr, 16) / 256;
40 auto g = std::stoi(gStr, nullptr, 16) / 256;
41 auto b = std::stoi(bStr, nullptr, 16) / 256;
42 return {r, g, b};
43 } catch (...) {
44 return {0, 0, 0};
45 }
46}
47
48std::string UtilsOSDependable::capture_terminal_response() {
49 HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
50 HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
51
52 // Save original console mode
53 DWORD originalOutMode = 0;
54 GetConsoleMode(hOutput, &originalOutMode);
55
56 // Enable virtual terminal processing
57 SetConsoleMode(hOutput, originalOutMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
58
59 // Set input to raw mode (disable line input and echo input)
60 DWORD originalInMode = 0;
61 GetConsoleMode(hInput, &originalInMode);
62 SetConsoleMode(hInput, originalInMode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT));
63
64 // Send OSC 11 query for background color
65 const char* query = "\x1b]11;?\x1b\\";
66 DWORD written = 0;
67 WriteConsoleA(hOutput, query, (DWORD)strlen(query), &written, nullptr);
68
69 // Read raw input
70 std::string response;
71 char buffer[256];
72 DWORD read = 0;
73 for (int i = 0; i < 20; ++i) {
74 if (ReadFile(hInput, buffer, sizeof(buffer), &read, nullptr) && read > 0) {
75 response.append(buffer, read);
76 if (response.find('\x1b') != std::string::npos && response.find("rgb:") != std::string::npos) {
77 break;
78 }
79 }
80 Sleep(50);
81 }
82
83 // Restore original modes
84 SetConsoleMode(hInput, originalInMode);
85 SetConsoleMode(hOutput, originalOutMode);
86
87 return response;
88}
89
90float UtilsOSDependable::get_terminal_bg_color_luminance() {
91 std::string color_str = capture_terminal_response();
92 auto [r, g, b] = parse_terminal_color_response(color_str);
93 float luminance = 0.2126 * (r / 255.0) + 0.7152 * (g / 255.0) + 0.0722 * (b / 255.0);
94
95 return luminance;
96}
97
99 return get_terminal_bg_color_luminance() <= 0.5;
100}
101
102int UtilsOSDependable::run_process(const char* cmd, char* const argv[]) {
103 return _spawnvp(_P_OVERLAY, cmd, argv);
104}
105
106#endif
static int run_process(const char *cmd, char *const argv[])
Executes an external program, replacing the current process (exec-style).
static bool is_bg_color_dark()
Determines if terminal background color is dark.
utility functions