source: mainline/uspace/app/aboutos/aboutos.c@ 2cdf520

Last change on this file since 2cdf520 was e229148, checked in by Jiri Svoboda <jiri@…>, 18 months ago

Morph Launcher into About HelenOS

  • Property mode set to 100644
File size: 8.5 KB
Line 
1/*
2 * Copyright (c) 2024 Jiri Svoboda
3 * Copyright (c) 2012 Petr Koupy
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup aboutos
31 * @{
32 */
33/** @file About HelenOS
34 */
35
36#include <errno.h>
37#include <gfx/coord.h>
38#include <gfximage/tga.h>
39#include <macros.h>
40#include <stdbool.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <str.h>
44#include <str_error.h>
45#include <ui/fixed.h>
46#include <ui/image.h>
47#include <ui/label.h>
48#include <ui/pbutton.h>
49#include <ui/resource.h>
50#include <ui/ui.h>
51#include <ui/window.h>
52
53#include "aboutos.h"
54#include "images.h"
55
56#define NAME "aboutos"
57
58static const char *display_spec = UI_DISPLAY_DEFAULT;
59
60static void aboutos_wnd_close(ui_window_t *, void *);
61static void aboutos_wnd_kbd(ui_window_t *, void *, kbd_event_t *);
62
63static ui_window_cb_t window_cb = {
64 .close = aboutos_wnd_close,
65 .kbd = aboutos_wnd_kbd
66};
67
68static void pb_clicked(ui_pbutton_t *, void *);
69
70static ui_pbutton_cb_t pbutton_cb = {
71 .clicked = pb_clicked
72};
73
74/** Window close button was clicked.
75 *
76 * @param window Window
77 * @param arg Argument (aboutos)
78 */
79static void aboutos_wnd_close(ui_window_t *window, void *arg)
80{
81 aboutos_t *aboutos = (aboutos_t *) arg;
82
83 ui_quit(aboutos->ui);
84}
85
86/** About HelenOS window keyboard event handler.
87 *
88 * @param window Window
89 * @param arg Argument (ui_prompt_dialog_t *)
90 * @param event Keyboard event
91 */
92static void aboutos_wnd_kbd(ui_window_t *window, void *arg,
93 kbd_event_t *event)
94{
95 aboutos_t *aboutos = (aboutos_t *) arg;
96
97 (void)window;
98
99 if (event->type == KEY_PRESS &&
100 (event->mods & (KM_CTRL | KM_SHIFT | KM_ALT)) == 0) {
101 if (event->key == KC_ENTER) {
102 /* Quit */
103 ui_quit(aboutos->ui);
104
105 }
106 }
107
108 ui_window_def_kbd(window, event);
109}
110
111/** Push button was clicked.
112 *
113 * @param pbutton Push button
114 * @param arg Argument (aboutos)
115 */
116static void pb_clicked(ui_pbutton_t *pbutton, void *arg)
117{
118 aboutos_t *aboutos = (aboutos_t *) arg;
119
120 ui_quit(aboutos->ui);
121}
122
123static void print_syntax(void)
124{
125 printf("Syntax: %s [-d <display-spec>]\n", NAME);
126}
127
128int main(int argc, char *argv[])
129{
130 int i;
131 aboutos_t aboutos;
132 ui_t *ui = NULL;
133 ui_wnd_params_t params;
134 ui_window_t *window = NULL;
135 ui_resource_t *ui_res;
136 gfx_bitmap_params_t logo_params;
137 gfx_bitmap_t *logo_bmp;
138 gfx_context_t *gc;
139 gfx_rect_t logo_rect;
140 gfx_rect_t rect;
141 gfx_coord2_t off;
142 const char *dspec = UI_DISPLAY_DEFAULT;
143 char *qmark;
144 errno_t rc;
145
146 i = 1;
147 while (i < argc) {
148 if (str_cmp(argv[i], "-d") == 0) {
149 ++i;
150 if (i >= argc) {
151 printf("Argument missing.\n");
152 print_syntax();
153 return 1;
154 }
155
156 dspec = argv[i++];
157 } else {
158 printf("Invalid option '%s'.\n", argv[i]);
159 print_syntax();
160 return 1;
161 }
162 }
163
164 display_spec = str_dup(dspec);
165 if (display_spec == NULL) {
166 printf("Out of memory.\n");
167 return 1;
168 }
169
170 /* Remove additional arguments */
171 qmark = str_chr(display_spec, '?');
172 if (qmark != NULL)
173 *qmark = '\0';
174
175 rc = ui_create(dspec, &ui);
176 if (rc != EOK) {
177 printf("Error creating UI on display %s.\n", display_spec);
178 return rc;
179 }
180
181 ui_wnd_params_init(&params);
182 params.caption = "About HelenOS";
183
184 /* FIXME: Auto layout */
185 if (ui_is_textmode(ui)) {
186 params.rect.p0.x = 0;
187 params.rect.p0.y = 0;
188 params.rect.p1.x = 45;
189 params.rect.p1.y = 15;
190 } else {
191 params.rect.p0.x = 0;
192 params.rect.p0.y = 0;
193 params.rect.p1.x = 350;
194 params.rect.p1.y = 275;
195 }
196
197 memset((void *) &aboutos, 0, sizeof(aboutos));
198 aboutos.ui = ui;
199
200 rc = ui_window_create(ui, &params, &window);
201 if (rc != EOK) {
202 printf("Error creating window.\n");
203 return rc;
204 }
205
206 ui_window_set_cb(window, &window_cb, (void *) &aboutos);
207 aboutos.window = window;
208
209 ui_res = ui_window_get_res(window);
210 gc = ui_window_get_gc(window);
211
212 rc = decode_tga(gc, (void *) helenos_tga, helenos_tga_size,
213 &logo_bmp, &logo_rect);
214 if (rc != EOK) {
215 printf("Unable to decode logo.\n");
216 return 1;
217 }
218
219 gfx_bitmap_params_init(&logo_params);
220 logo_params.rect = logo_rect;
221
222 rc = ui_fixed_create(&aboutos.fixed);
223 if (rc != EOK) {
224 printf("Error creating fixed layout.\n");
225 return rc;
226 }
227
228 rc = ui_image_create(ui_res, logo_bmp, &logo_rect, &aboutos.image);
229 if (rc != EOK) {
230 printf("Error creating label.\n");
231 return rc;
232 }
233
234 off.x = 76;
235 off.y = 42;
236 gfx_rect_translate(&off, &logo_rect, &rect);
237
238 /* Adjust for frame width (2 x 1 pixel) */
239 rect.p1.x += 2;
240 rect.p1.y += 2;
241 ui_image_set_rect(aboutos.image, &rect);
242 ui_image_set_flags(aboutos.image, ui_imgf_frame);
243
244 rc = ui_fixed_add(aboutos.fixed, ui_image_ctl(aboutos.image));
245 if (rc != EOK) {
246 printf("Error adding control to layout.\n");
247 return rc;
248 }
249
250 /* Release label */
251
252 rc = ui_label_create(ui_res, "HelenOS " STRING(HELENOS_RELEASE)
253 " (" STRING(HELENOS_CODENAME) ")", &aboutos.lrelease);
254 if (rc != EOK) {
255 printf("Error creating label.\n");
256 return rc;
257 }
258
259 if (ui_is_textmode(ui)) {
260 rect.p0.x = 1;
261 rect.p0.y = 5;
262 rect.p1.x = 44;
263 rect.p1.y = 6;
264 } else {
265 rect.p0.x = 10;
266 rect.p0.y = 140;
267 rect.p1.x = 340;
268 rect.p1.y = 160;
269 }
270
271 ui_label_set_rect(aboutos.lrelease, &rect);
272 ui_label_set_halign(aboutos.lrelease, gfx_halign_center);
273
274 rc = ui_fixed_add(aboutos.fixed, ui_label_ctl(aboutos.lrelease));
275 if (rc != EOK) {
276 printf("Error adding control to layout.\n");
277 return rc;
278 }
279
280 /* Copyright label */
281
282 rc = ui_label_create(ui_res, STRING(HELENOS_COPYRIGHT), &aboutos.lcopy);
283 if (rc != EOK) {
284 printf("Error creating label.\n");
285 return rc;
286 }
287
288 if (ui_is_textmode(ui)) {
289 rect.p0.x = 1;
290 rect.p0.y = 6;
291 rect.p1.x = 44;
292 rect.p1.y = 7;
293 } else {
294 rect.p0.x = 10;
295 rect.p0.y = 160;
296 rect.p1.x = 340;
297 rect.p1.y = 180;
298 }
299
300 ui_label_set_rect(aboutos.lcopy, &rect);
301 ui_label_set_halign(aboutos.lcopy, gfx_halign_center);
302
303 rc = ui_fixed_add(aboutos.fixed, ui_label_ctl(aboutos.lcopy));
304 if (rc != EOK) {
305 printf("Error adding control to layout.\n");
306 return rc;
307 }
308
309 /* Architecture label */
310
311 rc = ui_label_create(ui_res, "Running on " STRING(UARCH), &aboutos.larch);
312 if (rc != EOK) {
313 printf("Error creating label.\n");
314 return rc;
315 }
316
317 if (ui_is_textmode(ui)) {
318 rect.p0.x = 1;
319 rect.p0.y = 9;
320 rect.p1.x = 44;
321 rect.p1.y = 10;
322 } else {
323 rect.p0.x = 10;
324 rect.p0.y = 190;
325 rect.p1.x = 340;
326 rect.p1.y = 210;
327 }
328
329 ui_label_set_rect(aboutos.larch, &rect);
330 ui_label_set_halign(aboutos.larch, gfx_halign_center);
331
332 rc = ui_fixed_add(aboutos.fixed, ui_label_ctl(aboutos.larch));
333 if (rc != EOK) {
334 printf("Error adding control to layout.\n");
335 return rc;
336 }
337
338 /* OK button */
339
340 rc = ui_pbutton_create(ui_res, "OK", &aboutos.pbok);
341 if (rc != EOK) {
342 printf("Error creating button.\n");
343 return rc;
344 }
345
346 ui_pbutton_set_cb(aboutos.pbok, &pbutton_cb, (void *) &aboutos);
347
348 if (ui_is_textmode(ui)) {
349 rect.p0.x = 17;
350 rect.p0.y = 13;
351 rect.p1.x = 28;
352 rect.p1.y = 14;
353 } else {
354 rect.p0.x = 125;
355 rect.p0.y = 235;
356 rect.p1.x = 225;
357 rect.p1.y = rect.p0.y + 28;
358 }
359
360 ui_pbutton_set_rect(aboutos.pbok, &rect);
361 ui_pbutton_set_default(aboutos.pbok, true);
362
363 rc = ui_fixed_add(aboutos.fixed, ui_pbutton_ctl(aboutos.pbok));
364 if (rc != EOK) {
365 printf("Error adding control to layout.\n");
366 return rc;
367 }
368
369 ui_window_add(window, ui_fixed_ctl(aboutos.fixed));
370
371 rc = ui_window_paint(window);
372 if (rc != EOK) {
373 printf("Error painting window.\n");
374 return rc;
375 }
376
377 ui_run(ui);
378
379 ui_window_destroy(window);
380 ui_destroy(ui);
381
382 return 0;
383}
384
385/** @}
386 */
Note: See TracBrowser for help on using the repository browser.