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

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

Window event delivery mechanism

  • Property mode set to 100644
File size: 10.4 KB
Line 
1/*
2 * Copyright (c) 2019 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 <canvas.h>
36#include <congfx/console.h>
37#include <draw/surface.h>
38#include <display.h>
39#include <fibril.h>
40#include <guigfx/canvas.h>
41#include <gfx/bitmap.h>
42#include <gfx/color.h>
43#include <gfx/render.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 <window.h>
50
51static void wnd_kbd_event(void *, kbd_event_t *);
52
53static display_wnd_cb_t wnd_cb = {
54 .kbd_event = wnd_kbd_event
55};
56
57static bool quit = false;
58
59/** Clear screen.
60 *
61 * @param gc Graphic context
62 * @param w Screen width
63 * @param h Screen height
64 */
65static errno_t clear_scr(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
66{
67 gfx_color_t *color = NULL;
68 gfx_rect_t rect;
69 errno_t rc;
70
71 rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
72 if (rc != EOK)
73 goto error;
74
75 rc = gfx_set_color(gc, color);
76 if (rc != EOK)
77 goto error;
78
79 rect.p0.x = 0;
80 rect.p0.y = 0;
81 rect.p1.x = w;
82 rect.p1.y = h;
83
84 rc = gfx_fill_rect(gc, &rect);
85 if (rc != EOK)
86 goto error;
87
88 gfx_color_delete(color);
89 return EOK;
90error:
91 if (color != NULL)
92 gfx_color_delete(color);
93 return rc;
94}
95
96/** Run rectangle demo on a graphic context.
97 *
98 * @param gc Graphic context
99 * @param w Width
100 * @param h Height
101 */
102static errno_t demo_rects(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
103{
104 gfx_color_t *color = NULL;
105 gfx_rect_t rect;
106 int i, j;
107 errno_t rc;
108
109 rc = clear_scr(gc, w, h);
110 if (rc != EOK)
111 return rc;
112
113 for (j = 0; j < 10; j++) {
114 rc = gfx_color_new_rgb_i16(rand() % 0x10000, rand() % 0x10000,
115 rand() % 0x10000, &color);
116 if (rc != EOK)
117 return rc;
118
119 rc = gfx_set_color(gc, color);
120 if (rc != EOK)
121 return rc;
122
123 for (i = 0; i < 10; i++) {
124 rect.p0.x = rand() % (w - 1);
125 rect.p0.y = rand() % (h - 1);
126 rect.p1.x = rect.p0.x + rand() % (w - 1 - rect.p0.x);
127 rect.p1.y = rect.p0.y + rand() % (h - 1 - rect.p0.y);
128
129 rc = gfx_fill_rect(gc, &rect);
130 if (rc != EOK)
131 return rc;
132 }
133
134 gfx_color_delete(color);
135
136 fibril_usleep(500 * 1000);
137
138 if (quit)
139 break;
140 }
141
142 return EOK;
143}
144
145/** Fill bitmap with tartan pattern.
146 *
147 * @param bitmap Bitmap
148 * @param w Bitmap width
149 * @param h Bitmap height
150 * @return EOK on success or an error code
151 */
152static errno_t bitmap_tartan(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
153{
154 int i, j;
155 pixelmap_t pixelmap;
156 gfx_bitmap_alloc_t alloc;
157 errno_t rc;
158
159 rc = gfx_bitmap_get_alloc(bitmap, &alloc);
160 if (rc != EOK)
161 return rc;
162
163 /* In absence of anything else, use pixelmap */
164 pixelmap.width = w;
165 pixelmap.height = h;
166 pixelmap.data = alloc.pixels;
167
168 for (i = 0; i < w; i++) {
169 for (j = 0; j < h; j++) {
170 pixelmap_put_pixel(&pixelmap, i, j,
171 PIXEL(255, (i % 30) < 3 ? 255 : 0,
172 (j % 30) < 3 ? 255 : 0, i / 2));
173 }
174 }
175
176 return EOK;
177}
178
179/** Fill bitmap with moire pattern.
180 *
181 * @param bitmap Bitmap
182 * @param w Bitmap width
183 * @param h Bitmap height
184 * @return EOK on success or an error code
185 */
186static errno_t bitmap_moire(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
187{
188 int i, j;
189 int k;
190 pixelmap_t pixelmap;
191 gfx_bitmap_alloc_t alloc;
192 errno_t rc;
193
194 rc = gfx_bitmap_get_alloc(bitmap, &alloc);
195 if (rc != EOK)
196 return rc;
197
198 /* In absence of anything else, use pixelmap */
199 pixelmap.width = w;
200 pixelmap.height = h;
201 pixelmap.data = alloc.pixels;
202
203 for (i = 0; i < w; i++) {
204 for (j = 0; j < h; j++) {
205 k = i * i + j * j;
206 pixelmap_put_pixel(&pixelmap, i, j,
207 PIXEL(255, k, k, k));
208 }
209 }
210
211 return EOK;
212}
213
214/** Run bitmap demo on a graphic context.
215 *
216 * @param gc Graphic context
217 * @param w Width
218 * @param h Height
219 */
220static errno_t demo_bitmap(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
221{
222 gfx_bitmap_t *bitmap;
223 gfx_bitmap_params_t params;
224 int i, j;
225 gfx_coord2_t offs;
226 gfx_rect_t srect;
227 errno_t rc;
228
229 rc = clear_scr(gc, w, h);
230 if (rc != EOK)
231 return rc;
232
233 params.rect.p0.x = 0;
234 params.rect.p0.y = 0;
235 params.rect.p1.x = w;
236 params.rect.p1.y = h;
237
238 rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
239 if (rc != EOK)
240 return rc;
241
242 rc = bitmap_tartan(bitmap, w, h);
243 if (rc != EOK)
244 goto error;
245
246 for (j = 0; j < 10; j++) {
247 for (i = 0; i < 5; i++) {
248 srect.p0.x = rand() % (w - 40);
249 srect.p0.y = rand() % (h - 20);
250 srect.p1.x = srect.p0.x + rand() % (w - srect.p0.x);
251 srect.p1.y = srect.p0.y + rand() % (h - srect.p0.y);
252 offs.x = 0;
253 offs.y = 0;
254
255 rc = gfx_bitmap_render(bitmap, &srect, &offs);
256 if (rc != EOK)
257 goto error;
258 fibril_usleep(250 * 1000);
259
260 if (quit)
261 break;
262 }
263 }
264
265 gfx_bitmap_destroy(bitmap);
266
267 return EOK;
268error:
269 gfx_bitmap_destroy(bitmap);
270 return rc;
271}
272
273/** Run second bitmap demo on a graphic context.
274 *
275 * @param gc Graphic context
276 * @param w Width
277 * @param h Height
278 */
279static errno_t demo_bitmap2(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
280{
281 gfx_bitmap_t *bitmap;
282 gfx_bitmap_params_t params;
283 int i, j;
284 gfx_coord2_t offs;
285 errno_t rc;
286
287 rc = clear_scr(gc, w, h);
288 if (rc != EOK)
289 return rc;
290
291 params.rect.p0.x = 0;
292 params.rect.p0.y = 0;
293 params.rect.p1.x = 40;
294 params.rect.p1.y = 20;
295
296 rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
297 if (rc != EOK)
298 return rc;
299
300 rc = bitmap_moire(bitmap, 40, 20);
301 if (rc != EOK)
302 goto error;
303
304 for (j = 0; j < 10; j++) {
305 for (i = 0; i < 10; i++) {
306 offs.x = rand() % (w - 40);
307 offs.y = rand() % (h - 20);
308
309 rc = gfx_bitmap_render(bitmap, NULL, &offs);
310 if (rc != EOK)
311 goto error;
312 }
313
314 fibril_usleep(500 * 1000);
315
316 if (quit)
317 break;
318 }
319
320 gfx_bitmap_destroy(bitmap);
321
322 return EOK;
323error:
324 gfx_bitmap_destroy(bitmap);
325 return rc;
326}
327
328/** Run demo loop on a graphic context.
329 *
330 * @param gc Graphic context
331 * @param w Width
332 * @param h Height
333 */
334static errno_t demo_loop(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
335{
336 errno_t rc;
337
338 while (!quit) {
339 rc = demo_rects(gc, w, h);
340 if (rc != EOK)
341 return rc;
342
343 rc = demo_bitmap(gc, w, h);
344 if (rc != EOK)
345 return rc;
346
347 rc = demo_bitmap2(gc, w, h);
348 if (rc != EOK)
349 return rc;
350 }
351
352 return EOK;
353}
354
355/** Run demo on console. */
356static errno_t demo_console(void)
357{
358 console_ctrl_t *con = NULL;
359 console_gc_t *cgc = NULL;
360 gfx_context_t *gc;
361 errno_t rc;
362
363 printf("Init console..\n");
364 con = console_init(stdin, stdout);
365 if (con == NULL)
366 return EIO;
367
368 printf("Create console GC\n");
369 rc = console_gc_create(con, stdout, &cgc);
370 if (rc != EOK)
371 return rc;
372
373 gc = console_gc_get_ctx(cgc);
374
375 rc = demo_loop(gc, 80, 25);
376 if (rc != EOK)
377 return rc;
378
379 rc = console_gc_delete(cgc);
380 if (rc != EOK)
381 return rc;
382
383 return EOK;
384}
385
386/** Run demo on canvas. */
387static errno_t demo_canvas(void)
388{
389 canvas_gc_t *cgc = NULL;
390 gfx_context_t *gc;
391 window_t *window = NULL;
392 pixel_t *pixbuf = NULL;
393 surface_t *surface = NULL;
394 canvas_t *canvas = NULL;
395 gfx_coord_t vw, vh;
396 errno_t rc;
397
398 printf("Init canvas..\n");
399
400 window = window_open("comp:0/winreg", NULL,
401 WINDOW_MAIN | WINDOW_DECORATED, "GFX Demo");
402 if (window == NULL) {
403 printf("Error creating window.\n");
404 return -1;
405 }
406
407 vw = 400;
408 vh = 300;
409
410 pixbuf = calloc(vw * vh, sizeof(pixel_t));
411 if (pixbuf == NULL) {
412 printf("Error allocating memory for pixel buffer.\n");
413 return ENOMEM;
414 }
415
416 surface = surface_create(vw, vh, pixbuf, 0);
417 if (surface == NULL) {
418 printf("Error creating surface.\n");
419 return EIO;
420 }
421
422 canvas = create_canvas(window_root(window), NULL, vw, vh,
423 surface);
424 if (canvas == NULL) {
425 printf("Error creating canvas.\n");
426 return EIO;
427 }
428
429 window_resize(window, 0, 0, vw + 10, vh + 30, WINDOW_PLACEMENT_ANY);
430 window_exec(window);
431
432 printf("Create canvas GC\n");
433 rc = canvas_gc_create(canvas, surface, &cgc);
434 if (rc != EOK)
435 return rc;
436
437 gc = canvas_gc_get_ctx(cgc);
438
439 rc = demo_loop(gc, 400, 300);
440 if (rc != EOK)
441 return rc;
442
443 rc = canvas_gc_delete(cgc);
444 if (rc != EOK)
445 return rc;
446
447 return EOK;
448}
449
450/** Run demo on display server. */
451static errno_t demo_display(void)
452{
453 display_t *display = NULL;
454 gfx_context_t *gc;
455 display_window_t *window = NULL;
456 errno_t rc;
457
458 printf("Init display..\n");
459
460 rc = display_open(NULL, &display);
461 if (rc != EOK) {
462 printf("Error opening display.\n");
463 return rc;
464 }
465
466 rc = display_window_create(display, &wnd_cb, NULL, &window);
467 if (rc != EOK) {
468 printf("Error creating window.\n");
469 return rc;
470 }
471
472 rc = display_window_get_gc(window, &gc);
473 if (rc != EOK) {
474 printf("Error getting graphics context.\n");
475 }
476
477 rc = demo_loop(gc, 400, 300);
478 if (rc != EOK)
479 return rc;
480
481 rc = gfx_context_delete(gc);
482 if (rc != EOK)
483 return rc;
484
485 return EOK;
486}
487
488static void wnd_kbd_event(void *arg, kbd_event_t *event)
489{
490 printf("Keyboard event type=%d key=%d\n", event->type, event->key);
491 quit = true;
492}
493
494static void print_syntax(void)
495{
496 printf("syntax: gfxdemo {canvas|console|display}\n");
497}
498
499int main(int argc, char *argv[])
500{
501 errno_t rc;
502
503 if (argc < 2) {
504 print_syntax();
505 return 1;
506 }
507
508 if (str_cmp(argv[1], "console") == 0) {
509 rc = demo_console();
510 if (rc != EOK)
511 return 1;
512 } else if (str_cmp(argv[1], "canvas") == 0) {
513 rc = demo_canvas();
514 if (rc != EOK)
515 return 1;
516 } else if (str_cmp(argv[1], "display") == 0) {
517 rc = demo_display();
518 if (rc != EOK)
519 return 1;
520 } else {
521 print_syntax();
522 return 1;
523 }
524}
525
526/** @}
527 */
Note: See TracBrowser for help on using the repository browser.