blob: 1c62c75c91270715effd03333321324e362c96c0 [file] [log] [blame]
PulkoMandy69eec3e2023-04-10 15:22:28 +02001/*
2 * Copyright (C) 2023 Adrien Destugues <pulkomandy@pulkomandy.tk>
3 *
4 * Distributed under terms of the MIT license.
5 */
6
7#include <Application.h>
8#include <private/interface/ColumnListView.h>
9#include <private/interface/ColumnTypes.h>
10#include <GroupLayout.h>
11#include <LayoutBuilder.h>
12#include <MenuBar.h>
13#include <Window.h>
14
15#include <ctype.h>
16
17#include "../BeDC.h"
18
19
20class BColorStringField: public BStringField
21{
22public:
23 BColorStringField(const char* string, rgb_color color)
24 : BStringField(string)
25 , fColor(color)
26 {
27 }
28
29 rgb_color fColor;
30};
31
32
33class BColorStringColumn: public BStringColumn
34{
35public:
36 BColorStringColumn(const char* title, float w, float minw, float maxw)
37 : BStringColumn(title, w, minw, maxw, false)
38 {
39 }
40
41 void DrawField(BField* field, BRect rect, BView* parent) override
42 {
43 BColorStringField* csField = dynamic_cast<BColorStringField*>(field);
44 if (csField) {
45 parent->SetHighColor(csField->fColor);
46 }
47 BStringColumn::DrawField(field, rect, parent);
48 }
49};
50
51
52static char sanechar(int32 input) {
53 input = input & 0xff;
54 if (isprint(input))
55 return (char)input;
56 else
57 return '.';
58}
59
60
61class LoggerWindow: public BWindow
62{
63public:
64 LoggerWindow()
65 : BWindow(BRect(100, 100, 900, 700), "Dev console", B_DOCUMENT_WINDOW,
66 B_QUIT_ON_WINDOW_CLOSE | B_AUTO_UPDATE_SIZE_LIMITS)
67 {
68 BGroupLayout* layout = new BGroupLayout(B_VERTICAL);
69 SetLayout(layout);
70 layout->SetSpacing(0);
71
72 fEventList = new BColumnListView("messages", 0, B_NO_BORDER);
73 fEventList->AddColumn(new BColorStringColumn("Name", 100, 50, 200), 0);
74 fEventList->AddColumn(new BColorStringColumn("Text", INT16_MAX, 50, INT16_MAX), 1);
75
76 BLayoutBuilder::Group<>(layout)
77 .SetInsets(0, -1, -1, -1)
78 .Add(new BMenuBar("main menu"))
79 .Add(fEventList)
80 .End();
81 }
82
83 void MessageReceived(BMessage* message) override
84 {
85 switch(message->what) {
86 case BEDC_MESSAGE:
87 {
88 // TODO parse all info: bedc_ver, bedc_main_type
89 // bedc_ver: "1.0" (can be changed in later versions if the message format changes)
90 // bedc_main_type: BEDC_BMESSAGE or BEDC_PLAIN_MESSAGE
91 BString name = message->FindString("bedc_name");
92 BString text = message->FindString("bedc_text");
93 int8 colorEnum = message->FindInt8("bedc_color");
94 int8 type = message->FindInt8("bedc_type");
95 int8 main_type = message->FindInt8("bedc_main_type");
96
97 if (type == DC_CLEAR) {
98 fEventList->Clear();
99 return;
100 }
101
102 if (main_type == BEDC_BMESSAGE && text.IsEmpty()) {
103 int32 what = message->FindInt32("bedc_what");
104
105 text.SetToFormat("BMessage(what=%#010x, %d, '%c%c%c%c')", what, what,
106 sanechar(what >> 24), sanechar(what >> 16),
107 sanechar(what >> 8), sanechar(what >> 0));
108 }
109
110 // TODO: generic BMessage handling (results in one line per item in the message)
111 // TODO: separators
112 //
113 //
114 BRow* row = new BRow();
115 if (colorEnum == 0) {
116 row->SetField(new BStringField(name), 0);
117 } else {
118 rgb_color color;
119 switch(colorEnum) {
120 case DC_WHITE:
121 color = make_color(128, 128, 128, 255);
122 break;
123 case DC_BLACK:
124 color = make_color(64, 64, 64, 255);
125 break;
126 case DC_BLUE:
127 color = make_color(0, 0, 128, 255);
128 break;
129 case DC_RED:
130 color = make_color(0, 128, 0, 255);
131 break;
132 case DC_YELLOW:
133 color = make_color(128, 128, 0, 255);
134 break;
135 case DC_GREEN:
136 color = make_color(128, 0, 0, 255);
137 break;
138 }
139 row->SetField(new BColorStringField(name, color), 0);
140 }
141
142 if (type == DC_SUCCESS)
143 row->SetField(new BColorStringField(text, ui_color(B_SUCCESS_COLOR)), 1);
144 else if (type == DC_ERROR)
145 row->SetField(new BColorStringField(text, ui_color(B_FAILURE_COLOR)), 1);
146 else if (type == DC_MESSAGE)
147 row->SetField(new BStringField(text), 1);
148 else if (type == DC_SEPARATOR)
149 row->SetField(new BStringField("-----"), 1);
150 else {
151 message->PrintToStream();
152 }
153 fEventList->AddRow(row, -1);
154
155 if (main_type == BEDC_BMESSAGE) {
156 int index = 0;
157 char* nameFound;
158 type_code typeFound;
159 int32 countFound;
160 while (message->GetInfo(B_ANY_TYPE, index++, &nameFound, &typeFound, &countFound) == B_OK) {
161 // Don't display all the bedc_ internal stuff
162 if (BString(nameFound).StartsWith("bedc_"))
163 continue;
164
165 for (int j = 0; j < countFound; j++) {
166 name.SetToFormat("%s[%d] (%c%c%c%c)", nameFound, j,
167 (typeFound >> 24) & 0xFF, (typeFound >> 16) & 0xFF,
168 (typeFound >> 8) & 0xFF, (typeFound >> 0) & 0xFF
169 );
170
171 switch(typeFound) {
172#if 0
173 B_AFFINE_TRANSFORM_TYPE = 'AMTX',
174 B_ALIGNMENT_TYPE = 'ALGN',
175 B_ANY_TYPE = 'ANYT',
176 B_ATOM_TYPE = 'ATOM',
177 B_ATOMREF_TYPE = 'ATMR',
178 B_BOOL_TYPE = 'BOOL',
179 B_CHAR_TYPE = 'CHAR',
180 B_COLOR_8_BIT_TYPE = 'CLRB',
181 B_DOUBLE_TYPE = 'DBLE',
182 B_FLOAT_TYPE = 'FLOT',
183 B_GRAYSCALE_8_BIT_TYPE = 'GRYB',
184 B_INT16_TYPE = 'SHRT',
185 B_INT64_TYPE = 'LLNG',
186 B_INT8_TYPE = 'BYTE',
187 B_LARGE_ICON_TYPE = 'ICON',
188 B_MEDIA_PARAMETER_GROUP_TYPE = 'BMCG',
189 B_MEDIA_PARAMETER_TYPE = 'BMCT',
190 B_MEDIA_PARAMETER_WEB_TYPE = 'BMCW',
191 B_MESSAGE_TYPE = 'MSGG',
192 B_MESSENGER_TYPE = 'MSNG',
193 B_MIME_TYPE = 'MIME',
194 B_MINI_ICON_TYPE = 'MICN',
195 B_MONOCHROME_1_BIT_TYPE = 'MNOB',
196 B_OBJECT_TYPE = 'OPTR',
197 B_OFF_T_TYPE = 'OFFT',
198 B_PATTERN_TYPE = 'PATN',
199 B_POINTER_TYPE = 'PNTR',
200 B_PROPERTY_INFO_TYPE = 'SCTD',
201 B_RAW_TYPE = 'RAWT',
202 B_RECT_TYPE = 'RECT',
203 B_REF_TYPE = 'RREF',
204 B_NODE_REF_TYPE = 'NREF',
205 B_RGB_32_BIT_TYPE = 'RGBB',
206 B_RGB_COLOR_TYPE = 'RGBC',
207 B_SIZE_TYPE = 'SIZE',
208 B_SIZE_T_TYPE = 'SIZT',
209 B_SSIZE_T_TYPE = 'SSZT',
210 B_STRING_LIST_TYPE = 'STRL',
211 B_TIME_TYPE = 'TIME',
212 B_UINT16_TYPE = 'USHT',
213 B_UINT32_TYPE = 'ULNG',
214 B_UINT64_TYPE = 'ULLG',
215 B_UINT8_TYPE = 'UBYT',
216 B_VECTOR_ICON_TYPE = 'VICN',
217 B_XATTR_TYPE = 'XATR',
218 B_NETWORK_ADDRESS_TYPE = 'NWAD',
219 B_MIME_STRING_TYPE = 'MIMS',
220#endif
221 case B_STRING_TYPE:
222 text = message->FindString(nameFound, j);
223 break;
224 case B_INT32_TYPE:
225 {
226 int32 val = message->FindInt32(nameFound, j);
227 text.SetToFormat("%d (%#010x)", val, val);
228 break;
229 }
230 case B_POINT_TYPE:
231 {
232 BPoint val = message->FindPoint(nameFound, j);
233 text.SetToFormat("X: %f Y: %f", val.x, val.y);
234 break;
235 }
236 default:
237 text.SetTo("TODO: unhandled message content type");
238 break;
239 }
240
241 BRow* subRow = new BRow();
242 subRow->SetField(new BStringField(name), 0);
243 subRow->SetField(new BStringField(text), 1);
244 fEventList->AddRow(subRow, row);
245 }
246
247 }
248 }
249
250 break;
251 }
252 default:
253 BWindow::MessageReceived(message);
254 break;
255 }
256 }
257
258private:
259 BColumnListView* fEventList;
260};
261
262
263class LoggerApp: public BApplication
264{
265public:
266 LoggerApp()
267 : BApplication("application/x-vnd.ml-BeDCApp")
268 {
269 LoggerWindow* window = new LoggerWindow();
270 window->Show();
271 }
272
273 void MessageReceived(BMessage* message) override
274 {
275 switch(message->what) {
276 case BEDC_MESSAGE:
277 WindowAt(0)->PostMessage(message);
278 break;
279 default:
280 BApplication::MessageReceived(message);
281 break;
282 }
283 }
284};
285
286
287int main(void)
288{
289 LoggerApp app;
290 app.Run();
291}