source: mainline/uspace/app/launcher/launcher.c@ a5c7b865

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a5c7b865 was 552b69f, checked in by Jiri Svoboda <jiri@…>, 4 years ago

Dual-mode applications should automatically fall back to console

  • Property mode set to 100644
File size: 10.1 KB
Line 
1/*
2 * Copyright (c) 2021 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 launcher
31 * @{
32 */
33/** @file Launcher
34 */
35
36#include <errno.h>
37#include <gfx/coord.h>
38#include <gfximage/tga.h>
39#include <stdbool.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <str.h>
43#include <str_error.h>
44#include <task.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 "images.h"
54#include "launcher.h"
55
56#define NAME "launcher"
57
58static const char *display_spec = UI_DISPLAY_DEFAULT;
59
60static void wnd_close(ui_window_t *, void *);
61
62static ui_window_cb_t window_cb = {
63 .close = wnd_close
64};
65
66static void pb_clicked(ui_pbutton_t *, void *);
67
68static ui_pbutton_cb_t pbutton_cb = {
69 .clicked = pb_clicked
70};
71
72static int app_launchl(const char *, ...);
73
74/** Window close button was clicked.
75 *
76 * @param window Window
77 * @param arg Argument (launcher)
78 */
79static void wnd_close(ui_window_t *window, void *arg)
80{
81 launcher_t *launcher = (launcher_t *) arg;
82
83 ui_quit(launcher->ui);
84}
85
86/** Push button was clicked.
87 *
88 * @param pbutton Push button
89 * @param arg Argument (launcher)
90 */
91static void pb_clicked(ui_pbutton_t *pbutton, void *arg)
92{
93 launcher_t *launcher = (launcher_t *) arg;
94
95 if (pbutton == launcher->pb1) {
96 app_launchl("/app/terminal", "-c", "/app/nav", NULL);
97 } else if (pbutton == launcher->pb2) {
98 app_launchl("/app/terminal", "-c", "/app/edit", NULL);
99 } else if (pbutton == launcher->pb3) {
100 app_launchl("/app/terminal", NULL);
101 } else if (pbutton == launcher->pb4) {
102 app_launchl("/app/calculator", NULL);
103 } else if (pbutton == launcher->pb5) {
104 app_launchl("/app/uidemo", NULL);
105 } else if (pbutton == launcher->pb6) {
106 app_launchl("/app/gfxdemo", "ui", NULL);
107 }
108}
109
110static int app_launchl(const char *app, ...)
111{
112 errno_t rc;
113 task_id_t id;
114 task_wait_t wait;
115 va_list ap;
116 const char *arg;
117 const char **argv;
118 const char **argp;
119 int cnt = 0;
120 int i;
121
122 va_start(ap, app);
123 do {
124 arg = va_arg(ap, const char *);
125 cnt++;
126 } while (arg != NULL);
127 va_end(ap);
128
129 argv = calloc(cnt + 4, sizeof(const char *));
130 if (argv == NULL)
131 return -1;
132
133 task_exit_t texit;
134 int retval;
135
136 argp = argv;
137 *argp++ = app;
138
139 if (str_cmp(display_spec, UI_DISPLAY_DEFAULT) != 0) {
140 *argp++ = "-d";
141 *argp++ = display_spec;
142 }
143
144 va_start(ap, app);
145 do {
146 arg = va_arg(ap, const char *);
147 *argp++ = arg;
148 } while (arg != NULL);
149 va_end(ap);
150
151 *argp++ = NULL;
152
153 printf("%s: Spawning %s", NAME, app);
154 for (i = 0; argv[i] != NULL; i++) {
155 printf(" %s", argv[i]);
156 }
157 printf("\n");
158
159 rc = task_spawnv(&id, &wait, app, argv);
160 if (rc != EOK) {
161 printf("%s: Error spawning %s (%s)\n", NAME, app, str_error(rc));
162 return -1;
163 }
164
165 rc = task_wait(&wait, &texit, &retval);
166 if ((rc != EOK) || (texit != TASK_EXIT_NORMAL)) {
167 printf("%s: Error retrieving retval from %s (%s)\n", NAME,
168 app, str_error(rc));
169 return -1;
170 }
171
172 return retval;
173}
174
175static void print_syntax(void)
176{
177 printf("Syntax: %s [-d <display-spec>]\n", NAME);
178}
179
180int main(int argc, char *argv[])
181{
182 int i;
183 launcher_t launcher;
184 ui_t *ui = NULL;
185 ui_wnd_params_t params;
186 ui_window_t *window = NULL;
187 ui_resource_t *ui_res;
188 gfx_bitmap_params_t logo_params;
189 gfx_bitmap_t *logo_bmp;
190 gfx_context_t *gc;
191 gfx_rect_t logo_rect;
192 gfx_rect_t rect;
193 gfx_coord2_t off;
194 errno_t rc;
195
196 i = 1;
197 while (i < argc) {
198 if (str_cmp(argv[i], "-d") == 0) {
199 ++i;
200 if (i >= argc) {
201 printf("Argument missing.\n");
202 print_syntax();
203 return 1;
204 }
205
206 display_spec = argv[i++];
207 } else {
208 printf("Invalid option '%s'.\n", argv[i]);
209 print_syntax();
210 return 1;
211 }
212 }
213
214 rc = ui_create(display_spec, &ui);
215 if (rc != EOK) {
216 printf("Error creating UI on display %s.\n", display_spec);
217 return rc;
218 }
219
220 ui_wnd_params_init(&params);
221 params.caption = "Launcher";
222 params.placement = ui_wnd_place_top_right;
223 params.rect.p0.x = 0;
224 params.rect.p0.y = 0;
225 params.rect.p1.x = 210;
226 params.rect.p1.y = 345;
227
228 memset((void *) &launcher, 0, sizeof(launcher));
229 launcher.ui = ui;
230
231 rc = ui_window_create(ui, &params, &window);
232 if (rc != EOK) {
233 printf("Error creating window.\n");
234 return rc;
235 }
236
237 ui_window_set_cb(window, &window_cb, (void *) &launcher);
238 launcher.window = window;
239
240 ui_res = ui_window_get_res(window);
241 gc = ui_window_get_gc(window);
242
243 rc = decode_tga(gc, (void *) helenos_tga, helenos_tga_size,
244 &logo_bmp, &logo_rect);
245 if (rc != EOK) {
246 printf("Unable to decode logo.\n");
247 return 1;
248 }
249
250 gfx_bitmap_params_init(&logo_params);
251 logo_params.rect = logo_rect;
252
253 rc = ui_fixed_create(&launcher.fixed);
254 if (rc != EOK) {
255 printf("Error creating fixed layout.\n");
256 return rc;
257 }
258
259 rc = ui_image_create(ui_res, logo_bmp, &logo_rect, &launcher.image);
260 if (rc != EOK) {
261 printf("Error creating label.\n");
262 return rc;
263 }
264
265 off.x = 6;
266 off.y = 32;
267 gfx_rect_translate(&off, &logo_rect, &rect);
268
269 /* Adjust for frame width (2 x 1 pixel) */
270 rect.p1.x += 2;
271 rect.p1.y += 2;
272 ui_image_set_rect(launcher.image, &rect);
273 ui_image_set_flags(launcher.image, ui_imgf_frame);
274
275 rc = ui_fixed_add(launcher.fixed, ui_image_ctl(launcher.image));
276 if (rc != EOK) {
277 printf("Error adding control to layout.\n");
278 return rc;
279 }
280
281 rc = ui_label_create(ui_res, "Launch application", &launcher.label);
282 if (rc != EOK) {
283 printf("Error creating label.\n");
284 return rc;
285 }
286
287 rect.p0.x = 60;
288 rect.p0.y = 107;
289 rect.p1.x = 160;
290 rect.p1.y = 120;
291 ui_label_set_rect(launcher.label, &rect);
292 ui_label_set_halign(launcher.label, gfx_halign_center);
293
294 rc = ui_fixed_add(launcher.fixed, ui_label_ctl(launcher.label));
295 if (rc != EOK) {
296 printf("Error adding control to layout.\n");
297 return rc;
298 }
299
300 /* Navigator */
301
302 rc = ui_pbutton_create(ui_res, "Navigator", &launcher.pb1);
303 if (rc != EOK) {
304 printf("Error creating button.\n");
305 return rc;
306 }
307
308 ui_pbutton_set_cb(launcher.pb1, &pbutton_cb, (void *) &launcher);
309
310 rect.p0.x = 15;
311 rect.p0.y = 130;
312 rect.p1.x = 190;
313 rect.p1.y = rect.p0.y + 28;
314 ui_pbutton_set_rect(launcher.pb1, &rect);
315
316 rc = ui_fixed_add(launcher.fixed, ui_pbutton_ctl(launcher.pb1));
317 if (rc != EOK) {
318 printf("Error adding control to layout.\n");
319 return rc;
320 }
321
322 /* Text Editor */
323
324 rc = ui_pbutton_create(ui_res, "Text Editor", &launcher.pb2);
325 if (rc != EOK) {
326 printf("Error creating button.\n");
327 return rc;
328 }
329
330 ui_pbutton_set_cb(launcher.pb2, &pbutton_cb, (void *) &launcher);
331
332 rect.p0.x = 15;
333 rect.p0.y = 130 + 35;
334 rect.p1.x = 190;
335 rect.p1.y = rect.p0.y + 28;
336 ui_pbutton_set_rect(launcher.pb2, &rect);
337
338 rc = ui_fixed_add(launcher.fixed, ui_pbutton_ctl(launcher.pb2));
339 if (rc != EOK) {
340 printf("Error adding control to layout.\n");
341 return rc;
342 }
343
344 /* Terminal */
345
346 rc = ui_pbutton_create(ui_res, "Terminal", &launcher.pb3);
347 if (rc != EOK) {
348 printf("Error creating button.\n");
349 return rc;
350 }
351
352 ui_pbutton_set_cb(launcher.pb3, &pbutton_cb, (void *) &launcher);
353
354 rect.p0.x = 15;
355 rect.p0.y = 130 + 2 * 35;
356 rect.p1.x = 190;
357 rect.p1.y = rect.p0.y + 28;
358 ui_pbutton_set_rect(launcher.pb3, &rect);
359
360 rc = ui_fixed_add(launcher.fixed, ui_pbutton_ctl(launcher.pb3));
361 if (rc != EOK) {
362 printf("Error adding control to layout.\n");
363 return rc;
364 }
365
366 /* Calculator */
367
368 rc = ui_pbutton_create(ui_res, "Calculator", &launcher.pb4);
369 if (rc != EOK) {
370 printf("Error creating button.\n");
371 return rc;
372 }
373
374 ui_pbutton_set_cb(launcher.pb4, &pbutton_cb, (void *) &launcher);
375
376 rect.p0.x = 15;
377 rect.p0.y = 130 + 3 * 35;
378 rect.p1.x = 190;
379 rect.p1.y = rect.p0.y + 28;
380 ui_pbutton_set_rect(launcher.pb4, &rect);
381
382 rc = ui_fixed_add(launcher.fixed, ui_pbutton_ctl(launcher.pb4));
383 if (rc != EOK) {
384 printf("Error adding control to layout.\n");
385 return rc;
386 }
387
388 /* UI Demo */
389
390 rc = ui_pbutton_create(ui_res, "UI Demo", &launcher.pb5);
391 if (rc != EOK) {
392 printf("Error creating button.\n");
393 return rc;
394 }
395
396 ui_pbutton_set_cb(launcher.pb5, &pbutton_cb, (void *) &launcher);
397
398 rect.p0.x = 15;
399 rect.p0.y = 130 + 4 * 35;
400 rect.p1.x = 190;
401 rect.p1.y = rect.p0.y + 28;
402 ui_pbutton_set_rect(launcher.pb5, &rect);
403
404 rc = ui_fixed_add(launcher.fixed, ui_pbutton_ctl(launcher.pb5));
405 if (rc != EOK) {
406 printf("Error adding control to layout.\n");
407 return rc;
408 }
409
410 /* GFX Demo */
411
412 rc = ui_pbutton_create(ui_res, "GFX Demo", &launcher.pb6);
413 if (rc != EOK) {
414 printf("Error creating button.\n");
415 return rc;
416 }
417
418 ui_pbutton_set_cb(launcher.pb6, &pbutton_cb, (void *) &launcher);
419
420 rect.p0.x = 15;
421 rect.p0.y = 130 + 5 * 35;
422 rect.p1.x = 190;
423 rect.p1.y = rect.p0.y + 28;
424 ui_pbutton_set_rect(launcher.pb6, &rect);
425
426 rc = ui_fixed_add(launcher.fixed, ui_pbutton_ctl(launcher.pb6));
427 if (rc != EOK) {
428 printf("Error adding control to layout.\n");
429 return rc;
430 }
431
432 ui_window_add(window, ui_fixed_ctl(launcher.fixed));
433
434 rc = ui_window_paint(window);
435 if (rc != EOK) {
436 printf("Error painting window.\n");
437 return rc;
438 }
439
440 ui_run(ui);
441
442 ui_window_destroy(window);
443 ui_destroy(ui);
444
445 return 0;
446}
447
448/** @}
449 */
Note: See TracBrowser for help on using the repository browser.