source: mainline/uspace/app/gfxdemo/gfxdemo.c@ 4d9c807

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

Communicate window dimensions to display server

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