ohmu
·
2026-10-15
1#include "common/printing.h"
2#include "common/jsonconfig.h"
3#include "common/strutil.h"
4#include "detection/displayserver/displayserver.h"
5#include "modules/monitor/monitor.h"
6
7#include <math.h>
8
9bool ffPrintMonitor(FFMonitorOptions* options) {
10 const FFDisplayServerResult* result = ffConnectDisplayServer();
11
12 if (!result->displays.length) {
13 ffPrintError(FF_MODULE_GET_DISPLAY_NAME(Monitor), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "No display detected");
14 return false;
15 }
16
17 FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
18 uint32_t index = 0;
19 FF_LIST_FOR_EACH (FFDisplayResult, display, result->displays) {
20 double inch = sqrt(display->physicalWidth * display->physicalWidth + display->physicalHeight * display->physicalHeight) / 25.4;
21 double ppi = sqrt(display->width * display->width + display->height * display->height) / inch;
22 bool hdrCompatible = display->hdrStatus == FF_DISPLAY_HDR_STATUS_SUPPORTED || display->hdrStatus == FF_DISPLAY_HDR_STATUS_ENABLED;
23
24 ffStrbufClear(&key);
25 if (options->moduleArgs.key.length == 0) {
26 ffStrbufAppendS(&key, FF_MODULE_GET_DISPLAY_NAME(Monitor));
27 if (display->name.length > 0) {
28 ffStrbufAppendF(&key, " (%s)", display->name.chars);
29 }
30 } else {
31 uint32_t moduleIndex = result->displays.length == 1 ? 0 : index + 1;
32 FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, ((FFformatarg[]) {
33 FF_ARG(moduleIndex, "index"),
34 FF_ARG(display->name, "name"),
35 FF_ARG(options->moduleArgs.keyIcon, "icon"),
36 FF_ARG(FF_MODULE_GET_DISPLAY_NAME(Monitor), "module-name"),
37 }));
38 }
39
40 if (options->moduleArgs.outputFormat.length == 0) {
41 ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
42
43 printf("%ux%u px", display->width, display->height);
44 if (display->refreshRate > 0) {
45 printf(" @ %g Hz", ((int) (display->refreshRate * 1000 + 0.5)) / 1000.0);
46 }
47 if (inch > 0) {
48 printf(" - %ux%u mm (%.2f inches, %.2f ppi)", display->physicalWidth, display->physicalHeight, inch, ppi);
49 }
50 if (hdrCompatible) {
51 fputs(" [HDR Compatible]", stdout);
52 }
53 putchar('\n');
54 } else {
55 FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, ((FFformatarg[]) {
56 FF_ARG(display->name, "name"),
57 FF_ARG(display->width, "width"),
58 FF_ARG(display->height, "height"),
59 FF_ARG(display->physicalWidth, "physical-width"),
60 FF_ARG(display->physicalHeight, "physical-height"),
61 FF_ARG(inch, "inch"),
62 FF_ARG(ppi, "ppi"),
63 FF_ARG(display->manufactureYear, "manufacture-year"),
64 FF_ARG(display->manufactureWeek, "manufacture-week"),
65 FF_ARG(display->serial, "serial"),
66 FF_ARG(display->refreshRate, "refresh-rate"),
67 FF_ARG(hdrCompatible, "hdr-compatible"),
68 }));
69 }
70
71 // result is a singleton, so we don't destroy the members
72 ++index;
73 }
74
75 return true;
76}
77
78void ffParseMonitorJsonObject(FFMonitorOptions* options, yyjson_val* module) {
79 yyjson_val *key, *val;
80 size_t idx, max;
81 yyjson_obj_foreach (module, idx, max, key, val) {
82 if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs)) {
83 continue;
84 }
85
86 ffPrintError(FF_MODULE_GET_DISPLAY_NAME(Monitor), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", unsafe_yyjson_get_str(key));
87 }
88}
89
90[[gnu::cold]]
91void ffGenerateMonitorJsonConfig(FFMonitorOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
92 ffJsonConfigGenerateModuleArgsConfig(doc, module, &options->moduleArgs);
93}
94
95bool ffGenerateMonitorJsonResult([[maybe_unused]] FFMonitorOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
96 yyjson_mut_obj_add_str(doc, module, "error", "Monitor module is an alias of Display module");
97 return false;
98}
99
100void ffInitMonitorOptions(FFMonitorOptions* options) {
101 ffOptionInitModuleArg(&options->moduleArgs, "");
102}
103
104void ffDestroyMonitorOptions(FFMonitorOptions* options) {
105 ffOptionDestroyModuleArg(&options->moduleArgs);
106}
107
108FFModuleBaseInfo ffMonitorModuleInfo = {
109 .name = "Monitor",
110 .description = "Same as Display module, but with a different default output format",
111 .displayName = {
112 .en = "Monitor",
113 .ar = "الشاشة",
114 .cs = "Monitor",
115 .de = "Monitor",
116 .es = "Monitor",
117 .fi = "Monitori",
118 .fr = "Moniteur",
119 .gl = "Monitor",
120 .he = "צג",
121 .id = "Monitor",
122 .it = "Monitor",
123 .ja = "モニター",
124 .ko = "모니터",
125 .pl = "Monitor",
126 .pt = "Monitor",
127 .ru = "Монитор",
128 .tr = "Monitör",
129 .uk = "Монітор",
130 .vi = "Màn hình",
131 .zh_CN = "监视器",
132 .zh_TW = "監視器",
133 },
134 .initOptions = (void*) ffInitMonitorOptions,
135 .destroyOptions = (void*) ffDestroyMonitorOptions,
136 .parseJsonObject = (void*) ffParseMonitorJsonObject,
137 .printModule = (void*) ffPrintMonitor,
138 .generateJsonResult = (void*) ffGenerateMonitorJsonResult,
139 .generateJsonConfig = (void*) ffGenerateMonitorJsonConfig,
140 .formatArgs = FF_FORMAT_ARG_LIST(((FFModuleFormatArg[]) {
141 { "Display name *", "name" },
142 { "Native resolution width in pixels", "width" },
143 { "Native resolution height in pixels", "height" },
144 { "Physical width in millimeters", "physical-width" },
145 { "Physical height in millimeters", "physical-height" },
146 { "Physical diagonal length in inches", "inch" },
147 { "Pixels per inch (PPI)", "ppi" },
148 { "Year of manufacturing", "manufacture-year" },
149 { "Nth week of manufacturing in the year", "manufacture-week" },
150 { "Serial number", "serial" },
151 { "Maximum refresh rate in Hz", "refresh-rate" },
152 { "True if the display is HDR compatible", "hdr-compatible" },
153 })),
154 .defaultOrder = 19,
155};