source: mainline/uspace/app/gfxdemo/gfxdemo.c@ da15002

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

No need to load font twice

  • Property mode set to 100644
File size: 22.1 KB
RevLine 
[045186b]1/*
[fd11144]2 * Copyright (c) 2020 Jiri Svoboda
[045186b]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
[a3f63ac]35#include <congfx/console.h>
[c8cf261]36#include <display.h>
[9259d20]37#include <fibril.h>
[e0545de]38#include <gfx/bitmap.h>
[045186b]39#include <gfx/color.h>
40#include <gfx/render.h>
[8fa65af0]41#include <gfx/font.h>
42#include <gfx/text.h>
43#include <gfx/typeface.h>
[9259d20]44#include <io/console.h>
[e0545de]45#include <io/pixelmap.h>
[b3c185b6]46#include <stdbool.h>
[9259d20]47#include <stdlib.h>
[00e8290]48#include <str.h>
[5bded44]49#include <task.h>
[b93ec7c0]50#include <ui/ui.h>
51#include <ui/window.h>
52#include <ui/wdecor.h>
[045186b]53
[338d0935]54static void wnd_close_event(void *);
[b3c185b6]55static void wnd_kbd_event(void *, kbd_event_t *);
56
57static display_wnd_cb_t wnd_cb = {
[338d0935]58 .close_event = wnd_close_event,
[b3c185b6]59 .kbd_event = wnd_kbd_event
60};
61
[b93ec7c0]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
[b3c185b6]70static bool quit = false;
[8dbd13d]71static gfx_typeface_t *tface;
72static gfx_font_t *font;
73static gfx_coord_t vpad;
[b3c185b6]74
[587b4cb]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
[8dbd13d]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
[00e8290]256/** Run rectangle demo on a graphic context.
257 *
258 * @param gc Graphic context
[e0545de]259 * @param w Width
260 * @param h Height
[00e8290]261 */
[1822545]262static errno_t demo_rects(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
[045186b]263{
[9259d20]264 gfx_color_t *color = NULL;
265 gfx_rect_t rect;
[e0545de]266 int i, j;
[9259d20]267 errno_t rc;
268
[4f64b7b8]269 if (quit)
270 return EOK;
271
[8dbd13d]272 rc = demo_begin(gc, w, h, "Rectangle rendering");
[587b4cb]273 if (rc != EOK)
274 return rc;
275
[e0545de]276 for (j = 0; j < 10; j++) {
[9259d20]277 rc = gfx_color_new_rgb_i16(rand() % 0x10000, rand() % 0x10000,
278 rand() % 0x10000, &color);
279 if (rc != EOK)
[00e8290]280 return rc;
[9259d20]281
282 rc = gfx_set_color(gc, color);
283 if (rc != EOK)
[00e8290]284 return rc;
[9259d20]285
286 for (i = 0; i < 10; i++) {
[00e8290]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);
[9259d20]291
292 rc = gfx_fill_rect(gc, &rect);
293 if (rc != EOK)
[00e8290]294 return rc;
[9259d20]295 }
296
297 gfx_color_delete(color);
298
299 fibril_usleep(500 * 1000);
[b3c185b6]300
301 if (quit)
302 break;
[9259d20]303 }
[e0545de]304
305 return EOK;
306}
307
[587b4cb]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,
[6a87f28]334 PIXEL(0, (i % 30) < 3 ? 255 : 0,
[587b4cb]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,
[6a87f28]370 PIXEL(0, k, k, k));
[587b4cb]371 }
372 }
373
374 return EOK;
375}
376
[bea947f]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,
[6a87f28]405 k < w * w / 2 ? PIXEL(0, 0, 255, 0) :
[bea947f]406 PIXEL(0, 255, 0, 255));
407 }
408 }
409
410 return EOK;
411}
412
[e0545de]413/** Run bitmap demo on a graphic context.
414 *
415 * @param gc Graphic context
416 * @param w Width
417 * @param h Height
418 */
[1822545]419static errno_t demo_bitmap(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
[e0545de]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;
[587b4cb]427
[4f64b7b8]428 if (quit)
429 return EOK;
430
[8dbd13d]431 rc = demo_begin(gc, w, h, "Bitmap rendering without offset");
[587b4cb]432 if (rc != EOK)
433 return rc;
[e0545de]434
[a8eed5f]435 gfx_bitmap_params_init(&params);
[e0545de]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
[587b4cb]445 rc = bitmap_tartan(bitmap, w, h);
[e0545de]446 if (rc != EOK)
[587b4cb]447 goto error;
[e0545de]448
449 for (j = 0; j < 10; j++) {
450 for (i = 0; i < 5; i++) {
451 srect.p0.x = rand() % (w - 40);
[d18f3b7]452 srect.p0.y = rand() % (h - 20);
[e0545de]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
[0008c0f]458 rc = gfx_bitmap_render(bitmap, &srect, &offs);
459 if (rc != EOK)
460 goto error;
[587b4cb]461 fibril_usleep(250 * 1000);
[b3c185b6]462
463 if (quit)
[4f64b7b8]464 goto out;
[587b4cb]465 }
466 }
467
[4f64b7b8]468out:
[587b4cb]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
[4f64b7b8]491 if (quit)
492 return EOK;
493
[8dbd13d]494 rc = demo_begin(gc, w, h, "Bitmap rendering with offset");
[587b4cb]495 if (rc != EOK)
496 return rc;
497
[b3b00b6]498 gfx_bitmap_params_init(&params);
[587b4cb]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;
[e0545de]520 }
[587b4cb]521
522 fibril_usleep(500 * 1000);
[b3c185b6]523
524 if (quit)
525 break;
[e0545de]526 }
527
528 gfx_bitmap_destroy(bitmap);
529
530 return EOK;
[0008c0f]531error:
532 gfx_bitmap_destroy(bitmap);
533 return rc;
[e0545de]534}
[8fa65af0]535
[bea947f]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
[4f64b7b8]550 if (quit)
551 return EOK;
552
[8dbd13d]553 rc = demo_begin(gc, w, h, "Bitmap rendering with color key");
[bea947f]554 if (rc != EOK)
555 return rc;
556
[b3b00b6]557 gfx_bitmap_params_init(&params);
[bea947f]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}
[e0545de]596
[8fa65af0]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_coord2_t pos;
608 gfx_text_fmt_t fmt;
609 int i;
610 errno_t rc;
611
[4f64b7b8]612 if (quit)
613 return EOK;
614
[8dbd13d]615 rc = demo_begin(gc, w, h, "Text rendering");
[8fa65af0]616 if (rc != EOK)
617 goto error;
618
619 /* Vertical bars */
620
621 for (i = 0; i < 20; i++) {
622 rc = gfx_color_new_rgb_i16(0, 0x8000 * i / 20,
623 0x8000 * i / 20, &color);
624 if (rc != EOK)
625 goto error;
626
627 rc = gfx_set_color(gc, color);
628 if (rc != EOK)
629 goto error;
630
631 rect.p0.x = w * i / 20;
632 rect.p0.y = 0;
633 rect.p1.x = w * (i + 1) / 20;
634 rect.p1.y = h;
635
636 rc = gfx_fill_rect(gc, &rect);
637 if (rc != EOK)
638 goto error;
639
640 gfx_color_delete(color);
641 }
642
643 rc = gfx_color_new_rgb_i16(0, 0, 0x8000, &color);
644 if (rc != EOK)
645 goto error;
646
647 rc = gfx_set_color(gc, color);
648 if (rc != EOK)
649 goto error;
650
651 rect.p0.x = w / 20;
[8dbd13d]652 rect.p0.y = 1 * h / 15;
[8fa65af0]653 rect.p1.x = w - w / 20;
[8dbd13d]654 rect.p1.y = 4 * h / 15;
[8fa65af0]655
656 rc = gfx_fill_rect(gc, &rect);
657 if (rc != EOK)
658 goto error;
659
660 gfx_color_delete(color);
661
662 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
663 if (rc != EOK)
664 goto error;
665
666 gfx_text_fmt_init(&fmt);
[b433f68]667 fmt.color = color;
[8fa65af0]668
669 pos.x = rect.p0.x;
670 pos.y = rect.p0.y;
671 rc = gfx_puttext(font, &pos, &fmt, "Top left");
672 if (rc != EOK) {
673 printf("Error rendering text.\n");
674 goto error;
675 }
676
[8bf9058]677 pos.x = (rect.p0.x + rect.p1.x - 1) / 2;
[8fa65af0]678 pos.y = rect.p0.y;
679 fmt.halign = gfx_halign_center;
680 rc = gfx_puttext(font, &pos, &fmt, "Top center");
681 if (rc != EOK)
682 goto error;
683
[8bf9058]684 pos.x = rect.p1.x - 1;
[8fa65af0]685 pos.y = rect.p0.y;
686 fmt.halign = gfx_halign_right;
687 rc = gfx_puttext(font, &pos, &fmt, "Top right");
688 if (rc != EOK)
689 goto error;
690
691 fmt.valign = gfx_valign_center;
692
693 pos.x = rect.p0.x;
[8bf9058]694 pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
[8fa65af0]695 fmt.halign = gfx_halign_left;
696 rc = gfx_puttext(font, &pos, &fmt, "Center left");
697 if (rc != EOK)
698 goto error;
699
[8bf9058]700 pos.x = (rect.p0.x + rect.p1.x - 1) / 2;
701 pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
[8fa65af0]702 fmt.halign = gfx_halign_center;
703 rc = gfx_puttext(font, &pos, &fmt, "Center");
704 if (rc != EOK)
705 goto error;
706
[8bf9058]707 pos.x = rect.p1.x - 1;
708 pos.y = (rect.p0.y + rect.p1.y - 1) / 2;
[8fa65af0]709 fmt.halign = gfx_halign_right;
710 rc = gfx_puttext(font, &pos, &fmt, "Center right");
711 if (rc != EOK)
712 goto error;
713
714 fmt.valign = gfx_valign_bottom;
715
716 pos.x = rect.p0.x;
[8bf9058]717 pos.y = rect.p1.y - 1;
[8fa65af0]718 fmt.halign = gfx_halign_left;
719 rc = gfx_puttext(font, &pos, &fmt, "Bottom left");
720 if (rc != EOK)
721 goto error;
722
[8bf9058]723 pos.x = (rect.p0.x + rect.p1.x - 1) / 2;
724 pos.y = rect.p1.y - 1;
[8fa65af0]725 fmt.halign = gfx_halign_center;
726 rc = gfx_puttext(font, &pos, &fmt, "Bottom center");
727 if (rc != EOK)
728 goto error;
729
[8bf9058]730 pos.x = rect.p1.x - 1;
731 pos.y = rect.p1.y - 1;
[8fa65af0]732 fmt.halign = gfx_halign_right;
733 rc = gfx_puttext(font, &pos, &fmt, "Bottom right");
734 if (rc != EOK)
735 goto error;
736
[0d62c10]737 gfx_color_delete(color);
738
[8fa65af0]739 gfx_text_fmt_init(&fmt);
740
741 for (i = 0; i < 8; i++) {
[0d62c10]742 rc = gfx_color_new_rgb_i16((i & 4) ? 0xffff : 0,
743 (i & 2) ? 0xffff : 0, (i & 1) ? 0xffff : 0, &color);
744 if (rc != EOK)
745 goto error;
746
[b433f68]747 fmt.color = color;
[0d62c10]748
[8fa65af0]749 pos.x = w / 20;
[8dbd13d]750 pos.y = (6 + i) * h / 15;
[8fa65af0]751 rc = gfx_puttext(font, &pos, &fmt, "The quick brown fox jumps over the lazy dog.");
752 if (rc != EOK)
753 goto error;
[0d62c10]754
755 gfx_color_delete(color);
[8fa65af0]756 }
757
758 for (i = 0; i < 10; i++) {
759 fibril_usleep(500 * 1000);
760 if (quit)
761 break;
762 }
763
764 return EOK;
765error:
766 return rc;
767}
768
[1167ad34]769/** Run clipping demo on a graphic context.
770 *
771 * @param gc Graphic context
772 * @param w Width
773 * @param h Height
774 */
775static errno_t demo_clip(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
776{
777 gfx_bitmap_t *bitmap;
778 gfx_color_t *color;
779 gfx_bitmap_params_t params;
780 int i, j;
781 gfx_coord2_t offs;
782 gfx_rect_t rect;
783 errno_t rc;
784
785 if (quit)
786 return EOK;
787
[8dbd13d]788 rc = demo_begin(gc, w, h, "Clipping demonstration");
[1167ad34]789 if (rc != EOK)
790 return rc;
791
792 gfx_bitmap_params_init(&params);
793 params.rect.p0.x = 0;
794 params.rect.p0.y = 0;
795 params.rect.p1.x = 40;
796 params.rect.p1.y = 20;
797
798 rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
799 if (rc != EOK)
800 return rc;
801
802 rc = bitmap_moire(bitmap, 40, 20);
803 if (rc != EOK)
804 goto error;
805
806 for (j = 0; j < 10; j++) {
807 rect.p0.x = w / 8;
808 rect.p0.y = h / 8;
809 rect.p1.x = w * 7 / 8;
810 rect.p1.y = h * 3 / 8;
811
812 rc = gfx_set_clip_rect(gc, &rect);
813 if (rc != EOK)
814 return rc;
815
816 rc = gfx_color_new_rgb_i16(rand() % 0x10000, rand() % 0x10000,
817 rand() % 0x10000, &color);
818 if (rc != EOK)
819 return rc;
820
821 rc = gfx_set_color(gc, color);
822 if (rc != EOK)
823 return rc;
824
825 for (i = 0; i < 10; i++) {
826 rect.p0.x = rand() % (w - 1);
827 rect.p0.y = rand() % (h - 1);
828 rect.p1.x = rect.p0.x + rand() % (w - 1 - rect.p0.x);
829 rect.p1.y = rect.p0.y + rand() % (h - 1 - rect.p0.y);
830
831 rc = gfx_fill_rect(gc, &rect);
832 if (rc != EOK)
833 return rc;
834 }
835
836 gfx_color_delete(color);
837
838 rect.p0.x = w / 8;
839 rect.p0.y = h * 5 / 8;
840 rect.p1.x = w * 7 / 8;
841 rect.p1.y = h * 7 / 8;
842
843 rc = gfx_set_clip_rect(gc, &rect);
844 if (rc != EOK)
845 return rc;
846
847 for (i = 0; i < 10; i++) {
848 offs.x = rand() % (w - 40);
849 offs.y = rand() % (h - 20);
850
851 rc = gfx_bitmap_render(bitmap, NULL, &offs);
852 if (rc != EOK)
853 goto error;
854 }
855
856 fibril_usleep(500 * 1000);
857
858 if (quit)
859 break;
860 }
861
862 (void) gfx_set_clip_rect(gc, NULL);
863 gfx_bitmap_destroy(bitmap);
864 return EOK;
865error:
866 (void) gfx_set_clip_rect(gc, NULL);
867 gfx_bitmap_destroy(bitmap);
868 return rc;
869}
870
[e0545de]871/** Run demo loop on a graphic context.
872 *
873 * @param gc Graphic context
874 * @param w Width
875 * @param h Height
876 */
[1822545]877static errno_t demo_loop(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
[e0545de]878{
879 errno_t rc;
880
[8dbd13d]881 (void) demo_font_init(gc, w, h);
882
[b3c185b6]883 while (!quit) {
[e0545de]884 rc = demo_rects(gc, w, h);
885 if (rc != EOK)
[8dbd13d]886 goto error;
[e0545de]887
888 rc = demo_bitmap(gc, w, h);
889 if (rc != EOK)
[8dbd13d]890 goto error;
[587b4cb]891
892 rc = demo_bitmap2(gc, w, h);
893 if (rc != EOK)
[8dbd13d]894 goto error;
[bea947f]895
896 rc = demo_bitmap_kc(gc, w, h);
897 if (rc != EOK)
[8dbd13d]898 goto error;
[8fa65af0]899
900 rc = demo_text(gc, w, h);
901 if (rc != EOK)
[8dbd13d]902 goto error;
[1167ad34]903
904 rc = demo_clip(gc, w, h);
905 if (rc != EOK)
[8dbd13d]906 goto error;
[e0545de]907 }
[b3c185b6]908
[8dbd13d]909 demo_font_fini();
[b3c185b6]910 return EOK;
[8dbd13d]911error:
912 demo_font_fini();
913 return rc;
[00e8290]914}
915
916/** Run demo on console. */
917static errno_t demo_console(void)
918{
919 console_ctrl_t *con = NULL;
920 console_gc_t *cgc = NULL;
921 gfx_context_t *gc;
922 errno_t rc;
923
924 printf("Init console..\n");
925 con = console_init(stdin, stdout);
926 if (con == NULL)
927 return EIO;
928
929 printf("Create console GC\n");
930 rc = console_gc_create(con, stdout, &cgc);
931 if (rc != EOK)
932 return rc;
933
934 gc = console_gc_get_ctx(cgc);
935
[e0545de]936 rc = demo_loop(gc, 80, 25);
[00e8290]937 if (rc != EOK)
938 return rc;
[9259d20]939
[9be2358]940 rc = console_gc_delete(cgc);
941 if (rc != EOK)
[00e8290]942 return rc;
943
944 return EOK;
945}
946
[b93ec7c0]947/** Run demo on UI. */
948static errno_t demo_ui(const char *display_spec)
[00e8290]949{
[b93ec7c0]950 ui_t *ui = NULL;
951 ui_wnd_params_t params;
952 ui_window_t *window = NULL;
[00e8290]953 gfx_context_t *gc;
[b93ec7c0]954 gfx_rect_t rect;
955 gfx_rect_t wrect;
956 gfx_coord2_t off;
[00e8290]957 errno_t rc;
958
[b93ec7c0]959 printf("Init UI..\n");
[00e8290]960
[b93ec7c0]961 rc = ui_create(display_spec, &ui);
962 if (rc != EOK) {
963 printf("Error initializing UI (%s)\n", display_spec);
964 goto error;
[00e8290]965 }
966
[b93ec7c0]967 rect.p0.x = 0;
968 rect.p0.y = 0;
969 rect.p1.x = 400;
970 rect.p1.y = 300;
[00e8290]971
[b93ec7c0]972 ui_wnd_params_init(&params);
973 params.caption = "GFX Demo";
[00e8290]974
[b93ec7c0]975 /*
976 * Compute window rectangle such that application area corresponds
977 * to rect
978 */
[266ec54]979 ui_wdecor_rect_from_app(params.style, &rect, &wrect);
[b93ec7c0]980 off = wrect.p0;
981 gfx_rect_rtranslate(&off, &wrect, &params.rect);
[00e8290]982
[b93ec7c0]983 rc = ui_window_create(ui, &params, &window);
984 if (rc != EOK) {
985 printf("Error creating window.\n");
986 goto error;
[00e8290]987 }
988
[b93ec7c0]989 ui_window_set_cb(window, &ui_window_cb, NULL);
[00e8290]990
[b93ec7c0]991 rc = ui_window_get_app_gc(window, &gc);
992 if (rc != EOK) {
993 printf("Error creating graphic context.\n");
994 goto error;
995 }
[00e8290]996
[5bded44]997 task_retval(0);
998
[b93ec7c0]999 rc = demo_loop(gc, rect.p1.x, rect.p1.y);
[00e8290]1000 if (rc != EOK)
[b93ec7c0]1001 goto error;
[00e8290]1002
[b93ec7c0]1003 ui_window_destroy(window);
1004 ui_destroy(ui);
[00e8290]1005
1006 return EOK;
[b93ec7c0]1007error:
1008 if (window != NULL)
1009 ui_window_destroy(window);
1010 if (ui != NULL)
1011 ui_destroy(ui);
1012 return rc;
[00e8290]1013}
1014
[c8cf261]1015/** Run demo on display server. */
[fd11144]1016static errno_t demo_display(const char *display_svc)
[c8cf261]1017{
1018 display_t *display = NULL;
1019 gfx_context_t *gc;
[4d9c807]1020 display_wnd_params_t params;
[c8cf261]1021 display_window_t *window = NULL;
1022 errno_t rc;
1023
1024 printf("Init display..\n");
1025
[fd11144]1026 rc = display_open(display_svc, &display);
[c8cf261]1027 if (rc != EOK) {
1028 printf("Error opening display.\n");
1029 return rc;
1030 }
1031
[4d9c807]1032 display_wnd_params_init(&params);
1033 params.rect.p0.x = 0;
1034 params.rect.p0.y = 0;
1035 params.rect.p1.x = 400;
1036 params.rect.p1.y = 300;
1037
1038 rc = display_window_create(display, &params, &wnd_cb, NULL, &window);
[c8cf261]1039 if (rc != EOK) {
1040 printf("Error creating window.\n");
1041 return rc;
1042 }
1043
1044 rc = display_window_get_gc(window, &gc);
1045 if (rc != EOK) {
1046 printf("Error getting graphics context.\n");
[32dde7e8]1047 return rc;
[c8cf261]1048 }
1049
[5bded44]1050 task_retval(0);
1051
[e0545de]1052 rc = demo_loop(gc, 400, 300);
[c8cf261]1053 if (rc != EOK)
1054 return rc;
1055
1056 rc = gfx_context_delete(gc);
1057 if (rc != EOK)
1058 return rc;
1059
[e49b7997]1060 display_window_destroy(window);
1061 display_close(display);
1062
[c8cf261]1063 return EOK;
1064}
1065
[338d0935]1066static void wnd_close_event(void *arg)
1067{
1068 printf("Close event\n");
1069 quit = true;
1070}
1071
[b3c185b6]1072static void wnd_kbd_event(void *arg, kbd_event_t *event)
1073{
1074 printf("Keyboard event type=%d key=%d\n", event->type, event->key);
[5fae123]1075 if (event->type == KEY_PRESS)
1076 quit = true;
[b3c185b6]1077}
1078
[b93ec7c0]1079static void uiwnd_close_event(ui_window_t *window, void *arg)
1080{
1081 printf("Close event\n");
1082 quit = true;
1083}
1084
1085static void uiwnd_kbd_event(ui_window_t *window, void *arg, kbd_event_t *event)
1086{
1087 printf("Keyboard event type=%d key=%d\n", event->type, event->key);
1088 if (event->type == KEY_PRESS)
1089 quit = true;
1090}
1091
[00e8290]1092static void print_syntax(void)
1093{
[bac8acab]1094 printf("Syntax: gfxdemo [-d <display>] {console|display|ui}\n");
[00e8290]1095}
1096
1097int main(int argc, char *argv[])
1098{
1099 errno_t rc;
[fd11144]1100 const char *display_svc = DISPLAY_DEFAULT;
1101 int i;
1102
1103 i = 1;
1104 while (i < argc && argv[i][0] == '-') {
1105 if (str_cmp(argv[i], "-d") == 0) {
1106 ++i;
1107 if (i >= argc) {
1108 printf("Argument missing.\n");
1109 print_syntax();
1110 return 1;
1111 }
1112
1113 display_svc = argv[i++];
1114 } else {
1115 printf("Invalid option '%s'.\n", argv[i]);
1116 print_syntax();
1117 return 1;
1118 }
1119 }
[00e8290]1120
[fd11144]1121 if (i >= argc || str_cmp(argv[i], "display") == 0) {
1122 rc = demo_display(display_svc);
[0b63dc2]1123 if (rc != EOK)
1124 return 1;
[fd11144]1125 } else if (str_cmp(argv[i], "console") == 0) {
[00e8290]1126 rc = demo_console();
1127 if (rc != EOK)
1128 return 1;
[b93ec7c0]1129 } else if (str_cmp(argv[i], "ui") == 0) {
1130 rc = demo_ui(display_svc);
[00e8290]1131 if (rc != EOK)
1132 return 1;
1133 } else {
1134 print_syntax();
1135 return 1;
1136 }
[045186b]1137}
1138
1139/** @}
1140 */
Note: See TracBrowser for help on using the repository browser.