aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/examples/evas-buffer-simple.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/examples/evas-buffer-simple.c')
-rw-r--r--libraries/evas/src/examples/evas-buffer-simple.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/libraries/evas/src/examples/evas-buffer-simple.c b/libraries/evas/src/examples/evas-buffer-simple.c
new file mode 100644
index 0000000..6676ef1
--- /dev/null
+++ b/libraries/evas/src/examples/evas-buffer-simple.c
@@ -0,0 +1,228 @@
1/**
2 * Simple Evas example using the Buffer engine.
3 *
4 * You must have Evas compiled with the buffer engine, and have the
5 * evas-software-buffer pkg-config files installed.
6 *
7 * Compile with:
8 *
9 * @verbatim
10 * gcc -o evas-buffer-simple evas-buffer-simple.c `pkg-config --libs --cflags evas evas-software-buffer`
11 * @endverbatim
12 *
13 */
14#include <Evas.h>
15#include <Evas_Engine_Buffer.h>
16#include <stdio.h>
17#include <errno.h>
18
19#define WIDTH (320)
20#define HEIGHT (240)
21
22/*
23 * create_canvas(), destroy_canvas() and draw_scene() are support functions.
24 *
25 * They are only required to use raw Evas, but for real world usage,
26 * it is recommended to use ecore and its ecore-evas submodule, that
27 * provide convenience canvas creators, integration with main loop and
28 * automatic render of updates (draw_scene()) when system goes back to
29 * main loop.
30 */
31static Evas *create_canvas(int width, int height);
32static void destroy_canvas(Evas *canvas);
33static void draw_scene(Evas *canvas);
34
35// support function to save scene as PPM image
36static void save_scene(Evas *canvas, const char *dest);
37
38int main(void)
39{
40 Evas *canvas;
41 Evas_Object *bg, *r1, *r2, *r3;
42
43 evas_init();
44
45 // create your canvas
46 // NOTE: consider using ecore_evas_buffer_new() instead!
47 canvas = create_canvas(WIDTH, HEIGHT);
48 if (!canvas)
49 return -1;
50
51 bg = evas_object_rectangle_add(canvas);
52 evas_object_color_set(bg, 255, 255, 255, 255); // white bg
53 evas_object_move(bg, 0, 0); // at origin
54 evas_object_resize(bg, WIDTH, HEIGHT); // covers full canvas
55 evas_object_show(bg);
56
57 puts("initial scene, with just background:");
58 draw_scene(canvas);
59
60 r1 = evas_object_rectangle_add(canvas);
61 evas_object_color_set(r1, 255, 0, 0, 255); // 100% opaque red
62 evas_object_move(r1, 10, 10);
63 evas_object_resize(r1, 100, 100);
64 evas_object_show(r1);
65
66 // pay attention to transparency! Evas color values are pre-multiplied by
67 // alpha, so 50% opaque green is:
68 // non-premul: r=0, g=255, b=0 a=128 (50% alpha)
69 // premul:
70 // r_premul = r * a / 255 = 0 * 128 / 255 = 0
71 // g_premul = g * a / 255 = 255 * 128 / 255 = 128
72 // b_premul = b * a / 255 = 0 * 128 / 255 = 0
73 //
74 // this 50% green is over a red background, so it will show in the
75 // final output as yellow (green + red = yellow)
76 r2 = evas_object_rectangle_add(canvas);
77 evas_object_color_set(r2, 0, 128, 0, 128); // 50% opaque green
78 evas_object_move(r2, 10, 10);
79 evas_object_resize(r2, 50, 50);
80 evas_object_show(r2);
81
82 r3 = evas_object_rectangle_add(canvas);
83 evas_object_color_set(r3, 0, 128, 0, 255); // 100% opaque dark green
84 evas_object_move(r3, 60, 60);
85 evas_object_resize(r3, 50, 50);
86 evas_object_show(r3);
87
88 puts("final scene (note updates):");
89 draw_scene(canvas);
90 save_scene(canvas, "/tmp/evas-buffer-simple-render.ppm");
91
92 // NOTE: use ecore_evas_buffer_new() and here ecore_evas_free()
93 destroy_canvas(canvas);
94
95 evas_shutdown();
96
97 return 0;
98}
99
100static Evas *create_canvas(int width, int height)
101{
102 Evas *canvas;
103 Evas_Engine_Info_Buffer *einfo;
104 int method;
105 void *pixels;
106
107 method = evas_render_method_lookup("buffer");
108 if (method <= 0)
109 {
110 fputs("ERROR: evas was not compiled with 'buffer' engine!\n", stderr);
111 return NULL;
112 }
113
114 canvas = evas_new();
115 if (!canvas)
116 {
117 fputs("ERROR: could not instantiate new evas canvas.\n", stderr);
118 return NULL;
119 }
120
121 evas_output_method_set(canvas, method);
122 evas_output_size_set(canvas, width, height);
123 evas_output_viewport_set(canvas, 0, 0, width, height);
124
125 einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(canvas);
126 if (!einfo)
127 {
128 fputs("ERROR: could not get evas engine info!\n", stderr);
129 evas_free(canvas);
130 return NULL;
131 }
132
133 // ARGB32 is sizeof(int), that is 4 bytes, per pixel
134 pixels = malloc(width * height * sizeof(int));
135 if (!pixels)
136 {
137 fputs("ERROR: could not allocate canvas pixels!\n", stderr);
138 evas_free(canvas);
139 return NULL;
140 }
141
142 einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
143 einfo->info.dest_buffer = pixels;
144 einfo->info.dest_buffer_row_bytes = width * sizeof(int);
145 einfo->info.use_color_key = 0;
146 einfo->info.alpha_threshold = 0;
147 einfo->info.func.new_update_region = NULL;
148 einfo->info.func.free_update_region = NULL;
149 evas_engine_info_set(canvas, (Evas_Engine_Info *)einfo);
150
151 return canvas;
152}
153
154static void destroy_canvas(Evas *canvas)
155{
156 Evas_Engine_Info_Buffer *einfo;
157
158 einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(canvas);
159 if (!einfo)
160 {
161 fputs("ERROR: could not get evas engine info!\n", stderr);
162 evas_free(canvas);
163 return;
164 }
165
166 free(einfo->info.dest_buffer);
167 evas_free(canvas);
168}
169
170static void draw_scene(Evas *canvas)
171{
172 Eina_List *updates, *n;
173 Eina_Rectangle *update;
174
175 // render and get the updated rectangles:
176 updates = evas_render_updates(canvas);
177
178 // informative only here, just print the updated areas:
179 EINA_LIST_FOREACH(updates, n, update)
180 printf("UPDATED REGION: pos: %3d, %3d size: %3dx%3d\n",
181 update->x, update->y, update->w, update->h);
182
183 // free list of updates
184 evas_render_updates_free(updates);
185}
186
187static void save_scene(Evas *canvas, const char *dest)
188{
189 Evas_Engine_Info_Buffer *einfo;
190 const unsigned int *pixels, *pixels_end;
191 int width, height;
192 FILE *f;
193
194 einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(canvas);
195 if (!einfo)
196 {
197 fputs("ERROR: could not get evas engine info!\n", stderr);
198 return;
199 }
200 evas_output_size_get(canvas, &width, &height);
201
202 f = fopen(dest, "wb+");
203 if (!f)
204 {
205 fprintf(stderr, "ERROR: could not open for writing '%s': %s\n",
206 dest, strerror(errno));
207 return;
208 }
209
210 pixels = einfo->info.dest_buffer;
211 pixels_end = pixels + (width * height);
212
213 // PPM P6 format is dead simple to write:
214 fprintf(f, "P6\n%d %d\n255\n", width, height);
215 for (; pixels < pixels_end; pixels++)
216 {
217 int r, g, b;
218
219 r = ((*pixels) & 0xff0000) >> 16;
220 g = ((*pixels) & 0x00ff00) >> 8;
221 b = (*pixels) & 0x0000ff;
222
223 fprintf(f, "%c%c%c", r, g, b);
224 }
225
226 fclose(f);
227 printf("saved scene as '%s'\n", dest);
228}