2 * @page Examples Examples
4 * Here is a page with some Ecore examples explained:
6 * @li @ref ecore_time_functions_example_c
7 * @li @ref ecore_timer_example_c
8 * @li @ref ecore_idler_example_c
9 * @li @ref ecore_job_example_c
10 * @li @ref ecore_event_example_01_c
11 * @li @ref ecore_event_example_02_c
12 * @li @ref ecore_fd_handler_example_c
13 * @li @ref ecore_poller_example_c
14 * @li @ref ecore_con_lookup_example_c
15 * @li @ref ecore_con_url_download_example_c
16 * @li @ref ecore_con_server_simple_example_c
17 * @li @ref ecore_con_client_simple_example_c
18 * @li @ref ecore_evas_callbacks_example_c
19 * @li @ref ecore_evas_object_example_c
20 * @li @ref ecore_evas_basics_example_c
21 * @li @ref Ecore_Evas_Window_Sizes_Example_c
22 * @li @ref Ecore_Evas_Buffer_Example_01_c
23 * @li @ref Ecore_Evas_Buffer_Example_02_c
27 * @page ecore_time_functions_example_c ecore_time - Differences between time functions
29 * This example shows the difference between calling ecore_time_get(),
30 * ecore_loop_time_get() and ecore_time_unix_get().
32 * It initializes ecore, then sets a timer with a callback that, when called,
33 * will retrieve the system time using these 3 different functions. After
34 * displaying the time, it sleeps for 1 second, then call display the time
35 * again using the 3 functions.
37 * Since everything occurs inside the same main loop iteration, the internal
38 * ecore time variable will not be updated, and calling ecore_loop_time_get()
39 * before and after the sleep() call will return the same result.
41 * The two other functions will return a difference of 1 second, as expected.
42 * But ecore_time_unix_get() returns the number of seconds since 00:00:00 1st
43 * January 1970, while ecore_time_get() will return the time since a
44 * unspecified point, but that never goes back in time, even when the timezone
45 * of the machine changes.
47 * @note The usage of ecore_loop_time_get() should be preferred against the
48 * two other functions, for most time calculations, since it won't produce a
49 * system call to get the current time. Use ecore_time_unix_get() when you need
50 * to know the current time and date, and ecore_time_get() when you need a
51 * monotonic and more precise time than ecore_loop_time_get().
53 * @include ecore_time_functions_example.c
57 * @page ecore_timer_example_c ecore timers - Scheduled events
58 * @dontinclude ecore_timer_example.c
60 * This example shows how to setup timer callbacks. It starts a timer that will
61 * tick (expire) every 1 second, and then setup other timers that will expire
62 * only once, but each of them will affect the first timer still executing with
63 * a different API, to demonstrate its usage. To see the full code for this
64 * example, click @ref ecore_timer_example.c "here".
66 * To demonstrate this, let's define some constants that will determine at which
67 * time each timer will expire:
71 * These constants should tell by themselves what will be the behavior of the
72 * program, but I'll explain it anyway. The first timer is set to tick every 1
73 * second, but all the other timers until the 6th one will be started
74 * concurrently at the beginning of the program. Each of them will expire at the
75 * specified time in these constants:
77 * @li The timer2, after 3 seconds of the program being executed, will add a delay
78 * of 3 seconds to timer1;
79 * @li The timer3 will pause timer1 at 8.2 seconds;
80 * @li timer4 will resume timer1 at 11.0 seconds;
81 * @li timer5 will will change the interval of timer1 to 2 seconds;
82 * @li timer6 will stop timer1 and start timer7 and timer8, with 1.1 and 1.2
83 * seconds of interval, respectively; it also sets the precision to 0.2 seconds;
84 * @li timer7 and timer8 will just print their expiration time.
86 * @until ecore_time_get
89 * As almost all the other examples, we create a context structure to pass to
90 * our callbacks, so they can have access to the other timers. We also store the
91 * time of the program start in @c _initial_time, and use the function
92 * @c _get_current_time to retrieve the current time relative to that time. This
93 * will help demonstrate what is going on.
95 * Now, the behavior and relationship between the timers that was described
96 * above is dictated by the following timer callbacks:
101 * It's possible to see the same behavior as other Ecore callbacks here,
102 * returning @ref ECORE_CALLBACK_RENEW when the timer needs to continue ticking,
103 * and @ref ECORE_CALLBACK_CANCEL when it needs to stop its execution. Also
104 * notice that later on our program we are checking for the timers pointers in
105 * the context to see if they are still executing before deleting them, so we
106 * need to set these timer pointers to @c NULL when we are returning @ref
107 * ECORE_CALLBACK_CANCEL. Otherwise the pointer would still be not @c NULL, but
108 * pointing to something that is invalid, since the timer would have already
109 * expired without renewing.
111 * Now the main code, which will start the timers:
113 * @until ecore_shutdown
116 * This code is very simple. Just after starting the library, it will save the
117 * current time to @c _initial_time, start all timers from 1 to 6, and begin the
118 * main loop. Everything should be running right now, displaying the time which
119 * each timer is expiring, and what it is doing to affect the other timers.
121 * After returning from the main loop, every timer is checked to see if it's
122 * still alive and, in that case, deleted, before finalizing the library. This
123 * is not really necessary, since ecore_shutdown() will already delete them for
124 * you, but it's good practice if you have other things going on after this
125 * point that could restart the main loop.
130 * @page ecore_idler_example_c ecore idle state - Idlers, enterers and exiters
132 * This example demonstrates how to manage the idle state of the main loop. Once
133 * a program knows that the main loop is going to enter in idle state, it could
134 * start doing some processing until getting out of this state.
136 * To exemplify this, we also add events and a timer to this program, so we can
137 * see the idle exiter callback being called before processing the event and/or
138 * timer, the event/timer callback being called (processed), then the idle
139 * enterer being called before entering in idle state again. Once in idle, the
140 * main loop keeps calling the idler callback continuously until a new event or
143 * First, we declare a struct that will be used as context to be passed to
144 * every callback. It's not useful everywhere, since this example is very
145 * simple and doesn't do anything other than printing messages, but using this
146 * context will make it a little bit more real. Our context will be used to
147 * delete the timer, idler, idle enterer and exiter, and the event handler, and
148 * also to count how many times the idler was called.
150 * Then we start declaring callbacks for the idle enterer, idle exiter and the
151 * idler itself. Idle enterer and exiter callbacks just print a message saying
152 * that they were called, while the idler, in addition to printing a message
153 * too, also sends an event every 10 times that it is called, incrementing the
154 * context count variable. This event will be used to make the main loop exit
155 * the idle state and call the event callback.
157 * These callbacks return @ref ECORE_CALLBACK_RENEW, since we want them to keep
158 * being called every time the main loop changes to/from idle state. Otherwise,
159 * if we didn't want them to be called again, they should return @ref
160 * ECORE_CALLBACK_CANCEL.
162 * The next function declared is the event callback @c _event_handler_cb. It
163 * will check if the idler was called more than 100 times already @c
164 * (ctxt->count > 100), and will delete the idler, idle enterer and exiter, the
165 * timer (if it still exists), and request that the main loop stop running. Then
166 * it returns @ref ECORE_CALLBACK_DONE to indicate that the event shouldn't be
167 * handled by any other callback.
169 * Finally, we add a callback to the timer, that will just print a message when
170 * it is called, and this will happen only once (@ref ECORE_CALLBACK_CANCEL is
171 * being returned). This timer callback is just here to show that the main loop
172 * gets out of idle state when processing timers too.
174 * The @b main function is simple, just creates a new type of event that we will
175 * use to demonstrate the event handling together with the idle state, adds the
176 * callbacks that we declared so far, fill the context struct, and starts
177 * running the main loop.
179 * @note We use timer and event callbacks to demonstrate the idle state
180 * changing, but it also happens for file descriptor handlers, pipe handlers,
183 * @include ecore_idler_example.c
187 * @page ecore_job_example_c ecore_job - Queuing tasks
189 * This example shows how an @ref Ecore_Job can be added, how it can be
190 * deleted, and that they always execute in the added order.
192 * First, 2 callback functions are declared, one that prints strings passed to
193 * it in the @c data pointer, and another one that quits the main loop. In the
194 * @c main function, 3 jobs are added using the first callback, and another one
195 * is added using the second one.
197 * Then the second added job is deleted just to demonstrate the usage of
198 * ecore_job_del(), and the main loop is finally started. Run this example to
199 * see that @c job1, @c job3 and @c job_quit are ran, in this order.
201 * @include ecore_job_example.c
205 * @page ecore_event_example_01_c Handling events example
206 * This example shows the simplest possible way to register a handler for an
207 * ecore event, this way we can focus on the important aspects. The example will
208 * start the main loop and quit it when it receives the ECORE_EVENT_SIGNAL_EXIT
209 * event. This event is triggered by a SIGTERM(pressing ctrl+c).
211 * So let's start with the function we want called when we receive the event,
212 * instead of just stopping the main loop we'll also print a message, that's
213 * just so it's clear that it got called:
214 * @dontinclude ecore_event_example_01.c
217 * @note We return ECORE_CALLBACK_DONE because we don't want any other handlers
218 * for this event to be called, the program is quitting after all.
220 * We then have our main function and the obligatory initialization of ecore:
223 * We then get to the one line of our example that makes everything work, the
224 * registering of the callback:
226 * @note The @c NULL there is because there is no need to pass data to the
229 * And the all that is left to do is start the main loop:
232 * Full source code for this example: @ref ecore_event_example_01.c.
236 * @page ecore_event_example_02_c ecore events and handlers - Setup and use
237 * This example shows how to create a new type of event, setup some event
238 * handlers to it, fire the event and have the callbacks called. After
239 * finishing, we delete the event handlers so no memory will leak.
241 * See the full source code for this example @ref ecore_event_example_02.c
244 * Let's start the example from the beginning:
246 * @dontinclude ecore_event_example_02.c
249 * First thing is to declare a struct that will be passed as context to the
250 * event handlers. In this structure we will store the event handler pointers,
251 * and two strings that will be used by the first event handler. We also will
252 * use a global integer to store the event type used for our event. It is
253 * initialized with 0 in the beginning because the event wasn't created yet.
254 * Later, in the main function we will use ecore_event_type_new() to associate
255 * another value to it. Now the event handler callbacks:
259 * This is the first event handler callback. It prints the event data received
260 * by the event, and the data passed to this handler when it was added. Notice
261 * that this callback already knows that the event data is an integer pointer,
262 * and that the handler data is a string. It knows about the first one because
263 * this is based on the type of event that is going to be handled, and the
264 * second because it was passed to the ecore_event_handler_add() function when
265 * registering the event handler.
267 * Another interesting point about this callback is that it returns @ref
268 * ECORE_CALLBACK_DONE (0) if the event data is even, swallowing the event and
269 * don't allowing any other callback to be called after this one for this event.
270 * Otherwise it returns @ref ECORE_CALLBACK_PASS_ON, allowing the event to be
271 * handled by other event handlers registered for this event. This makes the
272 * second event handler be called just for "odd" events.
274 * @until ECORE_CALLBACK_DONE
277 * The second event handler will check if the event data is equal to 5, and if
278 * that's the case, it will change the event handler data of the first event
279 * handler to another string. Then it checks if the event data is higher than
280 * 10, and if so, it will request the main loop to quit.
282 * An interesting point of this example is that although the second event
283 * handler requests the main loop to finish after the 11th event being received,
284 * it will process all the events that were already fired, and call their
285 * respective event handlers, before the main loop stops. If we didn't want
286 * these event handlers to be called after the 11th event, we would need to
287 * unregister them with ecore_event_handler_del() at this point.
289 * Now some basic initialization of the context, and the Ecore library itself:
293 * This last line is interesting. It creates a new type of event and returns a
294 * unique ID for this event inside Ecore. This ID can be used anywhere else in
295 * your program to reference this specific type of event, and to add callbacks
298 * It's common if you are implementing a library that declares new types of
299 * events to export their respective types as extern in the header files. This
300 * way, when the library is initialized and the new type is created, it will be
301 * available through the header file to an application using it add some
302 * callbacks to it. Since our example is self-contained, we are just putting it
303 * as a global variable.
305 * Now we add some callbacks:
309 * This is very simple. Just need to call ecore_event_handler_add() with the
310 * respective event type, the callback function to be called, and a data pointer
311 * that will be passed to the callback when it is called by the event.
313 * Then we start firing events:
317 * This @c for will fire 16 events of this type. Notice that the events will be
318 * fired consecutively, but any callback will be called yet. They are just
319 * called by the main loop, and since it wasn't even started, nothing happens
320 * yet. For each event fired, we allocate an integer that will hold the number
321 * of the event (we are arbitrarily creating these numbers just for
322 * demonstration purposes). It's up to the event creator to decide which type of
323 * information it wants to give to the event handler, and the event handler must
324 * know what is the event info structure for that type of event.
326 * Since we are not allocating any complex structure, just a simple integer, we
327 * don't need to pass any special free function to ecore_event_add(), and it
328 * will use a simple @c free on our data. That's the default behavior.
330 * Now finishing our example:
334 * We just start the main loop and watch things happen, waiting to shutdown
335 * Ecore when the main loop exits and return.
339 * @page ecore_fd_handler_example_c ecore fd handlers - Monitoring file descriptors
340 * @dontinclude ecore_fd_handler_example.c
342 * This is a very simple example where we will start monitoring the stdin of the
343 * program and, whenever there's something to be read, we call our callback that
346 * Check the full code for this example @ref ecore_fd_handler_example.c "here".
348 * This seems to be stupid, since a similar result could be achieved by the
352 * while (nbytes = read(STDIN_FILENO, buf, sizeof(buf)))
354 * buf[nbytes - 1] = '\0';
355 * printf("Read %zd bytes from input: \"%s\"\n", nbytes - 1, buf);
359 * However, the above code is blocking, and won't allow you to do anything else
360 * other than reading the input. Of course there are other methods to do a
361 * non-blocking reading, like setting the file descriptor to non-blocking and
362 * keep looping always checking if there's something to be read, and do other
363 * things otherwise. Or use a @c select call to watch for more than one file
364 * descriptor at the same time.
366 * The advantage of using an @ref Ecore_Fd_Handler is that you can monitor a
367 * file descriptor, while still iterating on the Ecore main loop. It will allow
368 * you to have timers working and expiring, events still being processed when
369 * received, idlers doing its work when there's nothing happening, and whenever
370 * there's something to be read from the file descriptor, your callback will be
371 * called. And it's everything monitored in the same main loop, no threads are
372 * needed, thus reducing the complexity of the program and any overhead caused
373 * by the use of threads.
375 * Now let's start our program. First we just declare a context structure that
376 * will be passed to our callback, with pointers to our handler and to a timer
377 * that will be used later:
381 * Then we will declare a prepare_callback that is called before any fd_handler
382 * set in the program, and before the main loop select function is called. Just
383 * use one if you really know that you need it. We are just putting it here to
384 * exemplify its usage:
388 * Now, our fd handler. In its arguments, the @c data pointer will have any data
389 * passed to it when it was registered, and the @c handler pointer will contain
390 * the fd handler returned by the ecore_main_fd_handler_add() call. It can be
391 * used, for example, to retrieve which file descriptor triggered this callback,
392 * since it could be added to more than one file descriptor, or to check what
393 * type of activity there's in the file descriptor.
395 * The code is very simple: we first check if the type of activity was an error.
396 * It probably won't happen with the default input, but could be the case of a
397 * network socket detecting a disconnection. Next, we get the file descriptor
398 * from this handler (as said before, the callback could be added to more than
399 * one file descriptor), and read it since we know that it shouldn't block,
400 * because our fd handler told us that there's some activity on it. If the
401 * result of the read was 0 bytes, we know that it's an end of file (EOF), so we
402 * can finish reading the input. Otherwise we just print the content read from
407 * Also notice that this callback returns @ref ECORE_CALLBACK_RENEW to keep
408 * being called, as almost all other Ecore callbacks, otherwise if it returns
409 * @ref ECORE_CALLBACK_CANCEL then the file handler would be deleted.
411 * Just to demonstrate that our program isn't blocking in the input read but
412 * still can process other Ecore events, we are going to setup an @ref
413 * Ecore_Timer. This is its callback:
417 * Now in the main code we are going to initialize the library, and setup
418 * callbacks for the file descriptor, the prepare callback, and the timer:
422 * Notice that the use of ecore_main_fd_handler_add() specifies what kind of
423 * activity we are monitoring. In this case, we want to monitor for read (since
424 * it's the standard input) and for errors. This is done by the flags @ref
425 * ECORE_FD_READ and @ref ECORE_FD_ERROR. For the three callbacks we are also
426 * giving a pointer to our context structure, which has pointers to the handlers
429 * Then we can start the main loop and see everything happening:
433 * In the end we are just deleting the fd handler and the timer to demonstrate
434 * the API usage, since Ecore would already do it for us on its shutdown.
438 * @page ecore_poller_example_c ecore poller - Repetitive polling tasks
439 * @dontinclude ecore_poller_example.c
441 * This example show how to setup, and explains how an @ref Ecore_Poller is
442 * called. You can @ref ecore_poller_example.c "see the full source code here".
444 * In this example we store the initial time of the program just to use as
445 * comparison to the time when the poller callbacks are called. It will be
446 * stored in @c _initial_time :
448 * @until initial_time
450 * Then next step is to define the poller callback. This callback assumes that a
451 * @c data pointer is passed to it on creation, and is a string just used to
452 * identify the poller. The callback prints this string and the time since the
453 * program started, and returns @ref ECORE_CALLBACK_RENEW to keep being called.
457 * Now in the main function we initialize Ecore, and save the initial time of
458 * the program, so we can compare it later with the time that the pollers are
461 * @until initial_time
463 * Then we change the poll interval to 0.3 seconds (the default is 0.125
464 * seconds) just to show the API usage.
466 * Finally, we create two pollers, one that will be called every 4 ticks, and
467 * another one that will be called every 8 ticks. This means the the first
468 * poller interval will be around 1.2 seconds, and the second one will be
469 * around 2.4 seconds. But the most important point is: since the second poller
470 * interval is a multiple of the first one, they will be always synchronized.
471 * Ecore calls pollers that are in the "same tick" together. It doesn't go back
472 * to the main loop and check if there's another poller to execute at this
473 * time, but instead it calls all the pollers registered to this "tick" at the
474 * same time. See the description of ecore_poller_add() for more details. This
475 * is easy to see in the time printed by both of them.
477 * If instead of two synchronized pollers, we were using two different timers,
478 * one with interval of 1.2 seconds and another one with an interval of 2.4
479 * seconds, there would be no guarantee that they would be totally in sync. Some
480 * delay in the execution of another task, or even in the task called in the
481 * callback, could make them get out of sync, forcing Ecore's main loop to wake
482 * up more than necessary.
484 * Well, this is the code that create these two pollers and set the poll
485 * interval, then starts the main loop:
487 * @until ecore_main_loop_begin
489 * If you hit CTRL-C during the execution of the program, the main loop will
490 * quit, since there are some signal handlers already set by default to do this.
491 * So after the main loop begin call, we change the second poller's interval to
492 * 16 ticks, so it will happen each 4.8 seconds (or each 4 times that the first
495 * This means: the program is started, the first poller is called each 4 ticks
496 * and the second is called each 8 ticks. After CTRL-C is used, the second
497 * poller will be called each 16 ticks.
501 * The rest of the program is just deleting the pollers and shutting down the
506 * @page ecore_con_lookup_example_c Ecore_Con - DNS lookup
508 * This is a very simple example that shows how to make a simple DNS lookup
509 * using ecore_con_lookup().
511 * It's possible to see in the beginning of the main function that we are using
512 * the arguments passed via command line. This is the address that we are going
513 * to make the DNS lookup on.
515 * The next step is to initialize the libraries, and just call
516 * ecore_con_lookup(). This function will get the string that contains the
517 * address to be resolved as first parameter, then a callback that will be
518 * called when the resolve stage is done, and finally a data pointer that will
519 * be passed to the callback.
521 * This function is asynchronous, and the callback will be called only on
522 * success. If there was an error during the resolve stage, there's no way to
523 * know about that. It's only possible to know about errors when setting up the
524 * lookup, by looking at the return code of the ecore_con_lookup() function.
526 * The callback @c _lookup_done_cb passed as argument to ecore_con_lookup() just
527 * prints the resolved canonical name, IP, address of the sockaddr structure,
528 * and the length of the socket address (in bytes).
530 * Finally, we start the main loop, and after that we finalize the libraries and
533 * This is the code for this simple example:
535 * @include ecore_con_lookup_example.c
539 * @page ecore_con_url_download_example_c Ecore_Con_Url - downloading a file
541 * This is a simple example that shows how to download a file using @ref
542 * Ecore_Con_Url. The full source code for this example can be found at @ref
543 * ecore_con_url_download_example.c.
545 * First we are setting some callbacks for events that will be sent when data
546 * arrives in our connection (the data is the content of the file being
547 * downloaded), and when the download is completed. The @c _url_progress_cb and
548 * @c _url_complete_cb are these callbacks:
550 * @dontinclude ecore_con_url_download_example.c
552 * @until main_loop_quit
555 * Notice that we also declared a struct that will hold how many bytes were
556 * downloaded through this object. It will be set in the @c main function using
557 * ecore_con_url_data_set().
559 * In the next step, on the @c main function, we open a file where we are going
560 * to save the content being downloaded:
565 * With the file successfully open, let's create our @ref Ecore_Con_Url object.
566 * For this, we initialize the libraries and create the object:
570 * Then we allocate and set the data struct to the connection object, and set a
571 * file descriptor from our previously open file to it. We also add the event
572 * handlers (callbacks) to the events that will be emitted on data being
573 * received and download complete:
577 * Finally we start our request, and run the main loop:
582 * The rest of this code was just freeing resources, with some labels to be used
583 * for error handling.
587 * @page ecore_con_url_cookies_example_c Ecore_Con_Url - Managing cookies
589 * This example shows how to use an @ref Ecore_Con_Url and enable it to
590 * receive/send cookies. These cookies can be set by the server, saved to a
591 * file, loaded later from this file and sent again to the server. The complete
592 * example can be found at @ref ecore_con_url_cookies_example.c
593 * "ecore_con_url_cookies_example.c"
595 * First we are setting some callbacks for events that will be sent when data
596 * arrives in our connection (the data is the content of the file being
597 * downloaded), and when the download is completed. The @c _url_data_cb and
598 * @c _url_complete_cb are these callbacks:
600 * @dontinclude ecore_con_url_download_example.c
602 * @until main_loop_quit
605 * In the @c main function we parse some parameter from the command line. These
606 * parameters are the url that we are connecting to, and cookie use policy.
608 * After that we initialize the libraries and create a handler to our request
609 * using the given url:
614 * We also set the event handlers for this request and add a header to it, that
615 * will inform our custom user agent:
619 * Now we start playing with cookies. First, let's call
620 * ecore_con_url_cookies_init() to inform that we want cookies enabled. We also
621 * set a file from which we are loading previously set (old) cookies, in case
622 * that we don't want to clear old cookies or old session cookies.
624 * After that we set the file where we are going to save all valid cookies in
625 * the @ref Ecore_Con_Url object. This includes previously loaded cookies (that
626 * weren't cleared) and new cookies set by the response header "Set-Cookie" that
627 * comes with the response to our request:
629 * @until jar_file_set
631 * And finally, before performing the request, we check the command passed as
632 * argument in the command line and use it to choose between clearing old
633 * cookies, clearing just old session cookies, or ignoring old session cookies.
635 * After that we just finish our code as expected:
640 * Notice that in this code, if we want to clear old cookies, we also don't load
641 * them from the file. This is a bit confusing and the API isn't clear, but
642 * ecore_con_url_cookies_file_add() will load cookies from the specified files
643 * just when the operation is really performed (i.e. ecore_con_url_get() is
644 * called). So if ecore_con_url_cookies_clear() is called before
645 * ecore_con_url_get(), the old cookies may not have been loaded yet, so they
646 * are not cleared. To avoid having old cookies loaded, don't add any cookie
647 * file with ecore_con_url_cookies_file_add().
649 * The function ecore_con_url_cookies_clear() is just useful to clear cookies
650 * that are already loaded/valid in the @ref Ecore_Con_Url object (from a
651 * previous request, for example).
655 * @page ecore_con_url_headers_example_c Ecore_Con_Url - customizing a request
657 * This is a simple example that shows how to make a custom request using @ref
658 * Ecore_Con_Url. The full source code for this example can be found at @ref
659 * ecore_con_url_headers_example.c.
661 * The first part of the example is setting the callbacks to be called when an
662 * #ECORE_CON_EVENT_URL_DATA or #ECORE_CON_EVENT_URL_COMPLETE event is received.
663 * These are the callbacks that are going to be used with this:
665 * @dontinclude ecore_con_url_headers_example.c
667 * @until main_loop_quit
670 * The @c main code is as simple as the @ref Ecore_Con_Url example. It contains
671 * some checks for the arguments to see if a GET or POST request is required:
676 * Then we start our required libraries and configure a global option to use
677 * pipelined requests:
679 * @until pipeline_set
681 * Now we create our request object, but using ecore_con_url_custom_new() to use
682 * a POST or GET method depending on the command line arguments. And we also add
683 * the event handlers for our callbacks:
687 * In order to demonstrate our API, some options are set to this request before
688 * actually performing it:
692 * Depending on what kind of request was asked (GET or POST), we use one of the
693 * specific functions to perform it:
697 * After that, we just check for errors, start the main loop, free resources and
705 * @page ecore_con_server_simple_example_c Ecore_Con - Creating a server
707 * In this example we are going to create a server that listens for connections
708 * from clients through a TCP port. You can get the full source code at @ref
709 * ecore_con_server_simple_example.c.
711 * We begin our example in the main function, to demonstrate how to setup
712 * things, and then go to the callbacks that are needed for it to run properly.
714 * In the @c main function, after initializing the libraries, we use
715 * ecore_con_server_add() to startup the server. Look at the reference
716 * documentation of this function: it supports many types of server, and we are
717 * going to use #ECORE_CON_REMOTE_TCP (a TCP based server). Other arguments to
718 * this function are the address where we are listening on, the port, and a data
719 * pointer that will associate that data with the server:
721 * @dontinclude ecore_con_server_simple_example.c
725 * Notice that we are listening only on 127.0.0.1, which is the internal
726 * loopback interface. If the server needs to listening on all of its ips, use
729 * We also need to set event handlers to be called when we receive any data from
730 * the clients, when a new client connects to our server, or when a client
731 * disconnects. These callbacks are:
735 * More details about what these callbacks do will be given later.
737 * Now, before running the main loop, we also want to set some limits to our
738 * server. To avoid it to be overloaded with too many connections to handle, we
739 * are going to set a maximum of 3 clients connected at the same time. This
740 * number is used just to demonstrate the API. A good number to be used here
741 * would need to be determined by tests done on the server, to check the load
744 * Any other client trying to connect to this server, after the limit is
745 * reached, will wait until one of the connected clients disconnect and the
746 * server accepts the new connection.
748 * Another important thing to do is setting a timeout, to avoid that a client
749 * hold a connection for too long without doing anything. This timeout will
750 * disconnect the idle client, allowing that other clients that may be waiting
751 * to connect finally can do it.
753 * Then we just start the main loop:
755 * @until main_loop_begin
757 * After exiting the main loop, we print the list of connected clients, and also
758 * free the data associated with each respective client. This data was
759 * previously associated using ecore_con_client_data_set():
763 * Then before exiting we show the total uptime of the server:
767 * Now let's go back to the used callbacks.
769 * The first callback, @c _add, is registered to the event
770 * #ECORE_CON_EVENT_CLIENT_ADD, which will be called whenever a client connects
773 * This callback will associate a data structure to this client, that will be
774 * used to count how many bytes were received from it. It also prints some info
775 * about the client, and send a welcome string to it. ecore_con_client_flush()
776 * is used to ensure that the string is sent immediately, instead of being
779 * A timeout for idle specific for this client is also set, to demonstrate that
780 * it is independent of the general timeout of the server.
782 * Before exiting, the callback will display a list of all clients still
783 * connected to this server. The code for this callback follows:
785 * @dontinclude ecore_con_server_simple_example.c
787 * @until CALLBACK_RENEW
790 * The second callback is @c _del. It is associated with
791 * #ECORE_CON_EVENT_CLIENT_DEL, and is called whenever a client disconnects from
794 * It will just print some information about the client, free the associated
795 * data structure, and call ecore_con_client_del() on it before exiting the
796 * callback. Here's its code:
798 * @until CALLBACK_RENEW
801 * The last callback will print any data received by this server from its
802 * clients. It also increments the "bytes received" counter, sdata, in the
803 * data structure associated with this client. The callback code follows:
805 * @until CALLBACK_RENEW
808 * The important parts of this example were described above. If you need to see
809 * the full source code for it, there's a link to the code in the beginning of
812 * This example will start a server and start accepting connections from clients, as
813 * demonstrated in the following diagram:
815 * <img src="ecore_con-client-server-example.png" style="max-width: 400px"/>
816 * <a href="ecore_con-client-server-example.png">Full size</a>
819 * @image rtf ecore_con-client-server-example.png
820 * @image latex ecore_con-client-server-example.eps width=\textwidth
822 * @note This example contains a serious security flaw: it doesn't check for the
823 * size of data being received, thus allowing to the string to be exploited in
824 * some way. However, it is left like this to make the code simpler and just
825 * demonstrate the API usage.
829 * @page ecore_con_client_simple_example_c Ecore_Con - Creating a client
831 * Following the same idea as the @ref ecore_con_server_simple_example_c , this
832 * example will demonstrate how to create a client that connects to a specified
833 * server through a TCP port. You can see the full source code at @ref
834 * ecore_con_client_simple_example.c.
836 * Starting from the @c main function, after reading the command line argument
837 * list and initializing the libraries, we try to connect to the server:
839 * @dontinclude ecore_con_client_simple_example.c
844 * After doing this, everything else in @c main is setting up callbacks for the
845 * client events, starting the main loop and shutting down the libraries after
848 * Now let's go to the callbacks. These callbacks are very similar to the server
849 * callbacks (our implementation for this example is very simple). On the
850 * @c _add callback, we just set a data structure to the server, print some
851 * information about the server, and send a welcome message to it:
853 * @dontinclude ecore_con_client_simple_example.c
855 * @until CALLBACK_RENEW
858 * The @c _del callback is as simple as the previous one. We free the data
859 * associated with the server, print the uptime of this client, and quit the
860 * main loop (since there's nothing to do once we disconnect):
862 * @until CALLBACK_RENEW
865 * The @c _data callback is also similar to the server data callback. it will
866 * print any received data, and increase the data counter in the structure
867 * associated with this server:
870 * @until CALLBACK_RENEW
873 * You can see the server counterpart functions of the ones used in this example
874 * in the @ref ecore_con_server_simple_example_c.
876 * This example will connect to the server and start comunicating with it, as
877 * demonstrated in the following diagram:
879 * <img src="ecore_con-client-server-example2.png" style="max-width: 400px"/>
880 * <a href="ecore_con-client-server-example2.png">Full size</a>
883 * @image rtf ecore_con-client-server-example2.png
884 * @image latex ecore_con-client-server-example2.eps width=\textwidth
886 * @note This example contains a serious security flaw: it doesn't check for the
887 * size of data being received, thus allowing to the string to be exploited in
888 * some way. However, it is left like this to make the code simpler and just
889 * demonstrate the API usage.
893 * @example ecore_idler_example.c
894 * This example shows when @ref Ecore_Idler, @ref Ecore_Idle_Enterer and @ref
895 * Ecore_Idle_Exiter are called. See
896 * @ref ecore_idler_example_c "the explanation here".
900 * @example ecore_job_example.c
901 * This example shows how to use an @ref Ecore_Job. See
902 * @ref ecore_job_example_c "the explanation here".
906 * @example ecore_time_functions_example.c
907 * Shows the difference between the three time functions. See @ref
908 * ecore_time_functions_example_c "the example explained".
912 * @example ecore_timer_example.c
913 * This example show how to use timers to have timed events inside ecore.
914 * See @ref ecore_timer_example_c "the example explained".
918 * @example ecore_fd_handler_example.c
919 * This example shows how to setup and use an fd_handler. See
920 * @ref ecore_fd_handler_example_c "the explanation here".
924 * @example ecore_poller_example.c
925 * This example shows how to setup and use a poller. See
926 * @ref ecore_poller_example_c "the explanation here".
930 * @example ecore_event_example_01.c
931 * This example shows how to create an event handler. Explanation: @ref
932 * ecore_event_example_01_c
936 * @example ecore_event_example_02.c
937 * This example shows how to setup, change, and delete event handlers. See
938 * @ref ecore_event_example_02_c "the explanation here".
942 * @example ecore_fd_handler_gnutls_example.c
943 * Shows how to use fd handlers.
947 * @example ecore_con_lookup_example.c
948 * Shows how to make a simple DNS lookup. See the complete example description
949 * at @ref ecore_con_lookup_example_c
953 * @example ecore_con_url_download_example.c
954 * Shows how to download a file using an @ref Ecore_Con_Url object. See the
955 * complete example description at @ref ecore_con_url_download_example_c
959 * @example ecore_con_url_cookies_example.c
960 * Shows how to manage cookies on a @ref Ecore_Con_Url object. See the complete
961 * example description at @ref ecore_con_url_cookies_example_c.
965 * @example ecore_con_server_simple_example.c
966 * Shows how to setup a simple server that accepts client connections and sends
967 * a "hello" string to them. See the complete example description at @ref
968 * ecore_con_server_simple_example_c
972 * @example ecore_con_client_simple_example.c
973 * Shows how to setup a simple client that connects to a server and sends a
974 * "hello" string to it. See the complete example description at @ref
975 * ecore_con_client_simple_example_c
979 * @example ecore_con_url_headers_example.c
980 * Shows how to make GET or POST requests using an @ref Ecore_Con_Url object,
981 * and make use of most of its API. See the complete example description at
982 * @ref ecore_con_url_headers_example_c
986 * @page tutorial_ecore_pipe_gstreamer_example
988 * Here is an example that uses the pipe wrapper with a Gstreamer
989 * pipeline. For each decoded frame in the Gstreamer thread, a handle
990 * is called in the ecore thread.
992 * @include ecore_pipe_gstreamer_example.c
993 * @example ecore_pipe_gstreamer_example.c
997 * @page tutorial_ecore_pipe_simple_example
998 * @dontinclude ecore_pipe_simple_example.c
1000 * This example shows some simple usage of ecore_pipe. We are going to create a
1001 * pipe, fork our process, and then the child is going to communicate to the
1002 * parent the result of its processing through the pipe.
1004 * As always we start with our includes, nothing special:
1008 * The first thing we are going to define in our example is the function we are
1009 * going to run on the child process, which, as mentioned, will do some
1010 * processing and then will write the result to the pipe:
1013 * @note The sleep was added so the parent process would think the child process
1014 * was doing something interesting...
1016 * Next up is our function for handling data arriving in the pipe. It copies the
1017 * data to another buffer, adds a terminating NULL and prints it. Also if it
1018 * receives a certain string it stops the main loop(effectively ending the
1023 * And now on to our main function, we start by declaring some variables and
1024 * initializing ecore:
1027 * And since we are talking about pipes let's create one:
1030 * Now we are going to fork:
1034 * The child process is going to do the our fancy processing:
1036 * @note It's very important to call ecore_pipe_read_close() here so that the
1037 * child process won't read what it is writing to the pipe itself.
1039 * And the parent is going to run ecore's main loop waiting for some data:
1041 * @note Calling ecore_pipe_write_close() here isn't important but since we
1042 * aren't going to write in the pipe it is good practice.
1044 * And finally when done processing(the child) or done receiving(the parent) we
1045 * delete the pipe and shutdown ecore:
1048 * @example ecore_pipe_simple_example.c
1052 * @page tutorial_ecore_animator Ecore animator example
1053 * @dontinclude ecore_animator_example.c
1055 * For this example we are going to animate a rectangle growing, moving and
1056 * changing color, and then move it back to it's initial state with a
1057 * different animation. We are also going to have a second rectangle moving
1058 * along the bottom of the screen. To do this we are going to use ecore_evas,
1059 * but since that is not the focus here we won't going into detail about it.
1062 * @until evas_object_show
1063 * @until evas_object_show
1064 * All of this is just setup, not what we're interested in right now.
1066 * Now we are going to set the frametime for our animation to one fiftieth of
1067 * a second, this will make our program consume more resources but should make
1068 * our animation extra smooth:
1071 * And now we get right to the business of creating our ecore_animator:
1073 * @note We are telling our animation to last 10 second and to call
1074 * _advance_frame with rect as data.
1076 * So far we setup the first and second animations, the third one however is a
1077 * bit different, this time we won't use a timeline animation, that's because we
1078 * don't want our animation to stop:
1079 * @until animator_add
1081 * Next we set a few timers to execute _start_second_anim, _freeze_third_anim
1082 * and _thaw_thir_anim in 10, 5 and 10 seconds respectively:
1085 * And now we tell ecore to begin the main loop and free some resources once
1086 * it leaves the main loop:
1089 * Here we have the callback function for our first animation, which first
1090 * takes @p pos(where in the timeline we are), maps it to a SPRING curve that
1091 * which will wobble 15 times and will decay by a factor of 1.2:
1094 * Now that we have the frame we can adjust the rectangle to its appropriate
1098 * And now the callback that will run 10 seconds after the program starts(5
1099 * seconds after the first animation finishes) and starts our second
1102 * @note For this animation we made the frametime much larger which means our
1103 * animation might get "jerky".
1105 * The callback for our second animation, our savvy reader no doubt noted that
1106 * it's very similar to the callback for the first animation. What we change for
1107 * this one is the type of animation to BOUNCE and the number of times it will
1111 * And for our last animation callback something simpler, we just move our
1112 * rectangle right by one pixel until it reaches the end of the screen and then
1113 * start at the beginning again:
1116 * Our next two functions respectively freezes and thaw our third animation, so
1117 * that it won't happen for the 5 seconds after the first animation ends and the
1118 * second animation begins:
1122 * @example ecore_animator_example.c
1126 * @page ecore_thread_example_c Ecore_Thread - API overview
1128 * Working with threads is hard. Ecore helps to do so a bit easier, but as
1129 * the example in @ref ecore_thread_example.c "ecore_thread_example.c" shows,
1130 * there's a lot to consider even when doing the most simple things.
1132 * We'll be going through this thorough example now, showing how the differents
1133 * aspects of @ref Ecore_Thread are used, but users are encourage to avoid
1134 * threads unless it's really the only option, as they always add more
1135 * complexity than the program usually requires.
1137 * Ecore Threads come in two flavors, short jobs and feedback jobs. Short jobs
1138 * just run the given function and are more commonly used for small tasks
1139 * where the main loop does not need to know how the work is going in between.
1140 * The short job in our example is so short we had to artificially enlarge it
1141 * with @c sleep(). Other than that, it also uses threads local data to keep
1142 * the data we are working with persistent across different jobs ran by the
1143 * same system thread. This data will be freed when the no more jobs are
1144 * pending and the thread is terminated. If the data doesn't exist in the
1145 * thread's storage, we create it and save it there for future jobs to find
1146 * it. If creation fails, we cancel ourselves, so the main loop knows that
1147 * we didn't just exit normally, meaning the job could not be done. The main
1148 * part of the function checks in each iteration if it was canceled by the
1149 * main loop, and if it was, it stops processing and clears the data from the
1150 * storage (we assume @c cancel means no one else will need this, but this is
1151 * really application dependent).
1152 * @dontinclude ecore_thread_example.c
1158 * Feedback jobs, on the other hand, run tasks that will inform back to the
1159 * main loop its progress, send partial data as is processed, just ping saying
1160 * it's still alive and processing, or anything that needs the thread to talk
1161 * back to the main loop.
1166 * Finally, one more feedback job, but this one will be running outside of
1167 * Ecore's pool, so we can use the pool for real work and keep this very
1168 * light function unchecked. All it does is check if some condition is met
1169 * and send a message to the main loop telling it it's time to close.
1175 * Every now and then the program prints its status, counting threads running
1180 * In our main loop, we'll be receiving messages from our feedback jobs using
1181 * the same callback for both of them.
1185 * The light job running out of the pool will let us know when we can exit our
1189 * Next comes the handling of data sent from the actual worker threads, always
1190 * remembering that the data belongs to us now, and not the thread, so it's
1191 * our responsibility to free it.
1195 * Last, the condition to exit is given by how many messages we want to handle,
1196 * so we need to count them and inform the condition checking thread that the
1200 * When a thread finishes its job or gets canceled, the main loop is notified
1201 * through the callbacks set when creating the task. In this case, we just
1202 * print what happen and keep track of one of them used to exemplify canceling.
1203 * Here we are pretending one of our short jobs has a timeout, so if it doesn't
1204 * finish before a timer is triggered, it will be canceled.
1206 * @until _cancel_timer_cb
1209 * The main function does some setup that includes reading parameters from
1210 * the command line to change its behaviour and test different results.
1212 * @li -t \<some_num\> maximum number of threads to run at the same time.
1213 * @li -p \<some_path\> adds @c some_path to the list used by the feedback jobs.
1214 * This parameter can be used multiple times.
1215 * @li -m \<some_num\> the number of messages to process before the program is
1216 * signalled to exit.
1218 * Skipping some bits, we init Ecore and our application data.
1220 * @until appdata.max_msgs
1222 * If any paths for the feedback jobs were given, we use them, otherwise we
1223 * fallback to some defaults. Always initializing the proper mutexes used by the
1226 * @until EINA_LIST_FREE
1230 * Initialize the mutex needed for the condition checking thread
1231 * @skip appdata.mutex
1232 * @until appdata.condition
1234 * And start our tasks.
1235 * @until appdata.thread_3
1238 * To finalize, set a timer to cancel one of the tasks if it doesn't end
1239 * before the timeout, one more timer for status report and get into the main
1240 * loop. Once we are out, destroy our mutexes and finish the program.
1241 * @until _status_timer_cb
1244 * @example ecore_thread_example.c
1248 * @page ecore_evas_callbacks_example_c Ecore Evas Callbacks
1249 * @dontinclude ecore_evas_callbacks.c
1251 * Our example is remarkably simple, all it does is create an Ecore_Evas and
1252 * register a callback for a bunch of events. What's interesting here is
1253 * knowing when each of these callbacks will be called, however since that
1254 * depends on the underlying windowing system there are no guarantees that all
1255 * of the callbacks will be called for your windowing system. To know which
1256 * callbacks will be called for your windowing system run the example and
1257 * redirect the output to a file, and take a look at it.
1259 * @note Make sure you minimize, resize, give and remove focus to see more
1262 * The example is constituted of two main parts, first is the implementation of
1263 * callbacks that will be called for each event(all our callbacks do is print
1264 * their own name) and the second is the main function where we register the
1265 * event callbacks and run the main loop:
1266 * @include ecore_evas_callbacks.c
1267 * @example ecore_evas_callbacks.c
1271 * @page Ecore_Evas_Window_Sizes_Example_c Ecore_Evas window size hints
1273 * On this example, we show you how to deal with @c Ecore_Evas window
1274 * size hints, which are implemented <b>per Evas engine</b>.
1276 * We start by defining an initial size for our window and, after
1277 * creating it, adding a background white rectangle and a text object
1278 * to it, to be used to display the current window's sizes, at any
1280 * @dontinclude ecore_evas_window_sizes_example.c
1281 * @skip define WIDTH
1284 * @dontinclude ecore_evas_window_sizes_example.c
1287 * @dontinclude ecore_evas_window_sizes_example.c
1289 * @until main_loop_begin
1290 * @dontinclude ecore_evas_window_sizes_example.c
1294 * The program has a command line interface, responding to the
1296 * @dontinclude ecore_evas_window_sizes_example.c
1300 * Use the @c 'm' key to impose a minimum size of half the initial
1301 * ones on our window. Test it by trying to resize it to smaller sizes
1303 * @dontinclude ecore_evas_window_sizes_example.c
1304 * @skip keyname, "m"
1309 * The @c 'x' key will, in turn, set a maximum size on our window --
1310 * to two times our initial size. Test it by trying to resize the
1311 * window to bigger sizes than that:
1312 * @dontinclude ecore_evas_window_sizes_example.c
1313 * @skip keyname, "x"
1318 * Window base sizes will override any minimum sizes set, so try it
1319 * with the @c 'b' key. It will set a base size of two times the
1321 * @dontinclude ecore_evas_window_sizes_example.c
1322 * @skip keyname, "b"
1327 * Finally, there's a key to impose a "step size" on our window, of 40
1328 * pixels. With than on (@c 's' key), you'll see the window will
1329 * always be bound to @b multiples of that size, for dimensions on
1331 * @skip keyname, "s"
1336 * The full example follows.
1338 * @include ecore_evas_window_sizes_example.c
1339 * @example ecore_evas_window_sizes_example.c
1343 * @page ecore_evas_object_example_c Ecore Evas Object example
1344 * @dontinclude ecore_evas_object_example.c
1346 * This example creates an Ecore_Evas(a window) and associates a background and
1347 * a custom cursor for it.
1349 * We'll start looking at the association, which is quite simple. We choose to
1350 * associate using ECORE_EVAS_OBJECT_ASSOCIATE_BASE to have it be resized with
1351 * the window, since for a background that is what's most useful:
1352 * @skipline ecore_evas_object_associate
1353 * @note If we didn't associate the background we'd need to listen to resize of
1354 * Ecore_Evas and manually resize the background or have artifacts on our
1357 * We then check that the association worked:
1360 * Next we are going to set a custom cursor, for our cursor we are going to use
1361 * a small green rectangle. Our cursor is going to be on layer 0(any lower and
1362 * it would be below the background and thus invisible) and clicks will be
1363 * computed as happening on pixel 1, 1 of the image:
1366 * We then check every one of those parameters:
1369 * Here you have the full-source of the code:
1370 * @include ecore_evas_object_example.c
1371 * @example ecore_evas_object_example.c
1375 * @page ecore_evas_basics_example_c Ecore Evas basics example
1376 * @dontinclude ecore_evas_basics_example.c
1378 * This example will illustrates the usage of some basic Ecore_Evas functions.
1379 * This example will list the available evas engines, check which one we used to
1380 * create our window and set some data on our Ecore_Evas. It also allows you to
1381 * hide/show all windows in this process(we only have one, but if there were
1382 * more they would be hidden), to hide the windows type 'h' and hit return, to
1383 * show them, type 's' and hit return.
1385 * The very first thing we'll do is initialize ecore_evas:
1386 * @skipline evas_init
1389 * Once inited we query which engines are available:
1390 * @until ecore_evas_engines_free
1392 * We then create an Ecore_Evas(window) with the first available engine, on
1393 * position 0,0 with size 200,200 and no especial flags, set it's title and show
1397 * We now add some important data to our Ecore_Evas:
1400 * And since our data is dynamically allocated we'll need to free it when the
1402 * @until delete_request
1403 * @dontinclude ecore_evas_basics_example.c
1406 * @skip printf("Using
1408 * We now print which Evas engine is being used for our example:
1411 * We are going to add a background to our window but before we can do that
1412 * we'll need to get the canvas(Evas) on which to draw it:
1415 * We then do a sanity check, verifying if the Ecore_Evas of the Evas is the
1416 * Ecore_Evas from which we got the Evas:
1419 * Now we can actually add the background:
1420 * @until ecore_evas_object_associate
1422 * To hide and show the windows of this process when the user presses 'h' and
1423 * 's' respectively we need to know when the user types something, so we
1424 * register a callback for when we can read something from @c stdin:
1427 * The callback that actually does the hiding and showing is pretty simple, it
1428 * does a @c scanf(which we know won't block since there is something to read on
1429 * @c stdin) and if the character is an 'h' we iterate over all windows calling
1430 * @c ecore_evas_hide on them, if the character is an 's' we call @c
1431 * ecore_evas_show instead:
1432 * @dontinclude ecore_evas_basics_example.c
1433 * @skip static Eina_Bool
1435 * @skip ecore_main_loop_begin
1437 * Once all is done we run our main loop, and when that is done(application is
1438 * exiting) we free our Ecore_Evas and shutdown the ecore_evas subsystem:
1441 * Here you have the full-source of the code:
1442 * @include ecore_evas_basics_example.c
1443 * @example ecore_evas_basics_example.c
1447 * @page Ecore_Evas_Buffer_Example_01_c Ecore_Evas buffer example
1449 * Between the Evas examples, there is one in which one creates a
1450 * canvas bound to the Evas @b buffer engine and uses its pixel
1451 * contents to create an PPM image on disk. There, one does that by
1452 * creating the canvas "by hand", with @c evas_new(), @c
1453 * evas_engine_info_set(), etc.
1455 * On this example, we accomplish the very same task, but by using the
1456 * @c Ecore_Evas helper wrapper functions on a buffer engine
1457 * canvas. If you compare both codes, you'll see how much code one is
1458 * saved from by using the @c Ecore_Evas wrapper functions.
1460 * The code is simple as it can be. After instantianting our canvas
1461 * window, with ecore_evas_buffer_new(), we grab its canvas pointer
1462 * and create the desired objects scene on it, which in this case is
1463 * formed by 3 rectangles over the top left corner of a white
1465 * @dontinclude ecore_evas_buffer_example_01.c
1469 * Since it's a buffer canvas and we're using it to only save its
1470 * contents on a file, we even needn't ecore_evas_show() it. We make
1471 * it render itself, forcefully, without the aid of Ecore's main loop,
1472 * with ecore_evas_manual_render():
1473 * @dontinclude ecore_evas_buffer_example_01.c
1474 * @skip manual_render
1475 * @until manual_render
1477 * And we're ready to save the window's shiny rendered contents as a
1478 * simple PPM image. We do so by grabbing the pixels of the @c
1479 * Ecore_Evas' internal canvas, with ecore_evas_buffer_pixels_get():
1480 * @dontinclude ecore_evas_buffer_example_01.c
1483 * @dontinclude ecore_evas_buffer_example_01.c
1484 * @skip support function
1489 * Check that destination file for the result. The full example
1492 * @include ecore_evas_buffer_example_01.c
1493 * @example ecore_evas_buffer_example_01.c
1497 * @page Ecore_Evas_Buffer_Example_02_c Ecore_Evas (image) buffer example
1499 * In this example, we'll demonstrate the use of
1500 * ecore_evas_object_image_new(). The idea is to have the same scene
1501 * created for @ref Ecore_Evas_Buffer_Example_01_c as the contents of
1504 * The canvas receiving this image object will have a white
1505 * background, a red border image to delimit this image's boundaries
1506 * and the image itself. After we create the special image, we set
1507 * its "fill" property, place and resize it as we want. We have also
1508 * to resize its underlying @c Ecore_Evas too, to the same dimensions:
1509 * @dontinclude ecore_evas_buffer_example_02.c
1510 * @skip object_image_new
1511 * @until resize(sub_ee
1513 * Now, we re-create the scene we cited, using the sub-canvas of our
1514 * image to parent the objects in question. Because image objects are
1515 * created with the alpha channel enabled, by default, we'll be seeing
1516 * our white rectangle beneath the scene:
1517 * @dontinclude ecore_evas_buffer_example_02.c
1518 * @skip rectangle_add(sub_canvas
1521 * And that's all. The contents of our image could be updated as one
1522 * wished, and they would always be mirrored in the image's area.
1524 * Check that destination file for the result. The full example
1527 * @include ecore_evas_buffer_example_02.c
1528 * @example ecore_evas_buffer_example_02.c