diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/evas/src/examples/evas-buffer-simple.c | 228 |
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 | */ | ||
31 | static Evas *create_canvas(int width, int height); | ||
32 | static void destroy_canvas(Evas *canvas); | ||
33 | static void draw_scene(Evas *canvas); | ||
34 | |||
35 | // support function to save scene as PPM image | ||
36 | static void save_scene(Evas *canvas, const char *dest); | ||
37 | |||
38 | int 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 | |||
100 | static 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 | |||
154 | static 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 | |||
170 | static 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 | |||
187 | static 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 | } | ||