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
RevLine 
[6d5e378]1/*
[24c452b3]2 * Copyright (c) 2021 Jiri Svoboda
[6d5e378]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
[2109961]30/** @addtogroup launcher
[6d5e378]31 * @{
32 */
[a09d401]33/** @file Launcher
[6d5e378]34 */
35
36#include <errno.h>
[a09d401]37#include <gfx/coord.h>
[0576df9]38#include <gfximage/tga.h>
[a09d401]39#include <stdbool.h>
[6d5e378]40#include <stdio.h>
[38d150e]41#include <stdlib.h>
[fd11144]42#include <str.h>
[6d5e378]43#include <str_error.h>
[a09d401]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
[b8f1a349]53#include "images.h"
[2109961]54#include "launcher.h"
[b8f1a349]55
[2109961]56#define NAME "launcher"
[b8f1a349]57
[552b69f]58static const char *display_spec = UI_DISPLAY_DEFAULT;
[6d5e378]59
[a09d401]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
[24c452b3]72static int app_launchl(const char *, ...);
[a09d401]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) {
[24c452b3]96 app_launchl("/app/terminal", "-c", "/app/nav", NULL);
[a09d401]97 } else if (pbutton == launcher->pb2) {
[ec8a1bf]98 app_launchl("/app/terminal", "-c", "/app/edit", NULL);
[a09d401]99 } else if (pbutton == launcher->pb3) {
[ec8a1bf]100 app_launchl("/app/terminal", NULL);
[a09d401]101 } else if (pbutton == launcher->pb4) {
[ec8a1bf]102 app_launchl("/app/calculator", NULL);
[24c452b3]103 } else if (pbutton == launcher->pb5) {
[ec8a1bf]104 app_launchl("/app/uidemo", NULL);
105 } else if (pbutton == launcher->pb6) {
[24c452b3]106 app_launchl("/app/gfxdemo", "ui", NULL);
[a09d401]107 }
108}
[6d5e378]109
[24c452b3]110static int app_launchl(const char *app, ...)
[6d5e378]111{
[fd11144]112 errno_t rc;
[6d5e378]113 task_id_t id;
[1c635d6]114 task_wait_t wait;
[24c452b3]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;
[fd11144]138
[552b69f]139 if (str_cmp(display_spec, UI_DISPLAY_DEFAULT) != 0) {
[24c452b3]140 *argp++ = "-d";
141 *argp++ = display_spec;
[fd11144]142 }
143
[24c452b3]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);
[6d5e378]160 if (rc != EOK) {
[24c452b3]161 printf("%s: Error spawning %s (%s)\n", NAME, app, str_error(rc));
[6d5e378]162 return -1;
163 }
[a35b458]164
[1c635d6]165 rc = task_wait(&wait, &texit, &retval);
[b5674b2]166 if ((rc != EOK) || (texit != TASK_EXIT_NORMAL)) {
[6d5e378]167 printf("%s: Error retrieving retval from %s (%s)\n", NAME,
168 app, str_error(rc));
169 return -1;
170 }
[a35b458]171
[6d5e378]172 return retval;
173}
174
[fd11144]175static void print_syntax(void)
176{
[a09d401]177 printf("Syntax: %s [-d <display-spec>]\n", NAME);
[fd11144]178}
179
[6d5e378]180int main(int argc, char *argv[])
181{
[fd11144]182 int i;
[a09d401]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;
[0576df9]193 gfx_coord2_t off;
[a09d401]194 errno_t rc;
[fd11144]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
[a09d401]206 display_spec = argv[i++];
[fd11144]207 } else {
208 printf("Invalid option '%s'.\n", argv[i]);
209 print_syntax();
210 return 1;
211 }
[6d5e378]212 }
[a35b458]213
[a09d401]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";
[06d0c81]222 params.placement = ui_wnd_place_top_right;
[a09d401]223 params.rect.p0.x = 0;
224 params.rect.p0.y = 0;
225 params.rect.p1.x = 210;
[ec8a1bf]226 params.rect.p1.y = 345;
[a09d401]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;
[bdf3c0c]235 }
[a35b458]236
[a09d401]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
[0576df9]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");
[bdf3c0c]247 return 1;
248 }
[a35b458]249
[0576df9]250 gfx_bitmap_params_init(&logo_params);
251 logo_params.rect = logo_rect;
252
[a09d401]253 rc = ui_fixed_create(&launcher.fixed);
254 if (rc != EOK) {
255 printf("Error creating fixed layout.\n");
256 return rc;
257 }
[a35b458]258
[a09d401]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
[d8ddf7a]265 off.x = 6;
[0576df9]266 off.y = 32;
267 gfx_rect_translate(&off, &logo_rect, &rect);
[d8ddf7a]268
269 /* Adjust for frame width (2 x 1 pixel) */
270 rect.p1.x += 2;
271 rect.p1.y += 2;
[a09d401]272 ui_image_set_rect(launcher.image, &rect);
[d8ddf7a]273 ui_image_set_flags(launcher.image, ui_imgf_frame);
[a09d401]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 }
[d8ddf7a]280
[a09d401]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
[24c452b3]300 /* Navigator */
301
302 rc = ui_pbutton_create(ui_res, "Navigator", &launcher.pb1);
[a09d401]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;
[24c452b3]313 rect.p1.y = rect.p0.y + 28;
[a09d401]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
[ec8a1bf]322 /* Text Editor */
[24c452b3]323
[ec8a1bf]324 rc = ui_pbutton_create(ui_res, "Text Editor", &launcher.pb2);
[a09d401]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;
[24c452b3]333 rect.p0.y = 130 + 35;
[a09d401]334 rect.p1.x = 190;
[24c452b3]335 rect.p1.y = rect.p0.y + 28;
[a09d401]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
[ec8a1bf]344 /* Terminal */
[24c452b3]345
[ec8a1bf]346 rc = ui_pbutton_create(ui_res, "Terminal", &launcher.pb3);
[a09d401]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;
[24c452b3]355 rect.p0.y = 130 + 2 * 35;
[a09d401]356 rect.p1.x = 190;
[24c452b3]357 rect.p1.y = rect.p0.y + 28;
[a09d401]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
[ec8a1bf]366 /* Calculator */
[24c452b3]367
[ec8a1bf]368 rc = ui_pbutton_create(ui_res, "Calculator", &launcher.pb4);
[a09d401]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;
[24c452b3]377 rect.p0.y = 130 + 3 * 35;
[a09d401]378 rect.p1.x = 190;
[24c452b3]379 rect.p1.y = rect.p0.y + 28;
[a09d401]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
[ec8a1bf]388 /* UI Demo */
[a09d401]389
[ec8a1bf]390 rc = ui_pbutton_create(ui_res, "UI Demo", &launcher.pb5);
[24c452b3]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
[ec8a1bf]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
[24c452b3]432 ui_window_add(window, ui_fixed_ctl(launcher.fixed));
[a09d401]433
434 rc = ui_window_paint(window);
435 if (rc != EOK) {
436 printf("Error painting window.\n");
437 return rc;
438 }
[a35b458]439
[a09d401]440 ui_run(ui);
[a35b458]441
[a09d401]442 ui_window_destroy(window);
443 ui_destroy(ui);
[a35b458]444
[bdf3c0c]445 return 0;
[6d5e378]446}
447
448/** @}
449 */
Note: See TracBrowser for help on using the repository browser.