source: mainline/uspace/app/gfxdemo/gfxdemo.c@ 8dbd13d

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

Display status line for each demo screen

Clipping helps to prevent accidentally drawing over the status line.

  • Property mode set to 100644
File size: 23.1 KB
Line 
1/*
2 * Copyright (c) 2020 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup gfxdemo
30 * @{
31 */
32/** @file Graphic demo
33 */
34
35#include <congfx/console.h>
36#include <display.h>
37#include <fibril.h>
38#include <gfx/bitmap.h>
39#include <gfx/color.h>
40#include <gfx/render.h>
41#include <gfx/font.h>
42#include <gfx/text.h>
43#include <gfx/typeface.h>
44#include <io/console.h>
45#include <io/pixelmap.h>
46#include <stdbool.h>
47#include <stdlib.h>
48#include <str.h>
49#include <task.h>
50#include <ui/ui.h>
51#include <ui/window.h>
52#include <ui/wdecor.h>
53
54static void wnd_close_event(void *);
55static void wnd_kbd_event(void *, kbd_event_t *);
56
57static display_wnd_cb_t wnd_cb = {
58 .close_event = wnd_close_event,
59 .kbd_event = wnd_kbd_event
60};
61
62static void uiwnd_close_event(ui_window_t *, void *);
63static void uiwnd_kbd_event(ui_window_t *, void *, kbd_event_t *);
64
65static ui_window_cb_t ui_window_cb = {
66 .close = uiwnd_close_event,
67 .kbd = uiwnd_kbd_event
68};
69
70static bool quit = false;
71static gfx_typeface_t *tface;
72static gfx_font_t *font;
73static gfx_coord_t vpad;
74
75/** Clear screen.
76 *
77 * @param gc Graphic context
78 * @param w Screen width
79 * @param h Screen height
80 */
81static errno_t clear_scr(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
82{
83 gfx_color_t *color = NULL;
84 gfx_rect_t rect;
85 errno_t rc;
86
87 rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
88 if (rc != EOK)
89 goto error;
90
91 rc = gfx_set_color(gc, color);
92 if (rc != EOK)
93 goto error;
94
95 rect.p0.x = 0;
96 rect.p0.y = 0;
97 rect.p1.x = w;
98 rect.p1.y = h;
99
100 rc = gfx_fill_rect(gc, &rect);
101 if (rc != EOK)
102 goto error;
103
104 gfx_color_delete(color);
105 return EOK;
106error:
107 if (color != NULL)
108 gfx_color_delete(color);
109 return rc;
110}
111
112/** Initialize demo font.
113 *
114 * @param gc Graphic context
115 * @param w Width
116 * @param h Height
117 * @return EOK on success or an error code
118 */
119static errno_t demo_font_init(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
120{
121 gfx_font_info_t *finfo;
122 errno_t rc;
123
124 if (quit)
125 return EOK;
126
127 /* XXX Crude way of detecting text mode */
128 if (w < 256) {
129 /* Create dummy font for text mode */
130 rc = gfx_typeface_create(gc, &tface);
131 if (rc != EOK) {
132 printf("Error creating typeface\n");
133 goto error;
134 }
135
136 rc = gfx_font_create_textmode(tface, &font);
137 if (rc != EOK) {
138 printf("Error creating font\n");
139 goto error;
140 }
141
142 vpad = 0;
143 } else {
144 /* Load font */
145 rc = gfx_typeface_open(gc, "/data/font/helena.tpf", &tface);
146 if (rc != EOK) {
147 printf("Error opening typeface\n");
148 goto error;
149 }
150
151 finfo = gfx_typeface_first_font(tface);
152 if (finfo == NULL) {
153 printf("Typeface contains no font.\n");
154 rc = ENOENT;
155 goto error;
156 }
157
158 rc = gfx_font_open(finfo, &font);
159 if (rc != EOK) {
160 printf("Error opening font.\n");
161 goto error;
162 }
163
164 vpad = 5;
165 }
166
167 return EOK;
168error:
169 if (tface != NULL)
170 gfx_typeface_destroy(tface);
171 return rc;
172}
173
174/** Finalize demo font. */
175static void demo_font_fini(void)
176{
177 if (font == NULL)
178 return;
179
180 gfx_font_close(font);
181 font = NULL;
182
183 gfx_typeface_destroy(tface);
184 tface = NULL;
185}
186
187/** Start a new demo screen.
188 *
189 * Clear the screen, display a status line and set up clipping.
190 *
191 * @param gc Graphic context
192 * @param w Width
193 * @param h Height
194 * @param text Demo screen description
195 * @return EOK on success or an error code
196 */
197static errno_t demo_begin(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h,
198 const char *text)
199{
200 gfx_text_fmt_t fmt;
201 gfx_font_metrics_t metrics;
202 gfx_coord2_t pos;
203 gfx_color_t *color;
204 gfx_rect_t rect;
205 gfx_coord_t height;
206 errno_t rc;
207
208 rc = gfx_set_clip_rect(gc, NULL);
209 if (rc != EOK)
210 return rc;
211
212 rc = clear_scr(gc, w, h);
213 if (rc != EOK)
214 return rc;
215
216 if (font != NULL) {
217 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
218 if (rc != EOK)
219 goto error;
220
221 gfx_text_fmt_init(&fmt);
222 fmt.color = color;
223 fmt.halign = gfx_halign_center;
224 fmt.valign = gfx_valign_bottom;
225
226 pos.x = w / 2;
227 pos.y = h - 1;
228 rc = gfx_puttext(font, &pos, &fmt, text);
229 if (rc != EOK) {
230 printf("Error rendering text.\n");
231 gfx_color_delete(color);
232 goto error;
233 }
234
235 gfx_color_delete(color);
236
237 gfx_font_get_metrics(font, &metrics);
238 height = metrics.ascent + metrics.descent + 1;
239 } else {
240 height = 0;
241 }
242
243 rect.p0.x = 0;
244 rect.p0.y = 0;
245 rect.p1.x = w;
246 rect.p1.y = h - height - vpad;
247 rc = gfx_set_clip_rect(gc, &rect);
248 if (rc != EOK)
249 return rc;
250
251 return EOK;
252error:
253 return rc;
254}
255
256/** Run rectangle demo on a graphic context.
257 *
258 * @param gc Graphic context
259 * @param w Width
260 * @param h Height
261 */
262static errno_t demo_rects(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
263{
264 gfx_color_t *color = NULL;
265 gfx_rect_t rect;
266 int i, j;
267 errno_t rc;
268
269 if (quit)
270 return EOK;
271
272 rc = demo_begin(gc, w, h, "Rectangle rendering");
273 if (rc != EOK)
274 return rc;
275
276 for (j = 0; j < 10; j++) {
277 rc = gfx_color_new_rgb_i16(rand() % 0x10000, rand() % 0x10000,
278 rand() % 0x10000, &color);
279 if (rc != EOK)
280 return rc;
281
282 rc = gfx_set_color(gc, color);
283 if (rc != EOK)
284 return rc;
285
286 for (i = 0; i < 10; i++) {
287 rect.p0.x = rand() % (w - 1);
288 rect.p0.y = rand() % (h - 1);
289 rect.p1.x = rect.p0.x + rand() % (w - 1 - rect.p0.x);
290 rect.p1.y = rect.p0.y + rand() % (h - 1 - rect.p0.y);
291
292 rc = gfx_fill_rect(gc, &rect);
293 if (rc != EOK)
294 return rc;
295 }
296
297 gfx_color_delete(color);
298
299 fibril_usleep(500 * 1000);
300
301 if (quit)
302 break;
303 }
304
305 return EOK;
306}
307
308/** Fill bitmap with tartan pattern.
309 *
310 * @param bitmap Bitmap
311 * @param w Bitmap width
312 * @param h Bitmap height
313 * @return EOK on success or an error code
314 */
315static errno_t bitmap_tartan(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
316{
317 int i, j;
318 pixelmap_t pixelmap;
319 gfx_bitmap_alloc_t alloc;
320 errno_t rc;
321
322 rc = gfx_bitmap_get_alloc(bitmap, &alloc);
323 if (rc != EOK)
324 return rc;
325
326 /* In absence of anything else, use pixelmap */
327 pixelmap.width = w;
328 pixelmap.height = h;
329 pixelmap.data = alloc.pixels;
330
331 for (i = 0; i < w; i++) {
332 for (j = 0; j < h; j++) {
333 pixelmap_put_pixel(&pixelmap, i, j,
334 PIXEL(0, (i % 30) < 3 ? 255 : 0,
335 (j % 30) < 3 ? 255 : 0, i / 2));
336 }
337 }
338
339 return EOK;
340}
341
342/** Fill bitmap with moire pattern.
343 *
344 * @param bitmap Bitmap
345 * @param w Bitmap width
346 * @param h Bitmap height
347 * @return EOK on success or an error code
348 */
349static errno_t bitmap_moire(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
350{
351 int i, j;
352 int k;
353 pixelmap_t pixelmap;
354 gfx_bitmap_alloc_t alloc;
355 errno_t rc;
356
357 rc = gfx_bitmap_get_alloc(bitmap, &alloc);
358 if (rc != EOK)
359 return rc;
360
361 /* In absence of anything else, use pixelmap */
362 pixelmap.width = w;
363 pixelmap.height = h;
364 pixelmap.data = alloc.pixels;
365
366 for (i = 0; i < w; i++) {
367 for (j = 0; j < h; j++) {
368 k = i * i + j * j;
369 pixelmap_put_pixel(&pixelmap, i, j,
370 PIXEL(0, k, k, k));
371 }
372 }
373
374 return EOK;
375}
376
377/** Render circle to a bitmap.
378 *
379 * @param bitmap Bitmap
380 * @param w Bitmap width
381 * @param h Bitmap height
382 * @return EOK on success or an error code
383 */
384static errno_t bitmap_circle(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
385{
386 int i, j;
387 int k;
388 pixelmap_t pixelmap;
389 gfx_bitmap_alloc_t alloc;
390 errno_t rc;
391
392 rc = gfx_bitmap_get_alloc(bitmap, &alloc);
393 if (rc != EOK)
394 return rc;
395
396 /* In absence of anything else, use pixelmap */
397 pixelmap.width = w;
398 pixelmap.height = h;
399 pixelmap.data = alloc.pixels;
400
401 for (i = 0; i < w; i++) {
402 for (j = 0; j < h; j++) {
403 k = i * i + j * j;
404 pixelmap_put_pixel(&pixelmap, i, j,
405 k < w * w / 2 ? PIXEL(0, 0, 255, 0) :
406 PIXEL(0, 255, 0, 255));
407 }
408 }
409
410 return EOK;
411}
412
413/** Run bitmap demo on a graphic context.
414 *
415 * @param gc Graphic context
416 * @param w Width
417 * @param h Height
418 */
419static errno_t demo_bitmap(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
420{
421 gfx_bitmap_t *bitmap;
422 gfx_bitmap_params_t params;
423 int i, j;
424 gfx_coord2_t offs;
425 gfx_rect_t srect;
426 errno_t rc;
427
428 if (quit)
429 return EOK;
430
431 rc = demo_begin(gc, w, h, "Bitmap rendering without offset");
432 if (rc != EOK)
433 return rc;
434
435 gfx_bitmap_params_init(&params);
436 params.rect.p0.x = 0;
437 params.rect.p0.y = 0;
438 params.rect.p1.x = w;
439 params.rect.p1.y = h;
440
441 rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
442 if (rc != EOK)
443 return rc;
444
445 rc = bitmap_tartan(bitmap, w, h);
446 if (rc != EOK)
447 goto error;
448
449 for (j = 0; j < 10; j++) {
450 for (i = 0; i < 5; i++) {
451 srect.p0.x = rand() % (w - 40);
452 srect.p0.y = rand() % (h - 20);
453 srect.p1.x = srect.p0.x + rand() % (w - srect.p0.x);
454 srect.p1.y = srect.p0.y + rand() % (h - srect.p0.y);
455 offs.x = 0;
456 offs.y = 0;
457
458 rc = gfx_bitmap_render(bitmap, &srect, &offs);
459 if (rc != EOK)
460 goto error;
461 fibril_usleep(250 * 1000);
462
463 if (quit)
464 goto out;
465 }
466 }
467
468out:
469 gfx_bitmap_destroy(bitmap);
470
471 return EOK;
472error:
473 gfx_bitmap_destroy(bitmap);
474 return rc;
475}
476
477/** Run second bitmap demo on a graphic context.
478 *
479 * @param gc Graphic context
480 * @param w Width
481 * @param h Height
482 */
483static errno_t demo_bitmap2(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
484{
485 gfx_bitmap_t *bitmap;
486 gfx_bitmap_params_t params;
487 int i, j;
488 gfx_coord2_t offs;
489 errno_t rc;
490
491 if (quit)
492 return EOK;
493
494 rc = demo_begin(gc, w, h, "Bitmap rendering with offset");
495 if (rc != EOK)
496 return rc;
497
498 gfx_bitmap_params_init(&params);
499 params.rect.p0.x = 0;
500 params.rect.p0.y = 0;
501 params.rect.p1.x = 40;
502 params.rect.p1.y = 20;
503
504 rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
505 if (rc != EOK)
506 return rc;
507
508 rc = bitmap_moire(bitmap, 40, 20);
509 if (rc != EOK)
510 goto error;
511
512 for (j = 0; j < 10; j++) {
513 for (i = 0; i < 10; i++) {
514 offs.x = rand() % (w - 40);
515 offs.y = rand() % (h - 20);
516
517 rc = gfx_bitmap_render(bitmap, NULL, &offs);
518 if (rc != EOK)
519 goto error;
520 }
521
522 fibril_usleep(500 * 1000);
523
524 if (quit)
525 break;
526 }
527
528 gfx_bitmap_destroy(bitmap);
529
530 return EOK;
531error:
532 gfx_bitmap_destroy(bitmap);
533 return rc;
534}
535
536/** Run bitmap color key demo on a graphic context.
537 *
538 * @param gc Graphic context
539 * @param w Width
540 * @param h Height
541 */
542static errno_t demo_bitmap_kc(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
543{
544 gfx_bitmap_t *bitmap;
545 gfx_bitmap_params_t params;
546 int i, j;
547 gfx_coord2_t offs;
548 errno_t rc;
549
550 if (quit)
551 return EOK;
552
553 rc = demo_begin(gc, w, h, "Bitmap rendering with color key");
554 if (rc != EOK)
555 return rc;
556
557 gfx_bitmap_params_init(&params);
558 params.rect.p0.x = 0;
559 params.rect.p0.y = 0;
560 params.rect.p1.x = 40;
561 params.rect.p1.y = 40;
562 params.flags = bmpf_color_key;
563 params.key_color = PIXEL(0, 255, 0, 255);
564
565 rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
566 if (rc != EOK)
567 return rc;
568
569 rc = bitmap_circle(bitmap, 40, 40);
570 if (rc != EOK)
571 goto error;
572
573 for (j = 0; j < 10; j++) {
574 for (i = 0; i < 10; i++) {
575 offs.x = j * 20 + i * 20;
576 offs.y = i * 20;
577
578 rc = gfx_bitmap_render(bitmap, NULL, &offs);
579 if (rc != EOK)
580 goto error;
581 }
582
583 fibril_usleep(500 * 1000);
584
585 if (quit)
586 break;
587 }
588
589 gfx_bitmap_destroy(bitmap);
590
591 return EOK;
592error:
593 gfx_bitmap_destroy(bitmap);
594 return rc;
595}
596
597/** Run text demo on a graphic context.
598 *
599 * @param gc Graphic context
600 * @param w Width
601 * @param h Height
602 */
603static errno_t demo_text(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
604{
605 gfx_color_t *color = NULL;
606 gfx_rect_t rect;
607 gfx_typeface_t *tface = NULL;
608 gfx_font_info_t *finfo;
609 gfx_font_t *font = NULL;
610 gfx_coord2_t pos;
611 gfx_text_fmt_t fmt;
612 int i;
613 errno_t rc;
614
615 if (quit)
616 return EOK;
617
618 /* XXX Crude way of detecting text mode */
619 if (w < 256) {
620 /* Create dummy font for text mode */
621 rc = gfx_typeface_create(gc, &tface);
622 if (rc != EOK) {
623 printf("Error creating typeface\n");
624 goto error;
625 }
626
627 rc = gfx_font_create_textmode(tface, &font);
628 if (rc != EOK) {
629 printf("Error creating font\n");
630 goto error;
631 }
632 } else {
633 /* Load font */
634 rc = gfx_typeface_open(gc, "/data/font/helena.tpf", &tface);
635 if (rc != EOK) {
636 printf("Error opening typeface\n");
637 goto error;
638 }
639
640 finfo = gfx_typeface_first_font(tface);
641 if (finfo == NULL) {
642 printf("Typeface contains no font.\n");
643 rc = ENOENT;
644 goto error;
645 }
646
647 rc = gfx_font_open(finfo, &font);
648 if (rc != EOK) {
649 printf("Error opening font.\n");
650 goto error;
651 }
652 }
653
654 rc = demo_begin(gc, w, h, "Text rendering");
655 if (rc != EOK)
656 goto error;
657
658 /* Vertical bars */
659
660 for (i = 0; i < 20; i++) {
661 rc = gfx_color_new_rgb_i16(0, 0x8000 * i / 20,
662 0x8000 * i / 20, &color);
663 if (rc != EOK)
664 goto error;
665
666 rc = gfx_set_color(gc, color);
667 if (rc != EOK)
668 goto error;
669
670 rect.p0.x = w * i / 20;
671 rect.p0.y = 0;
672 rect.p1.x = w * (i + 1) / 20;
673 rect.p1.y = h;
674
675 rc = gfx_fill_rect(gc, &rect);
676 if (rc != EOK)
677 goto error;
678
679 gfx_color_delete(color);
680 }
681
682 rc = gfx_color_new_rgb_i16(0, 0, 0x8000, &color);
683 if (rc != EOK)
684 goto error;
685
686 rc = gfx_set_color(gc, color);
687 if (rc != EOK)
688 goto error;
689
690 rect.p0.x = w / 20;
691 rect.p0.y = 1 * h / 15;
692 rect.p1.x = w - w / 20;
693 rect.p1.y = 4 * h / 15;
694
695 rc = gfx_fill_rect(gc, &rect);
696 if (rc != EOK)
697 goto error;
698
699 gfx_color_delete(color);
700
701 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
702 if (rc != EOK)
703 goto error;
704
705 gfx_text_fmt_init(&fmt);
706 fmt.color = color;
707
708 pos.x = rect.p0.x;
709 pos.y = rect.p0.y;
710 rc = gfx_puttext(font, &pos, &fmt, "Top left");
711 if (rc != EOK) {
712 printf("Error rendering text.\n");
713 goto error;
714 }
715
716 pos.x = (rect.p0.x + rect.p1.x - 1) / 2;
717 pos.y = rect.p0.y;
718 fmt.halign = gfx_halign_center;
719 rc = gfx_puttext(font, &pos, &fmt, "Top center");
720 if (rc != EOK)
721 goto error;
722
723 pos.x = rect.p1.x - 1;
724 pos.y = rect.p0.y;
725 fmt.halign = gfx_halign_right;
726 rc = gfx_puttext(font, &pos, &fmt, "Top right");
727 if (rc != EOK)
728 goto error;
729
730 fmt.valign = gfx_valign_center;
731
732 pos.x = rect.p0.x;
733 pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
734 fmt.halign = gfx_halign_left;
735 rc = gfx_puttext(font, &pos, &fmt, "Center left");
736 if (rc != EOK)
737 goto error;
738
739 pos.x = (rect.p0.x + rect.p1.x - 1) / 2;
740 pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
741 fmt.halign = gfx_halign_center;
742 rc = gfx_puttext(font, &pos, &fmt, "Center");
743 if (rc != EOK)
744 goto error;
745
746 pos.x = rect.p1.x - 1;
747 pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
748 fmt.halign = gfx_halign_right;
749 rc = gfx_puttext(font, &pos, &fmt, "Center right");
750 if (rc != EOK)
751 goto error;
752
753 fmt.valign = gfx_valign_bottom;
754
755 pos.x = rect.p0.x;
756 pos.y = rect.p1.y - 1;
757 fmt.halign = gfx_halign_left;
758 rc = gfx_puttext(font, &pos, &fmt, "Bottom left");
759 if (rc != EOK)
760 goto error;
761
762 pos.x = (rect.p0.x + rect.p1.x - 1) / 2;
763 pos.y = rect.p1.y - 1;
764 fmt.halign = gfx_halign_center;
765 rc = gfx_puttext(font, &pos, &fmt, "Bottom center");
766 if (rc != EOK)
767 goto error;
768
769 pos.x = rect.p1.x - 1;
770 pos.y = rect.p1.y - 1;
771 fmt.halign = gfx_halign_right;
772 rc = gfx_puttext(font, &pos, &fmt, "Bottom right");
773 if (rc != EOK)
774 goto error;
775
776 gfx_color_delete(color);
777
778 gfx_text_fmt_init(&fmt);
779
780 for (i = 0; i < 8; i++) {
781 rc = gfx_color_new_rgb_i16((i & 4) ? 0xffff : 0,
782 (i & 2) ? 0xffff : 0, (i & 1) ? 0xffff : 0, &color);
783 if (rc != EOK)
784 goto error;
785
786 fmt.color = color;
787
788 pos.x = w / 20;
789 pos.y = (6 + i) * h / 15;
790 rc = gfx_puttext(font, &pos, &fmt, "The quick brown fox jumps over the lazy dog.");
791 if (rc != EOK)
792 goto error;
793
794 gfx_color_delete(color);
795 }
796
797 for (i = 0; i < 10; i++) {
798 fibril_usleep(500 * 1000);
799 if (quit)
800 break;
801 }
802
803 gfx_font_close(font);
804 gfx_typeface_destroy(tface);
805 return EOK;
806error:
807 if (font != NULL)
808 gfx_font_close(font);
809 if (tface != NULL)
810 gfx_typeface_destroy(tface);
811 return rc;
812}
813
814/** Run clipping demo on a graphic context.
815 *
816 * @param gc Graphic context
817 * @param w Width
818 * @param h Height
819 */
820static errno_t demo_clip(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
821{
822 gfx_bitmap_t *bitmap;
823 gfx_color_t *color;
824 gfx_bitmap_params_t params;
825 int i, j;
826 gfx_coord2_t offs;
827 gfx_rect_t rect;
828 errno_t rc;
829
830 if (quit)
831 return EOK;
832
833 rc = demo_begin(gc, w, h, "Clipping demonstration");
834 if (rc != EOK)
835 return rc;
836
837 gfx_bitmap_params_init(&params);
838 params.rect.p0.x = 0;
839 params.rect.p0.y = 0;
840 params.rect.p1.x = 40;
841 params.rect.p1.y = 20;
842
843 rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
844 if (rc != EOK)
845 return rc;
846
847 rc = bitmap_moire(bitmap, 40, 20);
848 if (rc != EOK)
849 goto error;
850
851 for (j = 0; j < 10; j++) {
852 rect.p0.x = w / 8;
853 rect.p0.y = h / 8;
854 rect.p1.x = w * 7 / 8;
855 rect.p1.y = h * 3 / 8;
856
857 rc = gfx_set_clip_rect(gc, &rect);
858 if (rc != EOK)
859 return rc;
860
861 rc = gfx_color_new_rgb_i16(rand() % 0x10000, rand() % 0x10000,
862 rand() % 0x10000, &color);
863 if (rc != EOK)
864 return rc;
865
866 rc = gfx_set_color(gc, color);
867 if (rc != EOK)
868 return rc;
869
870 for (i = 0; i < 10; i++) {
871 rect.p0.x = rand() % (w - 1);
872 rect.p0.y = rand() % (h - 1);
873 rect.p1.x = rect.p0.x + rand() % (w - 1 - rect.p0.x);
874 rect.p1.y = rect.p0.y + rand() % (h - 1 - rect.p0.y);
875
876 rc = gfx_fill_rect(gc, &rect);
877 if (rc != EOK)
878 return rc;
879 }
880
881 gfx_color_delete(color);
882
883 rect.p0.x = w / 8;
884 rect.p0.y = h * 5 / 8;
885 rect.p1.x = w * 7 / 8;
886 rect.p1.y = h * 7 / 8;
887
888 rc = gfx_set_clip_rect(gc, &rect);
889 if (rc != EOK)
890 return rc;
891
892 for (i = 0; i < 10; i++) {
893 offs.x = rand() % (w - 40);
894 offs.y = rand() % (h - 20);
895
896 rc = gfx_bitmap_render(bitmap, NULL, &offs);
897 if (rc != EOK)
898 goto error;
899 }
900
901 fibril_usleep(500 * 1000);
902
903 if (quit)
904 break;
905 }
906
907 (void) gfx_set_clip_rect(gc, NULL);
908 gfx_bitmap_destroy(bitmap);
909 return EOK;
910error:
911 (void) gfx_set_clip_rect(gc, NULL);
912 gfx_bitmap_destroy(bitmap);
913 return rc;
914}
915
916/** Run demo loop on a graphic context.
917 *
918 * @param gc Graphic context
919 * @param w Width
920 * @param h Height
921 */
922static errno_t demo_loop(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
923{
924 errno_t rc;
925
926 (void) demo_font_init(gc, w, h);
927
928 while (!quit) {
929 rc = demo_rects(gc, w, h);
930 if (rc != EOK)
931 goto error;
932
933 rc = demo_bitmap(gc, w, h);
934 if (rc != EOK)
935 goto error;
936
937 rc = demo_bitmap2(gc, w, h);
938 if (rc != EOK)
939 goto error;
940
941 rc = demo_bitmap_kc(gc, w, h);
942 if (rc != EOK)
943 goto error;
944
945 rc = demo_text(gc, w, h);
946 if (rc != EOK)
947 goto error;
948
949 rc = demo_clip(gc, w, h);
950 if (rc != EOK)
951 goto error;
952 }
953
954 demo_font_fini();
955 return EOK;
956error:
957 demo_font_fini();
958 return rc;
959}
960
961/** Run demo on console. */
962static errno_t demo_console(void)
963{
964 console_ctrl_t *con = NULL;
965 console_gc_t *cgc = NULL;
966 gfx_context_t *gc;
967 errno_t rc;
968
969 printf("Init console..\n");
970 con = console_init(stdin, stdout);
971 if (con == NULL)
972 return EIO;
973
974 printf("Create console GC\n");
975 rc = console_gc_create(con, stdout, &cgc);
976 if (rc != EOK)
977 return rc;
978
979 gc = console_gc_get_ctx(cgc);
980
981 rc = demo_loop(gc, 80, 25);
982 if (rc != EOK)
983 return rc;
984
985 rc = console_gc_delete(cgc);
986 if (rc != EOK)
987 return rc;
988
989 return EOK;
990}
991
992/** Run demo on UI. */
993static errno_t demo_ui(const char *display_spec)
994{
995 ui_t *ui = NULL;
996 ui_wnd_params_t params;
997 ui_window_t *window = NULL;
998 gfx_context_t *gc;
999 gfx_rect_t rect;
1000 gfx_rect_t wrect;
1001 gfx_coord2_t off;
1002 errno_t rc;
1003
1004 printf("Init UI..\n");
1005
1006 rc = ui_create(display_spec, &ui);
1007 if (rc != EOK) {
1008 printf("Error initializing UI (%s)\n", display_spec);
1009 goto error;
1010 }
1011
1012 rect.p0.x = 0;
1013 rect.p0.y = 0;
1014 rect.p1.x = 400;
1015 rect.p1.y = 300;
1016
1017 ui_wnd_params_init(&params);
1018 params.caption = "GFX Demo";
1019
1020 /*
1021 * Compute window rectangle such that application area corresponds
1022 * to rect
1023 */
1024 ui_wdecor_rect_from_app(params.style, &rect, &wrect);
1025 off = wrect.p0;
1026 gfx_rect_rtranslate(&off, &wrect, &params.rect);
1027
1028 rc = ui_window_create(ui, &params, &window);
1029 if (rc != EOK) {
1030 printf("Error creating window.\n");
1031 goto error;
1032 }
1033
1034 ui_window_set_cb(window, &ui_window_cb, NULL);
1035
1036 rc = ui_window_get_app_gc(window, &gc);
1037 if (rc != EOK) {
1038 printf("Error creating graphic context.\n");
1039 goto error;
1040 }
1041
1042 task_retval(0);
1043
1044 rc = demo_loop(gc, rect.p1.x, rect.p1.y);
1045 if (rc != EOK)
1046 goto error;
1047
1048 ui_window_destroy(window);
1049 ui_destroy(ui);
1050
1051 return EOK;
1052error:
1053 if (window != NULL)
1054 ui_window_destroy(window);
1055 if (ui != NULL)
1056 ui_destroy(ui);
1057 return rc;
1058}
1059
1060/** Run demo on display server. */
1061static errno_t demo_display(const char *display_svc)
1062{
1063 display_t *display = NULL;
1064 gfx_context_t *gc;
1065 display_wnd_params_t params;
1066 display_window_t *window = NULL;
1067 errno_t rc;
1068
1069 printf("Init display..\n");
1070
1071 rc = display_open(display_svc, &display);
1072 if (rc != EOK) {
1073 printf("Error opening display.\n");
1074 return rc;
1075 }
1076
1077 display_wnd_params_init(&params);
1078 params.rect.p0.x = 0;
1079 params.rect.p0.y = 0;
1080 params.rect.p1.x = 400;
1081 params.rect.p1.y = 300;
1082
1083 rc = display_window_create(display, &params, &wnd_cb, NULL, &window);
1084 if (rc != EOK) {
1085 printf("Error creating window.\n");
1086 return rc;
1087 }
1088
1089 rc = display_window_get_gc(window, &gc);
1090 if (rc != EOK) {
1091 printf("Error getting graphics context.\n");
1092 return rc;
1093 }
1094
1095 task_retval(0);
1096
1097 rc = demo_loop(gc, 400, 300);
1098 if (rc != EOK)
1099 return rc;
1100
1101 rc = gfx_context_delete(gc);
1102 if (rc != EOK)
1103 return rc;
1104
1105 display_window_destroy(window);
1106 display_close(display);
1107
1108 return EOK;
1109}
1110
1111static void wnd_close_event(void *arg)
1112{
1113 printf("Close event\n");
1114 quit = true;
1115}
1116
1117static void wnd_kbd_event(void *arg, kbd_event_t *event)
1118{
1119 printf("Keyboard event type=%d key=%d\n", event->type, event->key);
1120 if (event->type == KEY_PRESS)
1121 quit = true;
1122}
1123
1124static void uiwnd_close_event(ui_window_t *window, void *arg)
1125{
1126 printf("Close event\n");
1127 quit = true;
1128}
1129
1130static void uiwnd_kbd_event(ui_window_t *window, void *arg, kbd_event_t *event)
1131{
1132 printf("Keyboard event type=%d key=%d\n", event->type, event->key);
1133 if (event->type == KEY_PRESS)
1134 quit = true;
1135}
1136
1137static void print_syntax(void)
1138{
1139 printf("Syntax: gfxdemo [-d <display>] {console|display|ui}\n");
1140}
1141
1142int main(int argc, char *argv[])
1143{
1144 errno_t rc;
1145 const char *display_svc = DISPLAY_DEFAULT;
1146 int i;
1147
1148 i = 1;
1149 while (i < argc && argv[i][0] == '-') {
1150 if (str_cmp(argv[i], "-d") == 0) {
1151 ++i;
1152 if (i >= argc) {
1153 printf("Argument missing.\n");
1154 print_syntax();
1155 return 1;
1156 }
1157
1158 display_svc = argv[i++];
1159 } else {
1160 printf("Invalid option '%s'.\n", argv[i]);
1161 print_syntax();
1162 return 1;
1163 }
1164 }
1165
1166 if (i >= argc || str_cmp(argv[i], "display") == 0) {
1167 rc = demo_display(display_svc);
1168 if (rc != EOK)
1169 return 1;
1170 } else if (str_cmp(argv[i], "console") == 0) {
1171 rc = demo_console();
1172 if (rc != EOK)
1173 return 1;
1174 } else if (str_cmp(argv[i], "ui") == 0) {
1175 rc = demo_ui(display_svc);
1176 if (rc != EOK)
1177 return 1;
1178 } else {
1179 print_syntax();
1180 return 1;
1181 }
1182}
1183
1184/** @}
1185 */
Note: See TracBrowser for help on using the repository browser.