From 0809af70fb0e762a748b5d72ed353971d88bae9b Mon Sep 17 00:00:00 2001 From: "Jonas M. Gastal" Date: Tue, 18 Dec 2012 16:13:03 +0000 Subject: [PATCH] efl: Adding *.dox files from various libs. SVN revision: 81274 --- doc/Doxyfile.in | 7 +- doc/ecore_examples.dox | 1692 ++++++++++++++++++++++++++++++++++++++++ doc/eet_examples.dox | 184 +++++ doc/eio.dox.in | 456 +++++++++++ doc/evas_examples.dox | 1073 +++++++++++++++++++++++++ 5 files changed, 3411 insertions(+), 1 deletion(-) create mode 100644 doc/ecore_examples.dox create mode 100644 doc/eet_examples.dox create mode 100644 doc/eio.dox.in create mode 100644 doc/evas_examples.dox diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index c89b7de306..016ca76947 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -592,7 +592,12 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @top_srcdir@/src/lib @srcdir@/main.dox +INPUT = @top_srcdir@/src/lib \ + @srcdir@/main.dox \ + @srcdir@/ecore_examples.dox \ + @srcdir@/eet_examples.dox \ + @srcdir@/evas_examples.dox \ + @builddir@/eio.dox # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/doc/ecore_examples.dox b/doc/ecore_examples.dox new file mode 100644 index 0000000000..cc7ec9d0d5 --- /dev/null +++ b/doc/ecore_examples.dox @@ -0,0 +1,1692 @@ +/** + * @page Examples Examples + * + * Here is a page with some Ecore examples explained: + * + * @li @ref ecore_time_functions_example_c + * @li @ref ecore_timer_example_c + * @li @ref ecore_idler_example_c + * @li @ref ecore_job_example_c + * @li @ref ecore_event_example_01_c + * @li @ref ecore_event_example_02_c + * @li @ref ecore_fd_handler_example_c + * @li @ref ecore_poller_example_c + * @li @ref ecore_con_lookup_example_c + * @li @ref ecore_con_url_download_example_c + * @li @ref ecore_con_server_simple_example_c + * @li @ref ecore_con_client_simple_example_c + * @li @ref ecore_evas_callbacks_example_c + * @li @ref ecore_evas_object_example_c + * @li @ref ecore_evas_basics_example_c + * @li @ref Ecore_Evas_Window_Sizes_Example_c + * @li @ref Ecore_Evas_Buffer_Example_01_c + * @li @ref Ecore_Evas_Buffer_Example_02_c + * @li @ref Ecore_exe_simple_example_c + * @li @ref ecore_imf_example_c + */ + +/** + * @page ecore_time_functions_example_c ecore_time - Differences between time functions + * + * This example shows the difference between calling ecore_time_get(), + * ecore_loop_time_get() and ecore_time_unix_get(). + * + * It initializes ecore, then sets a timer with a callback that, when called, + * will retrieve the system time using these 3 different functions. After + * displaying the time, it sleeps for 1 second, then call display the time + * again using the 3 functions. + * + * Since everything occurs inside the same main loop iteration, the internal + * ecore time variable will not be updated, and calling ecore_loop_time_get() + * before and after the sleep() call will return the same result. + * + * The two other functions will return a difference of 1 second, as expected. + * But ecore_time_unix_get() returns the number of seconds since 00:00:00 1st + * January 1970, while ecore_time_get() will return the time since a + * unspecified point, but that never goes back in time, even when the timezone + * of the machine changes. + * + * @note The usage of ecore_loop_time_get() should be preferred against the + * two other functions, for most time calculations, since it won't produce a + * system call to get the current time. Use ecore_time_unix_get() when you need + * to know the current time and date, and ecore_time_get() when you need a + * monotonic and more precise time than ecore_loop_time_get(). + * + * @include ecore_time_functions_example.c + */ + +/** + * @page ecore_timer_example_c ecore timers - Scheduled events + * @dontinclude ecore_timer_example.c + * + * This example shows how to setup timer callbacks. It starts a timer that will + * tick (expire) every 1 second, and then setup other timers that will expire + * only once, but each of them will affect the first timer still executing with + * a different API, to demonstrate its usage. To see the full code for this + * example, click @ref ecore_timer_example.c "here". + * + * To demonstrate this, let's define some constants that will determine at which + * time each timer will expire: + * + * @until INTERVAL1 + * + * These constants should tell by themselves what will be the behavior of the + * program, but I'll explain it anyway. The first timer is set to tick every 1 + * second, but all the other timers until the 6th one will be started + * concurrently at the beginning of the program. Each of them will expire at the + * specified time in these constants: + * + * @li The timer2, after 3 seconds of the program being executed, will add a delay + * of 3 seconds to timer1; + * @li The timer3 will pause timer1 at 8.2 seconds; + * @li timer4 will resume timer1 at 11.0 seconds; + * @li timer5 will will change the interval of timer1 to 2 seconds; + * @li timer6 will stop timer1 and start timer7 and timer8, with 1.1 and 1.2 + * seconds of interval, respectively; it also sets the precision to 0.2 seconds; + * @li timer7 and timer8 will just print their expiration time. + * + * @until ecore_time_get + * @until } + * + * As almost all the other examples, we create a context structure to pass to + * our callbacks, so they can have access to the other timers. We also store the + * time of the program start in @c _initial_time, and use the function + * @c _get_current_time to retrieve the current time relative to that time. This + * will help demonstrate what is going on. + * + * Now, the behavior and relationship between the timers that was described + * above is dictated by the following timer callbacks: + * + * @until _timer6_cb + * @until } + * + * It's possible to see the same behavior as other Ecore callbacks here, + * returning @ref ECORE_CALLBACK_RENEW when the timer needs to continue ticking, + * and @ref ECORE_CALLBACK_CANCEL when it needs to stop its execution. Also + * notice that later on our program we are checking for the timers pointers in + * the context to see if they are still executing before deleting them, so we + * need to set these timer pointers to @c NULL when we are returning @ref + * ECORE_CALLBACK_CANCEL. Otherwise the pointer would still be not @c NULL, but + * pointing to something that is invalid, since the timer would have already + * expired without renewing. + * + * Now the main code, which will start the timers: + * + * @until ecore_shutdown + * @until } + * + * This code is very simple. Just after starting the library, it will save the + * current time to @c _initial_time, start all timers from 1 to 6, and begin the + * main loop. Everything should be running right now, displaying the time which + * each timer is expiring, and what it is doing to affect the other timers. + * + * After returning from the main loop, every timer is checked to see if it's + * still alive and, in that case, deleted, before finalizing the library. This + * is not really necessary, since ecore_shutdown() will already delete them for + * you, but it's good practice if you have other things going on after this + * point that could restart the main loop. + * + */ + +/** + * @page ecore_idler_example_c ecore idle state - Idlers, enterers and exiters + * + * This example demonstrates how to manage the idle state of the main loop. Once + * a program knows that the main loop is going to enter in idle state, it could + * start doing some processing until getting out of this state. + * + * To exemplify this, we also add events and a timer to this program, so we can + * see the idle exiter callback being called before processing the event and/or + * timer, the event/timer callback being called (processed), then the idle + * enterer being called before entering in idle state again. Once in idle, the + * main loop keeps calling the idler callback continuously until a new event or + * timer is received. + * + * First, we declare a struct that will be used as context to be passed to + * every callback. It's not useful everywhere, since this example is very + * simple and doesn't do anything other than printing messages, but using this + * context will make it a little bit more real. Our context will be used to + * delete the timer, idler, idle enterer and exiter, and the event handler, and + * also to count how many times the idler was called. + * + * Then we start declaring callbacks for the idle enterer, idle exiter and the + * idler itself. Idle enterer and exiter callbacks just print a message saying + * that they were called, while the idler, in addition to printing a message + * too, also sends an event every 10 times that it is called, incrementing the + * context count variable. This event will be used to make the main loop exit + * the idle state and call the event callback. + * + * These callbacks return @ref ECORE_CALLBACK_RENEW, since we want them to keep + * being called every time the main loop changes to/from idle state. Otherwise, + * if we didn't want them to be called again, they should return @ref + * ECORE_CALLBACK_CANCEL. + * + * The next function declared is the event callback @c _event_handler_cb. It + * will check if the idler was called more than 100 times already @c + * (ctxt->count > 100), and will delete the idler, idle enterer and exiter, the + * timer (if it still exists), and request that the main loop stop running. Then + * it returns @ref ECORE_CALLBACK_DONE to indicate that the event shouldn't be + * handled by any other callback. + * + * Finally, we add a callback to the timer, that will just print a message when + * it is called, and this will happen only once (@ref ECORE_CALLBACK_CANCEL is + * being returned). This timer callback is just here to show that the main loop + * gets out of idle state when processing timers too. + * + * The @b main function is simple, just creates a new type of event that we will + * use to demonstrate the event handling together with the idle state, adds the + * callbacks that we declared so far, fill the context struct, and starts + * running the main loop. + * + * @note We use timer and event callbacks to demonstrate the idle state + * changing, but it also happens for file descriptor handlers, pipe handlers, + * etc. + * + * @include ecore_idler_example.c + */ + +/** + * @page ecore_job_example_c ecore_job - Queuing tasks + * + * This example shows how an @ref Ecore_Job can be added, how it can be + * deleted, and that they always execute in the added order. + * + * First, 2 callback functions are declared, one that prints strings passed to + * it in the @c data pointer, and another one that quits the main loop. In the + * @c main function, 3 jobs are added using the first callback, and another one + * is added using the second one. + * + * Then the second added job is deleted just to demonstrate the usage of + * ecore_job_del(), and the main loop is finally started. Run this example to + * see that @c job1, @c job3 and @c job_quit are ran, in this order. + * + * @include ecore_job_example.c + */ + +/** + * @page ecore_event_example_01_c Handling events example + * This example shows the simplest possible way to register a handler for an + * ecore event, this way we can focus on the important aspects. The example will + * start the main loop and quit it when it receives the ECORE_EVENT_SIGNAL_EXIT + * event. This event is triggered by a SIGTERM(pressing ctrl+c). + * + * So let's start with the function we want called when we receive the event, + * instead of just stopping the main loop we'll also print a message, that's + * just so it's clear that it got called: + * @dontinclude ecore_event_example_01.c + * @skip static + * @until } + * @note We return ECORE_CALLBACK_DONE because we don't want any other handlers + * for this event to be called, the program is quitting after all. + * + * We then have our main function and the obligatory initialization of ecore: + * @until ecore_init + * + * We then get to the one line of our example that makes everything work, the + * registering of the callback: + * @until handler_add + * @note The @c NULL there is because there is no need to pass data to the + * callback. + * + * And the all that is left to do is start the main loop: + * @until } + * + * Full source code for this example: @ref ecore_event_example_01.c. + */ + +/** + * @page ecore_event_example_02_c ecore events and handlers - Setup and use + * This example shows how to create a new type of event, setup some event + * handlers to it, fire the event and have the callbacks called. After + * finishing, we delete the event handlers so no memory will leak. + * + * See the full source code for this example @ref ecore_event_example_02.c + * "here". + * + * Let's start the example from the beginning: + * + * @dontinclude ecore_event_example_02.c + * @until _event_type + * + * First thing is to declare a struct that will be passed as context to the + * event handlers. In this structure we will store the event handler pointers, + * and two strings that will be used by the first event handler. We also will + * use a global integer to store the event type used for our event. It is + * initialized with 0 in the beginning because the event wasn't created yet. + * Later, in the main function we will use ecore_event_type_new() to associate + * another value to it. Now the event handler callbacks: + * + * @until } + * + * This is the first event handler callback. It prints the event data received + * by the event, and the data passed to this handler when it was added. Notice + * that this callback already knows that the event data is an integer pointer, + * and that the handler data is a string. It knows about the first one because + * this is based on the type of event that is going to be handled, and the + * second because it was passed to the ecore_event_handler_add() function when + * registering the event handler. + * + * Another interesting point about this callback is that it returns @ref + * ECORE_CALLBACK_DONE (0) if the event data is even, swallowing the event and + * don't allowing any other callback to be called after this one for this event. + * Otherwise it returns @ref ECORE_CALLBACK_PASS_ON, allowing the event to be + * handled by other event handlers registered for this event. This makes the + * second event handler be called just for "odd" events. + * + * @until ECORE_CALLBACK_DONE + * @until } + * + * The second event handler will check if the event data is equal to 5, and if + * that's the case, it will change the event handler data of the first event + * handler to another string. Then it checks if the event data is higher than + * 10, and if so, it will request the main loop to quit. + * + * An interesting point of this example is that although the second event + * handler requests the main loop to finish after the 11th event being received, + * it will process all the events that were already fired, and call their + * respective event handlers, before the main loop stops. If we didn't want + * these event handlers to be called after the 11th event, we would need to + * unregister them with ecore_event_handler_del() at this point. + * + * Now some basic initialization of the context, and the Ecore library itself: + * + * @until type_new + * + * This last line is interesting. It creates a new type of event and returns a + * unique ID for this event inside Ecore. This ID can be used anywhere else in + * your program to reference this specific type of event, and to add callbacks + * to it. + * + * It's common if you are implementing a library that declares new types of + * events to export their respective types as extern in the header files. This + * way, when the library is initialized and the new type is created, it will be + * available through the header file to an application using it add some + * callbacks to it. Since our example is self-contained, we are just putting it + * as a global variable. + * + * Now we add some callbacks: + * + * @until ctxt); + * + * This is very simple. Just need to call ecore_event_handler_add() with the + * respective event type, the callback function to be called, and a data pointer + * that will be passed to the callback when it is called by the event. + * + * Then we start firing events: + * + * @until } + * + * This @c for will fire 16 events of this type. Notice that the events will be + * fired consecutively, but any callback will be called yet. They are just + * called by the main loop, and since it wasn't even started, nothing happens + * yet. For each event fired, we allocate an integer that will hold the number + * of the event (we are arbitrarily creating these numbers just for + * demonstration purposes). It's up to the event creator to decide which type of + * information it wants to give to the event handler, and the event handler must + * know what is the event info structure for that type of event. + * + * Since we are not allocating any complex structure, just a simple integer, we + * don't need to pass any special free function to ecore_event_add(), and it + * will use a simple @c free on our data. That's the default behavior. + * + * Now finishing our example: + * + * @until } + * + * We just start the main loop and watch things happen, waiting to shutdown + * Ecore when the main loop exits and return. + */ + +/** + * @page ecore_fd_handler_example_c ecore fd handlers - Monitoring file descriptors + * @dontinclude ecore_fd_handler_example.c + * + * This is a very simple example where we will start monitoring the stdin of the + * program and, whenever there's something to be read, we call our callback that + * will read it. + * + * Check the full code for this example @ref ecore_fd_handler_example.c "here". + * + * This seems to be stupid, since a similar result could be achieved by the + * following code: + * + * @code + * while (nbytes = read(STDIN_FILENO, buf, sizeof(buf))) + * { + * buf[nbytes - 1] = '\0'; + * printf("Read %zd bytes from input: \"%s\"\n", nbytes - 1, buf); + * } + * @endcode + * + * However, the above code is blocking, and won't allow you to do anything else + * other than reading the input. Of course there are other methods to do a + * non-blocking reading, like setting the file descriptor to non-blocking and + * keep looping always checking if there's something to be read, and do other + * things otherwise. Or use a @c select call to watch for more than one file + * descriptor at the same time. + * + * The advantage of using an @ref Ecore_Fd_Handler is that you can monitor a + * file descriptor, while still iterating on the Ecore main loop. It will allow + * you to have timers working and expiring, events still being processed when + * received, idlers doing its work when there's nothing happening, and whenever + * there's something to be read from the file descriptor, your callback will be + * called. And it's everything monitored in the same main loop, no threads are + * needed, thus reducing the complexity of the program and any overhead caused + * by the use of threads. + * + * Now let's start our program. First we just declare a context structure that + * will be passed to our callback, with pointers to our handler and to a timer + * that will be used later: + * + * @until }; + * + * Then we will declare a prepare_callback that is called before any fd_handler + * set in the program, and before the main loop select function is called. Just + * use one if you really know that you need it. We are just putting it here to + * exemplify its usage: + * + * @until } + * + * Now, our fd handler. In its arguments, the @c data pointer will have any data + * passed to it when it was registered, and the @c handler pointer will contain + * the fd handler returned by the ecore_main_fd_handler_add() call. It can be + * used, for example, to retrieve which file descriptor triggered this callback, + * since it could be added to more than one file descriptor, or to check what + * type of activity there's in the file descriptor. + * + * The code is very simple: we first check if the type of activity was an error. + * It probably won't happen with the default input, but could be the case of a + * network socket detecting a disconnection. Next, we get the file descriptor + * from this handler (as said before, the callback could be added to more than + * one file descriptor), and read it since we know that it shouldn't block, + * because our fd handler told us that there's some activity on it. If the + * result of the read was 0 bytes, we know that it's an end of file (EOF), so we + * can finish reading the input. Otherwise we just print the content read from + * it: + * + * @until } + * + * Also notice that this callback returns @ref ECORE_CALLBACK_RENEW to keep + * being called, as almost all other Ecore callbacks, otherwise if it returns + * @ref ECORE_CALLBACK_CANCEL then the file handler would be deleted. + * + * Just to demonstrate that our program isn't blocking in the input read but + * still can process other Ecore events, we are going to setup an @ref + * Ecore_Timer. This is its callback: + * + * @until } + * + * Now in the main code we are going to initialize the library, and setup + * callbacks for the file descriptor, the prepare callback, and the timer: + * + * @until timer_add + * + * Notice that the use of ecore_main_fd_handler_add() specifies what kind of + * activity we are monitoring. In this case, we want to monitor for read (since + * it's the standard input) and for errors. This is done by the flags @ref + * ECORE_FD_READ and @ref ECORE_FD_ERROR. For the three callbacks we are also + * giving a pointer to our context structure, which has pointers to the handlers + * added. + * + * Then we can start the main loop and see everything happening: + * + * @until } + * + * In the end we are just deleting the fd handler and the timer to demonstrate + * the API usage, since Ecore would already do it for us on its shutdown. + */ + +/** + * @page ecore_poller_example_c ecore poller - Repetitive polling tasks + * @dontinclude ecore_poller_example.c + * + * This example show how to setup, and explains how an @ref Ecore_Poller is + * called. You can @ref ecore_poller_example.c "see the full source code here". + * + * In this example we store the initial time of the program just to use as + * comparison to the time when the poller callbacks are called. It will be + * stored in @c _initial_time : + * + * @until initial_time + * + * Then next step is to define the poller callback. This callback assumes that a + * @c data pointer is passed to it on creation, and is a string just used to + * identify the poller. The callback prints this string and the time since the + * program started, and returns @ref ECORE_CALLBACK_RENEW to keep being called. + * + * @until } + * + * Now in the main function we initialize Ecore, and save the initial time of + * the program, so we can compare it later with the time that the pollers are + * being called: + * + * @until initial_time + * + * Then we change the poll interval to 0.3 seconds (the default is 0.125 + * seconds) just to show the API usage. + * + * Finally, we create two pollers, one that will be called every 4 ticks, and + * another one that will be called every 8 ticks. This means the the first + * poller interval will be around 1.2 seconds, and the second one will be + * around 2.4 seconds. But the most important point is: since the second poller + * interval is a multiple of the first one, they will be always synchronized. + * Ecore calls pollers that are in the "same tick" together. It doesn't go back + * to the main loop and check if there's another poller to execute at this + * time, but instead it calls all the pollers registered to this "tick" at the + * same time. See the description of ecore_poller_add() for more details. This + * is easy to see in the time printed by both of them. + * + * If instead of two synchronized pollers, we were using two different timers, + * one with interval of 1.2 seconds and another one with an interval of 2.4 + * seconds, there would be no guarantee that they would be totally in sync. Some + * delay in the execution of another task, or even in the task called in the + * callback, could make them get out of sync, forcing Ecore's main loop to wake + * up more than necessary. + * + * Well, this is the code that create these two pollers and set the poll + * interval, then starts the main loop: + * + * @until ecore_main_loop_begin + * + * If you hit CTRL-C during the execution of the program, the main loop will + * quit, since there are some signal handlers already set by default to do this. + * So after the main loop begin call, we change the second poller's interval to + * 16 ticks, so it will happen each 4.8 seconds (or each 4 times that the first + * poller is called). + * + * This means: the program is started, the first poller is called each 4 ticks + * and the second is called each 8 ticks. After CTRL-C is used, the second + * poller will be called each 16 ticks. + * + * @until } + * + * The rest of the program is just deleting the pollers and shutting down the + * library. + */ + +/** + * @page ecore_con_lookup_example_c Ecore_Con - DNS lookup + * + * This is a very simple example that shows how to make a simple DNS lookup + * using ecore_con_lookup(). + * + * It's possible to see in the beginning of the main function that we are using + * the arguments passed via command line. This is the address that we are going + * to make the DNS lookup on. + * + * The next step is to initialize the libraries, and just call + * ecore_con_lookup(). This function will get the string that contains the + * address to be resolved as first parameter, then a callback that will be + * called when the resolve stage is done, and finally a data pointer that will + * be passed to the callback. + * + * This function is asynchronous, and the callback will be called only on + * success. If there was an error during the resolve stage, there's no way to + * know about that. It's only possible to know about errors when setting up the + * lookup, by looking at the return code of the ecore_con_lookup() function. + * + * The callback @c _lookup_done_cb passed as argument to ecore_con_lookup() just + * prints the resolved canonical name, IP, address of the sockaddr structure, + * and the length of the socket address (in bytes). + * + * Finally, we start the main loop, and after that we finalize the libraries and + * exit. + * + * This is the code for this simple example: + * + * @include ecore_con_lookup_example.c + */ + +/** + * @page ecore_con_url_download_example_c Ecore_Con_Url - downloading a file + * + * This is a simple example that shows how to download a file using @ref + * Ecore_Con_Url. The full source code for this example can be found at @ref + * ecore_con_url_download_example.c. + * + * First we are setting some callbacks for events that will be sent when data + * arrives in our connection (the data is the content of the file being + * downloaded), and when the download is completed. The @c _url_progress_cb and + * @c _url_complete_cb are these callbacks: + * + * @dontinclude ecore_con_url_download_example.c + * @skip struct + * @until main_loop_quit + * @until } + * + * Notice that we also declared a struct that will hold how many bytes were + * downloaded through this object. It will be set in the @c main function using + * ecore_con_url_data_set(). + * + * In the next step, on the @c main function, we open a file where we are going + * to save the content being downloaded: + * + * @until open( + * @until } + * + * With the file successfully open, let's create our @ref Ecore_Con_Url object. + * For this, we initialize the libraries and create the object: + * + * @until } + * + * Then we allocate and set the data struct to the connection object, and set a + * file descriptor from our previously open file to it. We also add the event + * handlers (callbacks) to the events that will be emitted on data being + * received and download complete: + * + * @until complete_cb + * + * Finally we start our request, and run the main loop: + * + * @until return 0 + * @until } + * + * The rest of this code was just freeing resources, with some labels to be used + * for error handling. + */ + +/** + * @page ecore_con_url_cookies_example_c Ecore_Con_Url - Managing cookies + * + * This example shows how to use an @ref Ecore_Con_Url and enable it to + * receive/send cookies. These cookies can be set by the server, saved to a + * file, loaded later from this file and sent again to the server. The complete + * example can be found at @ref ecore_con_url_cookies_example.c + * "ecore_con_url_cookies_example.c" + * + * First we are setting some callbacks for events that will be sent when data + * arrives in our connection (the data is the content of the file being + * downloaded), and when the download is completed. The @c _url_data_cb and + * @c _url_complete_cb are these callbacks: + * + * @dontinclude ecore_con_url_download_example.c + * @skip Eina_Bool + * @until main_loop_quit + * @until } + * + * In the @c main function we parse some parameter from the command line. These + * parameters are the url that we are connecting to, and cookie use policy. + * + * After that we initialize the libraries and create a handler to our request + * using the given url: + * + * @until goto end + * @until } + * + * We also set the event handlers for this request and add a header to it, that + * will inform our custom user agent: + * + * @until User-Agent + * + * Now we start playing with cookies. First, let's call + * ecore_con_url_cookies_init() to inform that we want cookies enabled. We also + * set a file from which we are loading previously set (old) cookies, in case + * that we don't want to clear old cookies or old session cookies. + * + * After that we set the file where we are going to save all valid cookies in + * the @ref Ecore_Con_Url object. This includes previously loaded cookies (that + * weren't cleared) and new cookies set by the response header "Set-Cookie" that + * comes with the response to our request: + * + * @until jar_file_set + * + * And finally, before performing the request, we check the command passed as + * argument in the command line and use it to choose between clearing old + * cookies, clearing just old session cookies, or ignoring old session cookies. + * + * After that we just finish our code as expected: + * + * @until return + * @until } + * + * Notice that in this code, if we want to clear old cookies, we also don't load + * them from the file. This is a bit confusing and the API isn't clear, but + * ecore_con_url_cookies_file_add() will load cookies from the specified files + * just when the operation is really performed (i.e. ecore_con_url_get() is + * called). So if ecore_con_url_cookies_clear() is called before + * ecore_con_url_get(), the old cookies may not have been loaded yet, so they + * are not cleared. To avoid having old cookies loaded, don't add any cookie + * file with ecore_con_url_cookies_file_add(). + * + * The function ecore_con_url_cookies_clear() is just useful to clear cookies + * that are already loaded/valid in the @ref Ecore_Con_Url object (from a + * previous request, for example). + */ + +/** + * @page ecore_con_url_headers_example_c Ecore_Con_Url - customizing a request + * + * This is a simple example that shows how to make a custom request using @ref + * Ecore_Con_Url. The full source code for this example can be found at @ref + * ecore_con_url_headers_example.c. + * + * The first part of the example is setting the callbacks to be called when an + * #ECORE_CON_EVENT_URL_DATA or #ECORE_CON_EVENT_URL_COMPLETE event is received. + * These are the callbacks that are going to be used with this: + * + * @dontinclude ecore_con_url_headers_example.c + * @skip static + * @until main_loop_quit + * @until } + * + * The @c main code is as simple as the @ref Ecore_Con_Url example. It contains + * some checks for the arguments to see if a GET or POST request is required: + * + * @until GET + * @until } + * + * Then we start our required libraries and configure a global option to use + * pipelined requests: + * + * @until pipeline_set + * + * Now we create our request object, but using ecore_con_url_custom_new() to use + * a POST or GET method depending on the command line arguments. And we also add + * the event handlers for our callbacks: + * + * @until complete_cb + * + * In order to demonstrate our API, some options are set to this request before + * actually performing it: + * + * @until url_time + * + * Depending on what kind of request was asked (GET or POST), we use one of the + * specific functions to perform it: + * + * @until url_post + * + * After that, we just check for errors, start the main loop, free resources and + * finally exit: + * + * @until return + * @until } + */ + +/** + * @page ecore_con_server_simple_example_c Ecore_Con - Creating a server + * + * In this example we are going to create a server that listens for connections + * from clients through a TCP port. You can get the full source code at @ref + * ecore_con_server_simple_example.c. + * + * We begin our example in the main function, to demonstrate how to setup + * things, and then go to the callbacks that are needed for it to run properly. + * + * In the @c main function, after initializing the libraries, we use + * ecore_con_server_add() to startup the server. Look at the reference + * documentation of this function: it supports many types of server, and we are + * going to use #ECORE_CON_REMOTE_TCP (a TCP based server). Other arguments to + * this function are the address where we are listening on, the port, and a data + * pointer that will associate that data with the server: + * + * @dontinclude ecore_con_server_simple_example.c + * @skip main(void) + * @until exit + * + * Notice that we are listening only on 127.0.0.1, which is the internal + * loopback interface. If the server needs to listening on all of its ips, use + * 0.0.0.0 instead. + * + * We also need to set event handlers to be called when we receive any data from + * the clients, when a new client connects to our server, or when a client + * disconnects. These callbacks are: + * + * @until CLIENT_DATA + * + * More details about what these callbacks do will be given later. + * + * Now, before running the main loop, we also want to set some limits to our + * server. To avoid it to be overloaded with too many connections to handle, we + * are going to set a maximum of 3 clients connected at the same time. This + * number is used just to demonstrate the API. A good number to be used here + * would need to be determined by tests done on the server, to check the load + * supported by it. + * + * Any other client trying to connect to this server, after the limit is + * reached, will wait until one of the connected clients disconnect and the + * server accepts the new connection. + * + * Another important thing to do is setting a timeout, to avoid that a client + * hold a connection for too long without doing anything. This timeout will + * disconnect the idle client, allowing that other clients that may be waiting + * to connect finally can do it. + * + * Then we just start the main loop: + * + * @until main_loop_begin + * + * After exiting the main loop, we print the list of connected clients, and also + * free the data associated with each respective client. This data was + * previously associated using ecore_con_client_data_set(): + * + * @until } + * + * Then before exiting we show the total uptime of the server: + * + * @until uptime + * + * Now let's go back to the used callbacks. + * + * The first callback, @c _add, is registered to the event + * #ECORE_CON_EVENT_CLIENT_ADD, which will be called whenever a client connects + * to the server. + * + * This callback will associate a data structure to this client, that will be + * used to count how many bytes were received from it. It also prints some info + * about the client, and send a welcome string to it. ecore_con_client_flush() + * is used to ensure that the string is sent immediately, instead of being + * buffered. + * + * A timeout for idle specific for this client is also set, to demonstrate that + * it is independent of the general timeout of the server. + * + * Before exiting, the callback will display a list of all clients still + * connected to this server. The code for this callback follows: + * + * @dontinclude ecore_con_server_simple_example.c + * @skip Eina_Bool + * @until CALLBACK_RENEW + * @until } + * + * The second callback is @c _del. It is associated with + * #ECORE_CON_EVENT_CLIENT_DEL, and is called whenever a client disconnects from + * this server. + * + * It will just print some information about the client, free the associated + * data structure, and call ecore_con_client_del() on it before exiting the + * callback. Here's its code: + * + * @until CALLBACK_RENEW + * @until } + * + * The last callback will print any data received by this server from its + * clients. It also increments the "bytes received" counter, sdata, in the + * data structure associated with this client. The callback code follows: + * + * @until CALLBACK_RENEW + * @until } + * + * The important parts of this example were described above. If you need to see + * the full source code for it, there's a link to the code in the beginning of + * this page. + * + * This example will start a server and start accepting connections from clients, as + * demonstrated in the following diagram: + * @htmlonly + * + * Full size + * @endhtmlonly + * + * @image rtf ecore_con-client-server-example.png + * @image latex ecore_con-client-server-example.eps width=\textwidth + * + * @note This example contains a serious security flaw: it doesn't check for the + * size of data being received, thus allowing to the string to be exploited in + * some way. However, it is left like this to make the code simpler and just + * demonstrate the API usage. + */ + +/** + * @page ecore_con_client_simple_example_c Ecore_Con - Creating a client + * + * Following the same idea as the @ref ecore_con_server_simple_example_c , this + * example will demonstrate how to create a client that connects to a specified + * server through a TCP port. You can see the full source code at @ref + * ecore_con_client_simple_example.c. + * + * Starting from the @c main function, after reading the command line argument + * list and initializing the libraries, we try to connect to the server: + * + * @dontinclude ecore_con_client_simple_example.c + * @skip main( + * @until exit(2) + * @until } + * + * After doing this, everything else in @c main is setting up callbacks for the + * client events, starting the main loop and shutting down the libraries after + * it. + * + * Now let's go to the callbacks. These callbacks are very similar to the server + * callbacks (our implementation for this example is very simple). On the + * @c _add callback, we just set a data structure to the server, print some + * information about the server, and send a welcome message to it: + * + * @dontinclude ecore_con_client_simple_example.c + * @skip Eina_Bool + * @until CALLBACK_RENEW + * @until } + * + * The @c _del callback is as simple as the previous one. We free the data + * associated with the server, print the uptime of this client, and quit the + * main loop (since there's nothing to do once we disconnect): + * + * @until CALLBACK_RENEW + * @until } + * + * The @c _data callback is also similar to the server data callback. it will + * print any received data, and increase the data counter in the structure + * associated with this server: + * + * @skip Eina_Bool + * @until CALLBACK_RENEW + * @until } + * + * You can see the server counterpart functions of the ones used in this example + * in the @ref ecore_con_server_simple_example_c. + * + * This example will connect to the server and start comunicating with it, as + * demonstrated in the following diagram: + * @htmlonly + * + * Full size + * @endhtmlonly + * + * @image rtf ecore_con-client-server-example2.png + * @image latex ecore_con-client-server-example2.eps width=\textwidth + * + * @note This example contains a serious security flaw: it doesn't check for the + * size of data being received, thus allowing to the string to be exploited in + * some way. However, it is left like this to make the code simpler and just + * demonstrate the API usage. + */ + +/** + * @example ecore_idler_example.c + * This example shows when @ref Ecore_Idler, @ref Ecore_Idle_Enterer and @ref + * Ecore_Idle_Exiter are called. See + * @ref ecore_idler_example_c "the explanation here". + */ + +/** + * @example ecore_job_example.c + * This example shows how to use an @ref Ecore_Job. See + * @ref ecore_job_example_c "the explanation here". + */ + +/** + * @example ecore_time_functions_example.c + * Shows the difference between the three time functions. See @ref + * ecore_time_functions_example_c "the example explained". + */ + +/** + * @example ecore_timer_example.c + * This example show how to use timers to have timed events inside ecore. + * See @ref ecore_timer_example_c "the example explained". + */ + +/** + * @example ecore_exe_example_child.c + * This is a child process used to receive messages and send it back + * to its father. + * Check the @ref Ecore_exe_simple_example_c "Full tutorial" + */ + +/** + * @example ecore_exe_example.c + * This is a process that will send messages to a child and it will stop + * when it receives "quit". + * Check the @ref Ecore_exe_simple_example_c "Full tutorial" + */ + +/** + * @example ecore_fd_handler_example.c + * This example shows how to setup and use an fd_handler. See + * @ref ecore_fd_handler_example_c "the explanation here". + */ + +/** + * @example ecore_poller_example.c + * This example shows how to setup and use a poller. See + * @ref ecore_poller_example_c "the explanation here". + */ + +/** + * @example ecore_event_example_01.c + * This example shows how to create an event handler. Explanation: @ref + * ecore_event_example_01_c + */ + +/** + * @example ecore_event_example_02.c + * This example shows how to setup, change, and delete event handlers. See + * @ref ecore_event_example_02_c "the explanation here". + */ + +/** + * @example ecore_fd_handler_gnutls_example.c + * Shows how to use fd handlers. + */ + +/** + * @example ecore_con_lookup_example.c + * Shows how to make a simple DNS lookup. See the complete example description + * at @ref ecore_con_lookup_example_c + */ + +/** + * @example ecore_con_url_download_example.c + * Shows how to download a file using an @ref Ecore_Con_Url object. See the + * complete example description at @ref ecore_con_url_download_example_c + */ + +/** + * @example ecore_con_url_cookies_example.c + * Shows how to manage cookies on a @ref Ecore_Con_Url object. See the complete + * example description at @ref ecore_con_url_cookies_example_c. + */ + +/** + * @example ecore_con_server_simple_example.c + * Shows how to setup a simple server that accepts client connections and sends + * a "hello" string to them. See the complete example description at @ref + * ecore_con_server_simple_example_c + */ + +/** + * @example ecore_con_client_simple_example.c + * Shows how to setup a simple client that connects to a server and sends a + * "hello" string to it. See the complete example description at @ref + * ecore_con_client_simple_example_c + */ + +/** + * @example ecore_con_url_headers_example.c + * Shows how to make GET or POST requests using an @ref Ecore_Con_Url object, + * and make use of most of its API. See the complete example description at + * @ref ecore_con_url_headers_example_c + */ + +/** + * @page tutorial_ecore_pipe_gstreamer_example + * + * Here is an example that uses the pipe wrapper with a Gstreamer + * pipeline. For each decoded frame in the Gstreamer thread, a handle + * is called in the ecore thread. + * + * @include ecore_pipe_gstreamer_example.c + * @example ecore_pipe_gstreamer_example.c + */ + +/** + * @page tutorial_ecore_pipe_simple_example + * @dontinclude ecore_pipe_simple_example.c + * + * This example shows some simple usage of ecore_pipe. We are going to create a + * pipe, fork our process, and then the child is going to communicate to the + * parent the result of its processing through the pipe. + * + * As always we start with our includes, nothing special: + * @skip #include + * @until Ecore.h + * + * The first thing we are going to define in our example is the function we are + * going to run on the child process, which, as mentioned, will do some + * processing and then will write the result to the pipe: + * @until } + * @until } + * @note The sleep was added so the parent process would think the child process + * was doing something interesting... + * + * Next up is our function for handling data arriving in the pipe. It copies the + * data to another buffer, adds a terminating NULL and prints it. Also if it + * receives a certain string it stops the main loop(effectively ending the + * program): + * @until } + * @until } + * + * And now on to our main function, we start by declaring some variables and + * initializing ecore: + * @until ecore_init + * + * And since we are talking about pipes let's create one: + * @until pipe_add + * + * Now we are going to fork: + * @until fork + * @note duh... + * + * The child process is going to do the our fancy processing: + * @until } + * @note It's very important to call ecore_pipe_read_close() here so that the + * child process won't read what it is writing to the pipe itself. + * + * And the parent is going to run ecore's main loop waiting for some data: + * @until } + * @note Calling ecore_pipe_write_close() here isn't important but since we + * aren't going to write in the pipe it is good practice. + * + * And finally when done processing(the child) or done receiving(the parent) we + * delete the pipe and shutdown ecore: + * @until } + * + * @example ecore_pipe_simple_example.c + */ + +/** + * @page tutorial_ecore_animator Ecore animator example + * @dontinclude ecore_animator_example.c + * + * For this example we are going to animate a rectangle growing, moving and + * changing color, and then move it back to it's initial state with a + * different animation. We are also going to have a second rectangle moving + * along the bottom of the screen. To do this we are going to use ecore_evas, + * but since that is not the focus here we won't going into detail about it. + * + * @skip #include + * @until evas_object_show + * @until evas_object_show + * All of this is just setup, not what we're interested in right now. + * + * Now we are going to set the frametime for our animation to one fiftieth of + * a second, this will make our program consume more resources but should make + * our animation extra smooth: + * @until frametime + * + * And now we get right to the business of creating our ecore_animator: + * @until timeline + * @note We are telling our animation to last 10 second and to call + * _advance_frame with rect as data. + * + * So far we setup the first and second animations, the third one however is a + * bit different, this time we won't use a timeline animation, that's because we + * don't want our animation to stop: + * @until animator_add + * + * Next we set a few timers to execute _start_second_anim, _freeze_third_anim + * and _thaw_thir_anim in 10, 5 and 10 seconds respectively: + * @until thaw + * + * And now we tell ecore to begin the main loop and free some resources once + * it leaves the main loop: + * @until } + * + * Here we have the callback function for our first animation, which first + * takes @p pos(where in the timeline we are), maps it to a SPRING curve that + * which will wobble 15 times and will decay by a factor of 1.2: + * @until pos_map + * + * Now that we have the frame we can adjust the rectangle to its appropriate + * state: + * @until } + * + * And now the callback that will run 10 seconds after the program starts(5 + * seconds after the first animation finishes) and starts our second + * animation: + * @until } + * @note For this animation we made the frametime much larger which means our + * animation might get "jerky". + * + * The callback for our second animation, our savvy reader no doubt noted that + * it's very similar to the callback for the first animation. What we change for + * this one is the type of animation to BOUNCE and the number of times it will + * bounce to 50: + * @until } + * + * And for our last animation callback something simpler, we just move our + * rectangle right by one pixel until it reaches the end of the screen and then + * start at the beginning again: + * @until } + * + * Our next two functions respectively freezes and thaw our third animation, so + * that it won't happen for the 5 seconds after the first animation ends and the + * second animation begins: + * @until } + * @until } + * + * @example ecore_animator_example.c + */ + +/** + * @page ecore_thread_example_c Ecore_Thread - API overview + * + * Working with threads is hard. Ecore helps to do so a bit easier, but as + * the example in @ref ecore_thread_example.c "ecore_thread_example.c" shows, + * there's a lot to consider even when doing the most simple things. + * + * We'll be going through this thorough example now, showing how the differents + * aspects of @ref Ecore_Thread are used, but users are encourage to avoid + * threads unless it's really the only option, as they always add more + * complexity than the program usually requires. + * + * Ecore Threads come in two flavors, short jobs and feedback jobs. Short jobs + * just run the given function and are more commonly used for small tasks + * where the main loop does not need to know how the work is going in between. + * The short job in our example is so short we had to artificially enlarge it + * with @c sleep(). Other than that, it also uses threads local data to keep + * the data we are working with persistent across different jobs ran by the + * same system thread. This data will be freed when the no more jobs are + * pending and the thread is terminated. If the data doesn't exist in the + * thread's storage, we create it and save it there for future jobs to find + * it. If creation fails, we cancel ourselves, so the main loop knows that + * we didn't just exit normally, meaning the job could not be done. The main + * part of the function checks in each iteration if it was canceled by the + * main loop, and if it was, it stops processing and clears the data from the + * storage (we assume @c cancel means no one else will need this, but this is + * really application dependent). + * @dontinclude ecore_thread_example.c + * @skip static void + * @until sleep(1) + * @until } + * @until } + * + * Feedback jobs, on the other hand, run tasks that will inform back to the + * main loop its progress, send partial data as is processed, just ping saying + * it's still alive and processing, or anything that needs the thread to talk + * back to the main loop. + * @skip static void + * @until the_end + * @until } + * + * Finally, one more feedback job, but this one will be running outside of + * Ecore's pool, so we can use the pool for real work and keep this very + * light function unchecked. All it does is check if some condition is met + * and send a message to the main loop telling it it's time to close. + * @skip static void + * @until } + * @until } + * @until } + * + * Every now and then the program prints its status, counting threads running + * and pending jobs. + * @skip static void + * @until } + * + * In our main loop, we'll be receiving messages from our feedback jobs using + * the same callback for both of them. + * @skip static void + * @until char *str + * + * The light job running out of the pool will let us know when we can exit our + * program. + * @until } + * + * Next comes the handling of data sent from the actual worker threads, always + * remembering that the data belongs to us now, and not the thread, so it's + * our responsibility to free it. + * @until } + * @until } + * + * Last, the condition to exit is given by how many messages we want to handle, + * so we need to count them and inform the condition checking thread that the + * value changed. + * @until } + * + * When a thread finishes its job or gets canceled, the main loop is notified + * through the callbacks set when creating the task. In this case, we just + * print what happen and keep track of one of them used to exemplify canceling. + * Here we are pretending one of our short jobs has a timeout, so if it doesn't + * finish before a timer is triggered, it will be canceled. + * @skip static void + * @until _cancel_timer_cb + * @until } + * + * The main function does some setup that includes reading parameters from + * the command line to change its behaviour and test different results. + * These are: + * @li -t \ maximum number of threads to run at the same time. + * @li -p \ adds @c some_path to the list used by the feedback jobs. + * This parameter can be used multiple times. + * @li -m \ the number of messages to process before the program is + * signalled to exit. + * + * Skipping some bits, we init Ecore and our application data. + * @skip ecore_init + * @until appdata.max_msgs + * + * If any paths for the feedback jobs were given, we use them, otherwise we + * fallback to some defaults. Always initializing the proper mutexes used by the + * threaded job. + * @skip path_list + * @until EINA_LIST_FREE + * @until } + * @until } + * + * Initialize the mutex needed for the condition checking thread + * @skip appdata.mutex + * @until appdata.condition + * + * And start our tasks. + * @until appdata.thread_3 + * @until EINA_FALSE + * + * To finalize, set a timer to cancel one of the tasks if it doesn't end + * before the timeout, one more timer for status report and get into the main + * loop. Once we are out, destroy our mutexes and finish the program. + * @until _status_timer_cb + * @until } + * + * @example ecore_thread_example.c + */ + +/** + * @page ecore_evas_callbacks_example_c Ecore Evas Callbacks + * @dontinclude ecore_evas_callbacks.c + * + * Our example is remarkably simple, all it does is create an Ecore_Evas and + * register a callback for a bunch of events. What's interesting here is + * knowing when each of these callbacks will be called, however since that + * depends on the underlying windowing system there are no guarantees that all + * of the callbacks will be called for your windowing system. To know which + * callbacks will be called for your windowing system run the example and + * redirect the output to a file, and take a look at it. + * + * @note Make sure you minimize, resize, give and remove focus to see more + * callbacks called. + * + * The example is constituted of two main parts, first is the implementation of + * callbacks that will be called for each event(all our callbacks do is print + * their own name) and the second is the main function where we register the + * event callbacks and run the main loop: + * @include ecore_evas_callbacks.c + * @example ecore_evas_callbacks.c + */ + +/** + * @page Ecore_Evas_Window_Sizes_Example_c Ecore_Evas window size hints + * + * On this example, we show you how to deal with @c Ecore_Evas window + * size hints, which are implemented per Evas engine. + * + * We start by defining an initial size for our window and, after + * creating it, adding a background white rectangle and a text object + * to it, to be used to display the current window's sizes, at any + * given time: + * @dontinclude ecore_evas_window_sizes_example.c + * @skip define WIDTH + * @until define + * @until define + * @dontinclude ecore_evas_window_sizes_example.c + * @skip evas_init + * @until show(bg) + * @dontinclude ecore_evas_window_sizes_example.c + * @skip text = + * @until main_loop_begin + * @dontinclude ecore_evas_window_sizes_example.c + * @skip to inform + * @until } + * + * The program has a command line interface, responding to the + * following keys: + * @dontinclude ecore_evas_window_sizes_example.c + * @skip commands + * @until ; + * + * Use the @c 'm' key to impose a minimum size of half the initial + * ones on our window. Test it by trying to resize it to smaller sizes + * than that: + * @dontinclude ecore_evas_window_sizes_example.c + * @skip keyname, "m" + * @until } + * @until } + * @until } + * + * The @c 'x' key will, in turn, set a maximum size on our window -- + * to two times our initial size. Test it by trying to resize the + * window to bigger sizes than that: + * @dontinclude ecore_evas_window_sizes_example.c + * @skip keyname, "x" + * @until } + * @until } + * @until } + * + * Window base sizes will override any minimum sizes set, so try it + * with the @c 'b' key. It will set a base size of two times the + * initial one: + * @dontinclude ecore_evas_window_sizes_example.c + * @skip keyname, "b" + * @until } + * @until } + * @until } + * + * Finally, there's a key to impose a "step size" on our window, of 40 + * pixels. With than on (@c 's' key), you'll see the window will + * always be bound to @b multiples of that size, for dimensions on + * both axis: + * @skip keyname, "s" + * @until } + * @until } + * @until } + * + * The full example follows. + * + * @include ecore_evas_window_sizes_example.c + * @example ecore_evas_window_sizes_example.c + */ + +/** + * @page ecore_evas_object_example_c Ecore Evas Object example + * @dontinclude ecore_evas_object_example.c + * + * This example creates an Ecore_Evas(a window) and associates a background and + * a custom cursor for it. + * + * We'll start looking at the association, which is quite simple. We choose to + * associate using ECORE_EVAS_OBJECT_ASSOCIATE_BASE to have it be resized with + * the window, since for a background that is what's most useful: + * @skipline ecore_evas_object_associate + * @note If we didn't associate the background we'd need to listen to resize of + * Ecore_Evas and manually resize the background or have artifacts on our + * window. + * + * We then check that the association worked: + * @until printf + * + * Next we are going to set a custom cursor, for our cursor we are going to use + * a small green rectangle. Our cursor is going to be on layer 0(any lower and + * it would be below the background and thus invisible) and clicks will be + * computed as happening on pixel 1, 1 of the image: + * @until cursor_set + * + * We then check every one of those parameters: + * @until printf + * + * Here you have the full-source of the code: + * @include ecore_evas_object_example.c + * @example ecore_evas_object_example.c + */ + +/** + * @page ecore_evas_basics_example_c Ecore Evas basics example + * @dontinclude ecore_evas_basics_example.c + * + * This example will illustrates the usage of some basic Ecore_Evas functions. + * This example will list the available evas engines, check which one we used to + * create our window and set some data on our Ecore_Evas. It also allows you to + * hide/show all windows in this process(we only have one, but if there were + * more they would be hidden), to hide the windows type 'h' and hit return, to + * show them, type 's' and hit return. + * + * The very first thing we'll do is initialize ecore_evas: + * @skipline evas_init + * @until return 1 + * + * Once inited we query which engines are available: + * @until ecore_evas_engines_free + * + * We then create an Ecore_Evas(window) with the first available engine, on + * position 0,0 with size 200,200 and no especial flags, set it's title and show + * it: + * @until evas_show + * + * We now add some important data to our Ecore_Evas: + * @until data_set + * + * And since our data is dynamically allocated we'll need to free it when the + * Ecore_Evas dies: + * @until delete_request + * @dontinclude ecore_evas_basics_example.c + * @skip static void + * @until } + * @skip printf("Using + * + * We now print which Evas engine is being used for our example: + * @until printf + * + * We are going to add a background to our window but before we can do that + * we'll need to get the canvas(Evas) on which to draw it: + * @until canvas + * + * We then do a sanity check, verifying if the Ecore_Evas of the Evas is the + * Ecore_Evas from which we got the Evas: + * @until printf + * + * Now we can actually add the background: + * @until ecore_evas_object_associate + * + * To hide and show the windows of this process when the user presses 'h' and + * 's' respectively we need to know when the user types something, so we + * register a callback for when we can read something from @c stdin: + * @until ) + * + * The callback that actually does the hiding and showing is pretty simple, it + * does a @c scanf(which we know won't block since there is something to read on + * @c stdin) and if the character is an 'h' we iterate over all windows calling + * @c ecore_evas_hide on them, if the character is an 's' we call @c + * ecore_evas_show instead: + * @dontinclude ecore_evas_basics_example.c + * @skip static Eina_Bool + * @until } + * @skip ecore_main_loop_begin + * + * Once all is done we run our main loop, and when that is done(application is + * exiting) we free our Ecore_Evas and shutdown the ecore_evas subsystem: + * @until shutdown + * + * Here you have the full-source of the code: + * @include ecore_evas_basics_example.c + * @example ecore_evas_basics_example.c + */ + +/** + * @page Ecore_Evas_Buffer_Example_01_c Ecore_Evas buffer example + * + * Between the Evas examples, there is one in which one creates a + * canvas bound to the Evas @b buffer engine and uses its pixel + * contents to create an PPM image on disk. There, one does that by + * creating the canvas "by hand", with @c evas_new(), @c + * evas_engine_info_set(), etc. + * + * On this example, we accomplish the very same task, but by using the + * @c Ecore_Evas helper wrapper functions on a buffer engine + * canvas. If you compare both codes, you'll see how much code one is + * saved from by using the @c Ecore_Evas wrapper functions. + * + * The code is simple as it can be. After instantianting our canvas + * window, with ecore_evas_buffer_new(), we grab its canvas pointer + * and create the desired objects scene on it, which in this case is + * formed by 3 rectangles over the top left corner of a white + * background: + * @dontinclude ecore_evas_buffer_example_01.c + * @skip main(void) + * @until show(r3) + * + * Since it's a buffer canvas and we're using it to only save its + * contents on a file, we even needn't ecore_evas_show() it. We make + * it render itself, forcefully, without the aid of Ecore's main loop, + * with ecore_evas_manual_render(): + * @dontinclude ecore_evas_buffer_example_01.c + * @skip manual_render + * @until manual_render + * + * And we're ready to save the window's shiny rendered contents as a + * simple PPM image. We do so by grabbing the pixels of the @c + * Ecore_Evas' internal canvas, with ecore_evas_buffer_pixels_get(): + * @dontinclude ecore_evas_buffer_example_01.c + * @skip _scene_save + * @until } + * @dontinclude ecore_evas_buffer_example_01.c + * @skip support function + * @until } + * @until } + * @until } + * + * Check that destination file for the result. The full example + * follows. + * + * @include ecore_evas_buffer_example_01.c + * @example ecore_evas_buffer_example_01.c + */ + +/** + * @page Ecore_Evas_Buffer_Example_02_c Ecore_Evas (image) buffer example + * + * In this example, we'll demonstrate the use of + * ecore_evas_object_image_new(). The idea is to have the same scene + * created for @ref Ecore_Evas_Buffer_Example_01_c as the contents of + * an image object. + * + * The canvas receiving this image object will have a white + * background, a red border image to delimit this image's boundaries + * and the image itself. After we create the special image, we set + * its "fill" property, place and resize it as we want. We have also + * to resize its underlying @c Ecore_Evas too, to the same dimensions: + * @dontinclude ecore_evas_buffer_example_02.c + * @skip object_image_new + * @until resize(sub_ee + * + * Now, we re-create the scene we cited, using the sub-canvas of our + * image to parent the objects in question. Because image objects are + * created with the alpha channel enabled, by default, we'll be seeing + * our white rectangle beneath the scene: + * @dontinclude ecore_evas_buffer_example_02.c + * @skip rectangle_add(sub_canvas + * @until loop_begin + * + * And that's all. The contents of our image could be updated as one + * wished, and they would always be mirrored in the image's area. + * + * Check that destination file for the result. The full example + * follows. + * + * @include ecore_evas_buffer_example_02.c + * @example ecore_evas_buffer_example_02.c + */ + +/** + * @page Ecore_exe_simple_example_c Ecore_exe + * Creating a processes and IPC (Inter process communication) + * + * In this example we will show how to create a new process and communicate + * with it in a portable way using the Ecore_exe module. + * + * In this example we will have two process and both will communicate with each + * other using messages. A father process will start a child process and it will + * keep sending messages to the child until it receives a message to quit. + * To see the full source use the links: + * @li @ref ecore_exe_example.c "Father" + * @li @ref ecore_exe_example_child.c "Child" + * + * Let's start the tutorial. The implementation of the child it's pretty simple. + * We just read strings from stdin and write a message in the stdout. But you + * should be asking yourself right know. "If I'm receiving data from an other + * process why I'm reading and writing in stdin/stdout?". That's because, when + * you spawn a process using the Ecore_Exe module it will create a pipe between + * the father and the child process and the stdin/stdout of the child process + * will be redirected to the pipe. So when the child wants to receive or send + * data to the father, just use the stdin/stdout. + * However the steps to send data from the father to the child is quite + * different, but we will get there. + * + * The child will register a fd handler to monitor the stdin. + * So we start registering the ecore FD handler: + * @dontinclude ecore_exe_example_child.c + * @skip ecore_main_fd_handler_add + * @until ; + * + * If you don't remenber the parameters of @ref ecore_main_fd_handler_add, + * please check its documentation. + * + * Now that we have our handler registered we will start the ecore's main loop: + * @skipline ecore_main_loop_begin + * + * Now let's take a look in the callback function. Its a simple function + * that will read from stdin 3 times and at the third time will say + * to the father: "quit". + * @dontinclude ecore_exe_example_child.c + * @skip static Eina_Bool + * @until } + * @until } + * @until } + * @until } + * + * You may notice that we are sending the messages to stdout, and our father + * will receive it. Also our string must have a "\n" because the string will + * be buffered in the pipe until it finds EOF or a "newline" in our case we + * won't have a EOF unless we close the pipe, so we use the "\n" char. + * + * One more thing, we use fflush(stdout) because probably our message won't + * fill our entire buffer and the father would never receive the message. So we + * use this function to flush the buffer and the father can receive as fast as + * possible. + * + * Now that we have our child ready, let's start our work in the father's source + * code. + * + * We start creating the child process like this: + * @dontinclude ecore_exe_example.c + * @skip childHandle = ecore_exe_pipe_run + * @until ; + * + * With the command above we are creating our child process, the first + * parameter is the command to be executed, the second are the pipe flags and + * in our case we will write and read in the pipe so we must say what we are + * doing in the pipe. You may notice the flag ECORE_EXE_PIPE_READ_LINE_BUFFERED, + * this means that reads are buffered until I find a newline. And the third + * parameter is data that we would like to send to the process in its creating. + * This case we are sending nothing, so just use NULL. + * + * Then we check if the process was created: + * @skip if + * @until } + * + * After this we get the PID of the child process and just print it in the screen. + * The PID stands for Process identification. This is just an internal + * identifier of your process: + * + * @skip childPid + * @until fprintf + * @until fprintf + * + * The way that Ecore_exe works is: when we want to read data sent from + * our child we must use an ecore event. + * So let's start register our event listener: + * @skipline ecore_event_handler_add + * + * Now to send messages to our child we will use a timer, so every 1 second we + * will send a message to the child. + * @skipline ecore_timer_add + * + * After all this we start the main loop. Now let's pass to the callback + * functions. + * + * Now we will see how we actually send the data and receive it. + * Let's start with _sendMessage: + * @dontinclude ecore_exe_example.c + * @skip _sendMessage(void *data) + * @until } + * + * We use ecore_exe_send to send data to the child process, it's pretty simple. + * To know what the parameters stands for, check the docs. + * + * @note The function @b ecore_exe_send will never block your program, also + * there is no partial send of the data. This means either the function will + * send all the data or it will fail. + * + * Now let's take a look in our event callback and see how we retrieve the + * messages. + * @dontinclude ecore_exe_example.c + * @skip static Eina_Bool + * @until } + * @until } + * + * It's just like an normal event, we get a reference to Ecore_Exe_Event_Data, + * extract the data and then show it in the screen. + * + * And that's it, after all it's not complicated to create a process and + * communicate with it. + * + */ + +/** + * @page ecore_imf_example_c ecore_imf - How to handle preedit and commit string from Input Method Framework + * + * This example demonstrates how to connect input method framework and handle preedit and commit string from input method framework. + * + * To input Chinese, Japanese, Korean and other complex languages, the editor should be connected with input method framework. + * + * How to initialize and shutdown ecore imf module + * @li ecore_imf_init() should be called to initialize and load immodule. + * @li ecore_imf_shutdown() is used for shutdowning and unloading immodule. + * + * How to create input context and register pre-edit and commit event handler + * + * Each entry should have each input context to connect with input service framework. + * Key event is processed by input method engine. + * The result is notified to application through ECORE_IMF_CALLBACK_PREEDIT_CHANGED and ECORE_IMF_CALLBACK_COMMIT event. + * + * The full example follows. + * + * @include ecore_imf_example.c + */ diff --git a/doc/eet_examples.dox b/doc/eet_examples.dox new file mode 100644 index 0000000000..b842584466 --- /dev/null +++ b/doc/eet_examples.dox @@ -0,0 +1,184 @@ +/** + * @page Examples Examples + * + * Here is a page with examples. + * + * @ref Example_Eet_Data_Simple + * + * @ref Example_Eet_Data_Nested + * + * @ref Example_Eet_Data_File_Descriptor_01 + * + * @ref Example_Eet_Data_File_Descriptor_02 + * + * @ref Example_Eet_Data_Cipher_Decipher + * + * List of examples + */ + +/** + * @page Example_Eet_Basic Very basic Eet example + * + * @includelineno eet-basic.c + * @example eet-basic.c + */ + +/** + * @page Example_Eet_File Example of the various ways to interface with an Eet File + * + * @includelineno eet-file.c + * @example eet-file.c + */ + +/** + * @page Example_Eet_Data_Simple Simple data example + * + * @includelineno eet-data-simple.c + * @example eet-data-simple.c + */ + +/** + * @page Example_Eet_Data_Nested Nested data example + * + * @includelineno eet-data-nested.c + * @example eet-data-nested.c + */ + +/** + * @page Example_Eet_Data_File_Descriptor_01 File descriptor data example + * + * @includelineno eet-data-file_descriptor_01.c + * @example eet-data-file_descriptor_01.c + */ + +/** + * @page Example_Eet_Data_File_Descriptor_02 File descriptor data example, with Eet unions and variants + * + * This is an example much like the one shown in @ref + * eet_data_file_descriptor. The difference is that here we're + * attaining ourselves to two new data types to store in an Eet file + * -- @b unions and @b variants. We don't try to come with data + * mapping to real world use cases, here. Instead, we're defining + * 3 different simple structures to be used throughout the example: + * @dontinclude eet-data-file_descriptor_02.c + * @skip typedef struct _Example_Struct1 + * @until typedef struct _Example_Struct3 + * @skip struct _Example_Struct1 + * @until int body + * @until }; + * + * To identify, for both union and variant data cases, the type of + * each chunk of data, we're defining types to point to each of those + * structs: + * @dontinclude eet-data-file_descriptor_02.c + * @skip typedef enum _Example_Data_Type + * @until ; + * @skip enum _Example_Data_Type + * @until }; + * + * We have also a mapping from those types to name strings, to be used + * in the Eet unions and variants @c type_get() and @c type_set() type + * identifying callbacks: + * @skip struct + * @until }; + * + * In this example, we have no fancy hash to store our data into + * profiles/accounts, but just two lists for union and variant data + * nodes: + * @dontinclude eet-data-file_descriptor_02.c + * @skip typedef struct _Example_Lists + * @until typedef struct _Example_Lists + * @skip struct _Example_Lists + * @until }; + * + * Let's begin with our unions, then, which look like: + * @dontinclude eet-data-file_descriptor_02.c + * @skip typedef struct _Example_Union + * @until typedef struct _Example_Union + * @skip struct _Example_Union + * @until }; + * + * The first interesting part of the code is where we define our data + * descriptors for the main lists, the unions and all of structures + * upon which those two depend. + * @dontinclude eet-data-file_descriptor_02.c + * @skip declaring types + * @until _union_descriptor); + * The code for descriptors on @c Example_Struct1, @c Example_Struct2 + * and @c Example_Struct3 is straightforward, a matter already covered + * on @ref eet_data_file_descriptor. What is new, here, are the two + * type matching functions for our unions. There, we must set the @c + * data pointer to its matching type, on @c _union_type_set and return + * the correct matching type, on @c _union_type_get: + * @dontinclude eet-data-file_descriptor_02.c + * @skip union type_get() + * @until _union_type_set + * @until _union_type_set + * + * With the #EET_DATA_DESCRIPTOR_ADD_MAPPING calls, which follow, we + * make the the link between our type names and their respective + * structs. The code handling actual data is pretty much the same as in + * @ref eet_data_file_descriptor -- one uses command line arguments to + * enter new data chunks (or just to visualize the contents of an Eet + * file), signalling if they are unions or variants. One must also + * pass the type of the data chuck to enter, with integers 1, 2 or + * 3. Then, come the fields for each type: + * @dontinclude eet-data-file_descriptor_02.c + * @skip Usage + * @until argv + * + * Variants are very similar to unions, except that data chunks need + * @b not contain previously allocated space for each of the possible + * types of data going in them: + * @dontinclude eet-data-file_descriptor_02.c + * @skip typedef struct _Example_Variant + * @until typedef struct _Example_Variant + * @skip struct _Example_Variant_Type + * @until }; + * @until }; + * + * The code declaring the data descriptors and handling the data is + * very similar to the unions part, and is left for the reader to + * check for him/herself. The complete code of the example follows. + * + * @includelineno eet-data-file_descriptor_02.c + * @example eet-data-file_descriptor_02.c + */ + +/** + * @page Example_Eet_Data_Cipher_Decipher Eet data cipher/decipher example + * + * In this example, we exemplify the usage of eet_write_cipher() and + * eet_read_cipher(). For it to work, make sure to have your + * Eet installation with a ciphering backend enabled. + * + * We start by defining the information to record in an Eet file (@c + * buffer), the key to cipher that (@c key) and a dummy wrong key to + * try to access that information, later (@c key_bad). + * @dontinclude eet-data-cipher_decipher.c + * @skip buffer = + * @until bad = + * + * After opening our file, we simply use the first cited function to + * write our string ciphered: + * @dontinclude eet-data-cipher_decipher.c + * @skip eet_open + * @until eet_close + * + * Then, after closing it on purpose, we open it again, to retrieve + * the encrypted information back, in a readable format: + * @skip eet_open + * @until eet_close + * @until eet_close + * + * Note that we do it twice, being the last time with the wrong + * key. In this last case, if the information is read back and matches + * the original @c buffer, something wrong is going on (we made it to + * fail on purpose). The former access is OK, and must work. + * + * What we do in sequence is just to delete the file. The complete + * code of the example follows. + * + * @includelineno eet-data-cipher_decipher.c + * @example eet-data-cipher_decipher.c + */ diff --git a/doc/eio.dox.in b/doc/eio.dox.in new file mode 100644 index 0000000000..de25ae6730 --- /dev/null +++ b/doc/eio.dox.in @@ -0,0 +1,456 @@ +/* EIO - EFL data type library + * Copyright (C) 2010 Enlightenment Developers: + * Cedric Bail + * Vincent "caro" Torri + * Stephen "okra" Houston + * Gustavo Sverzut Barbieri + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ + +/** + * @page eio_main Eio + * @author Cedric Bail + * @author Stephen "okra" Houston + * @author Gustavo Sverzut Barbieri + * @author Vincent "caro" Torri + * @author Guillaume "kuri" Friloux + * @date 2010-2012 + * + * @section eio_intro_sec Introduction + * @version @PACKAGE_VERSION@ + * + * The Eio library is a library that implements an API for asynchronous + * input/output operation. Most operation are done in a separated thread + * to prevent lock. See @ref Eio_Group. Some helper to work on data + * received in Eio callback are also provided see @ref Eio_Helper. + * It is also possible to work asynchronously on Eina_File with @ref Eio_Map + * or on Eet_File with @ref Eio_Eet. It come with way to manipulate + * eXtended attribute assynchronously with @ref Eio_Xattr. + * + * This library is cross-platform and can be compiled and used on + * Linux, BSD, Opensolaris and Windows (XP and CE). + */ + +/** + * @page tutorial_dir_copy eio_dir_copy() tutorial + * + * To use eio_dir_copy(), you basically need the source and + * destination files (or directories), and set three callbacks: + * + * @li The notification callback, which allows you to know if a file or + * a directory is copied, and the progress of the copy. + * @li The end callback, which is called when the copy is finished. + * @li The error callback, which is called if an error occured. You + * can then retrieve the error type as an errno error. + * + * @warning It is the user's duty to provide the "right target". It + * means that copying to '.' will copy the content directly inside '.' + * and not in a subdirectory. + * + * Here is a simple example: + * + * @code + * #include + * #include + * + * static void + * _test_notify_cb(void *data, Eio_File *handler, const Eio_Progress *info) + * { + * switch (info->op) + * { + * case EIO_FILE_COPY: + * printf("[%s] %f%%\n", info->dest, info->percent); + * break; + * case EIO_DIR_COPY: + * printf("global [%li/%li] %f%%\n", info->current, info->max, info->percent); + * break; + * } + * } + * + * static void + * _test_done_cb(void *data, Eio_File *handler) + * { + * printf("copy done\n"); + * ecore_main_loop_quit(); + * } + * + * static void + * _test_error_cb(int error, Eio_File *handler, void *data) + * { + * fprintf(stderr, "error: [%s]\n", strerror(error)); + * ecore_main_loop_quit(); + * } + * + * int + * main(int argc, char **argv) + * { + * Eio_File *cp; + * + * if (argc != 3) + * { + * fprintf(stderr, "eio_cp source_file destination_file\n"); + * return -1; + * } + * + * ecore_init(); + * eio_init(); + * + * cp = eio_dir_copy(argv[1], argv[2], + * _test_notify_cb, + * _test_done_cb, + * _test_error_cb, + * NULL); + * + * ecore_main_loop_begin(); + * + * eio_shutdown(); + * ecore_shutdown(); + * + * return 0; + * } + * @endcode + */ + +/** + * @page tutorial_dir_stat_ls eio_dir_stat_ls() tutorial + * + * @li The filter callback, which allow or not a file to be seen + * by the main loop handler. This callback run in a separated thread. + * @li The main callback, which receive in the main loop all the file + * that are allowed by the filter. If you are updating a user interface + * it make sense to delay the insertion a little, so you get a chance + * to update the canvas for a bunch of file instead of one by one. + * @li The end callback, which is called in the main loop when the + * content of the directory has been correctly scanned and all the + * file notified to the main loop. + * @li The error callback, which is called if an error occured or + * if the listing was cancelled during it's run. You can then retrieve + * the error type as an errno error. + * + * Here is a simple example that implement a stupidly simple replacement for find: + * + * @code + * #include + * #include + * + * static Eina_Bool + * _test_filter_cb(void *data, Eio_File *handler, const Eina_File_Direct_Info *info) + * { + * fprintf(stderr, "ACCEPTING: %s\n", info->path); + * return EINA_TRUE; + * } + * + * static void + * _test_main_cb(void *data, Eio_File *handler, const Eina_File_Direct_Info *info) + * { + * fprintf(stderr, "PROCESS: %s\n", info->path); + * } + * + * static void + * _test_done_cb(void *data, Eio_File *handler) + * { + * printf("ls done\n"); + * ecore_main_loop_quit(); + * } + * + * static void + * _test_error_cb(void *data, Eio_File *handler, int error) + * { + * fprintf(stderr, "error: [%s]\n", strerror(error)); + * ecore_main_loop_quit(); + * } + * + * int + * main(int argc, char **argv) + * { + * Eio_File *cp; + * + * if (argc != 2) + * { + * fprintf(stderr, "eio_ls directory\n"); + * return -1; + * } + * + * ecore_init(); + * eio_init(); + * + * cp = eio_dir_stat_ls(argv[1], + * _test_filter_cb, + * _test_main_cb, + * _test_done_cb, + * _test_error_cb, + * NULL); + * + * ecore_main_loop_begin(); + * + * eio_shutdown(); + * ecore_shutdown(); + * + * return 0; + * } + * + * @endcode + */ + +/** + * @page tutorial_file_ls eio_file_ls() tutorial + * + * To use eio_file_ls(), you just need to define four callbacks: + * + * @li The filter callback, which allow or not a file to be seen + * by the main loop handler. This callback run in a separated thread. + * @li The main callback, which receive in the main loop all the file + * that are allowed by the filter. If you are updating a user interface + * it make sense to delay the insertion a little, so you get a chance + * to update the canvas for a bunch of file instead of one by one. + * @li The end callback, which is called in the main loop when the + * content of the directory has been correctly scanned and all the + * file notified to the main loop. + * @li The error callback, which is called if an error occured or + * if the listing was cancelled during it's run. You can then retrieve + * the error type as an errno error. + * + * Here is a simple example: + * + * @code + * #include + * #include + * + * static Eina_Bool + * _test_filter_cb(void *data, Eio_File *handler, const char *file) + * { + * fprintf(stderr, "ACCEPTING: %s\n", file); + * return EINA_TRUE; + * } + * + * static void + * _test_main_cb(void *data, Eio_File *handler, const char *file) + * { + * fprintf(stderr, "PROCESS: %s\n", file); + * } + * + * static void + * _test_done_cb(void *data, Eio_File *handler) + * { + * printf("ls done\n"); + * ecore_main_loop_quit(); + * } + * + * static void + * _test_error_cb(void *data, Eio_File *handler, int error) + * { + * fprintf(stderr, "error: [%s]\n", strerror(error)); + * ecore_main_loop_quit(); + * } + * + * int + * main(int argc, char **argv) + * { + * Eio_File *cp; + * + * if (argc != 2) + * { + * fprintf(stderr, "eio_ls directory\n"); + * return -1; + * } + * + * ecore_init(); + * eio_init(); + * + * cp = eio_file_ls(argv[1], + * _test_filter_cb, + * _test_main_cb, + * _test_done_cb, + * _test_error_cb, + * NULL); + * + * ecore_main_loop_begin(); + * + * eio_shutdown(); + * ecore_shutdown(); + * + * return 0; + * } + * + * @endcode + */ + +/** + * @page tutorial_monitor_add eio_monitor_add() tutorial + * + * To use eio_monitor_add(), you have to define callbacks + * for events declared by eio. + * Available events are : + * - EIO_MONITOR_FILE_CREATED + * - EIO_MONITOR_FILE_DELETED + * - EIO_MONITOR_FILE_MODIFIED + * - EIO_MONITOR_FILE_CLOSED + * - EIO_MONITOR_DIRECTORY_CREATED + * - EIO_MONITOR_DIRECTORY_DELETED + * - EIO_MONITOR_DIRECTORY_CLOSED + * - EIO_MONITOR_SELF_RENAME + * - EIO_MONITOR_SELF_DELETED + * + * As nothing is worth an example, here it is : + * @code + * #include + * #include + * #include + * + * void file_modified(void *data, int type, void *event) + * { + * const char *filename = (const char *)data; + * printf("file %s ", filename); + * if( type == EIO_MONITOR_FILE_MODIFIED ) + * printf("is being modified"); + * else if( type == EIO_MONITOR_FILE_CLOSED ) + * printf("is not more being modified"); + * else printf("got unexpected changes"); + * printf("\n"); + * } + * + * int main(int argc, char **argv) { + * Eio_Monitor *monitor = NULL, + * *monitor2 = NULL; + * eio_init(); + * const char *filename = eina_stringshare_add("/tmp/eio_notify_testfile"); + * + * monitor = eio_monitor_add(filename); + * ecore_event_handler_add(EIO_MONITOR_FILE_MODIFIED, (Ecore_Event_Handler_Cb)file_modified, filename); + * ecore_event_handler_add(EIO_MONITOR_FILE_CLOSED, (Ecore_Event_Handler_Cb)file_modified, filename); + * + * ecore_main_loop_begin(); + * eio_shutdown(); + * eina_stringshare_del(filename); + * } + * @endcode + * Build the example doing : + * @verbatim gcc -o tutorial_monitor_add tutorial_monitor_add.c `pkg-config --libs --cflags eio ecore ecore-file eina` + * then create the file /tmp/eio_notify_testfile : + * touch /tmp/eio_notify_testfile + * and launch tutorial_monitor_add, and in another terminal, write into /tmp/eio_notify_testfile, doing for example : + * echo "test" >> /tmp/eio_notify_testfile + * @endverbatim + */ + +/** + * @page tutorial_dir_direct_ls eio_dir_direct_ls() tutorial + * + * @li The filter callback, which allow or not a file to be seen + * by the main loop handler. This callback run in a separated thread. + * It also take care of getting a stat buffer needed by the main callback + * to display the file size. + * @li The main callback, which receive in the main loop all the file + * that are allowed by the filter. If you are updating a user interface + * it make sense to delay the insertion a little, so you get a chance + * to update the canvas for a bunch of file instead of one by one. + * @li The end callback, which is called in the main loop when the + * content of the directory has been correctly scanned and all the + * file notified to the main loop. + * @li The error callback, which is called if an error occured or + * if the listing was cancelled during it's run. You can then retrieve + * the error type as an errno error. + * + * Here is a simple example that implement a stupidly simple recursive ls that display file size: + * + * @code + * #include + * #include + * #include + * + * static Eina_Bool + * _test_filter_cb(void *data, Eio_File *handler, Eina_File_Direct_Info *info) + * { + * Eina_Stat *buffer; + * Eina_Bool isdir; + * + * isdir = info->type == EINA_FILE_DIR; + * + * buffer = malloc(sizeof (Eina_Stat)); + * if (eina_file_statat(eio_file_container_get(handler), info, buffer)) + * { + * free(buffer); + * return EINA_FALSE; + * } + * + * if (!isdir && info->type == EINA_FILE_DIR) + * { + * struct stat st; + * if (lstat(info->path, &st) == 0) + * { + * if (S_ISLNK(st.st_mode)) + * info->type = EINA_FILE_LNK; + * } + * } + * + * eio_file_associate_direct_add(handler, "stat", buffer, free); + * fprintf(stdout, "ACCEPTING: %s\n", info->path); + * return EINA_TRUE; + * } + * + * static void + * _test_main_cb(void *data, Eio_File *handler, const Eina_File_Direct_Info *info) + * { + * struct stat *buffer; + * + * buffer = eio_file_associate_find(handler, "stat"); + * fprintf(stdout, "PROCESS: %s of size %li\n", info->path, buffer->st_size); + * } + * + * static void + * _test_done_cb(void *data, Eio_File *handler) + * { + * printf("ls done\n"); + * ecore_main_loop_quit(); + * } + * + * static void + * _test_error_cb(void *data, Eio_File *handler, int error) + * { + * fprintf(stdout, "error: [%s]\n", strerror(error)); + * ecore_main_loop_quit(); + * } + * + * int + * main(int argc, char **argv) + * { + * Eio_File *cp; + * + * if (argc != 2) + * { + * fprintf(stdout, "eio_ls directory\n"); + * return -1; + * } + * + * ecore_init(); + * eio_init(); + * + * cp = eio_dir_direct_ls(argv[1], + * _test_filter_cb, + * _test_main_cb, + * _test_done_cb, + * _test_error_cb, + * NULL); + * + * ecore_main_loop_begin(); + * + * eio_shutdown(); + * ecore_shutdown(); + * + * return 0; + * } + * @endcode + */ diff --git a/doc/evas_examples.dox b/doc/evas_examples.dox new file mode 100644 index 0000000000..65dd513409 --- /dev/null +++ b/doc/evas_examples.dox @@ -0,0 +1,1073 @@ +/** + * @page Examples Examples + * + * Here is a page with examples. + * + * @ref Example_Evas_Buffer_Simple + * + * @ref Example_Evas_Init_Shutdown + * + * @ref Example_Evas_Text + * + * @ref Example_Evas_Images + * + * @ref Example_Evas_Images_2 + * + * @ref Example_Evas_Events + * + * @ref Example_Evas_Object_Manipulation + * + * @ref Example_Evas_Aspect_Hints + * + * @ref Example_Evas_Size_Hints + * + * @ref Example_Evas_Stacking + * + * @ref Example_Evas_Smart_Objects + * + * @ref Example_Evas_Box Evas box + */ + +/** + * @page Example_Evas_Buffer_Simple Simple Evas canvas example + * + * The canvas will here use the buffer engine. + * + * @include evas-buffer-simple.c + * @example evas-buffer-simple.c + */ + +/** + * @page Example_Evas_Init_Shutdown Evas' init/shutdown routines example + * + * @include evas-init-shutdown.c + * @example evas-init-shutdown.c + */ + +/** + * @page Example_Evas_Images Some image object functions examples + * @dontinclude evas-images.c + * + * In this example, we add two images to a canvas, each one having a + * quarter of the canvas' size, positioned on the top left and bottom + * right corners, respectively: + * @skip img1 = evas_object_image_add(d.evas); + * @until ecore_main_loop_begin + * See there is a border image around the top left one, which is + * the one that should be displayed. The other one will (on + * purpose) fail to load, because we set a wrong file path as image + * source on it: + * @dontinclude evas-images.c + * @skip valid_path + * @until bogus_path + * This is how one is supposed to test for success when binding source + * images to image objects: evas_object_image_load_error_get(), + * followed by evas_load_error_str(), if one wants to pretty print/log + * the error. We'll talk about the border image further. + * + * To interact with the program, there's a command line interface. + * A help string can be asked for with the 'h' key: + * @dontinclude evas-images.c + * @skip commands + * @until ; + * The first four commands will change the top left images's @b fill property + * values, which dictate how the source image (Enlightenment's logo) + * is to be displayed through the image object's area. Experiment with + * those switches until you get the idea of evas_object_fill_set(). + * + * The 'f' command will toggle that image's "filled" property, which + * is whether it should track its size and set the fill one to fit the + * object's boundaries perfectly (stretching). Note that this command + * and the four above it will conflict: in real usage one would use + * one or other ways of setting an image object's viewport with regard + * to its image source. + * + * There are four commands which deal with the border image. This red + * frame is there to illustrate image borders. The image source + * for the border is a solid red rectangle, with a transparent @b + * rectangular area in its middle. See how we use it to get a 3 pixel + * wide frame with evas_object_image_border_set(d.border, 3, 3, + * 3, 3). To finish the effect of showing it as a border, we + * issue evas_object_image_border_center_fill_set(d.border, + * EVAS_BORDER_FILL_NONE). + * + * Use 't' to change the border's thickness. 'b' will change the + * border image's center region rendering schema: either a hole (no + * rendering), blending (see the original transparent area, in this + * case) or solid (the transparent area gets filled). Finally, 'c' + * will change the border's scaling factor. + * + * While you have the border in 'blending mode', test the command 'm': + * it will set whether to use or not smooth scaling on the border's + * source image. Since the image is small originally (30 x 30), we're + * obviously up-scaling it (except the border pixels, do you + * remember?). With this last switch, you'll either see the + * transparent shape in the middle flat (no smoothing) or blurry + * (smoothed). + * + * The full example follows. + * + * @include evas-images.c + * @example evas-images.c + */ + +/** + * @page Example_Evas_Images_2 Some more image object functions examples (2nd block) + * @dontinclude evas-images2.c + * + * In this example, we have three images on the canvas, but one of + * them is special -- we're using it as a proxy image + * object. It will mirror the contents of the other two images + * (which are the ones on the top of the canvas), one at a time: + * @skip d.proxy_img = evas_object_image_filled_add(d.evas); + * @until evas_object_show(d.proxy_img); + * As in other examples, we have a command line interface on it. + * @dontinclude evas-images2.c + * @skip commands + * @until ; + * The 'p' one will change the source of the proxy image to one of the + * other two, as seem above. + * @skip if (strcmp(ev->keyname, "p") == 0) + * @until } + * Note the top right image, the smaller one: + * @dontinclude evas-images2.c + * @skip noise_img = + * @until show + * Since we are creating the data for its pixel buffer ourselves, we + * have to set its size with evas_object_image_size_set(), first. We + * set our data with the function evas_object_image_data_set(), where + * the second argument is a buffer with random data. There's a last + * command to print it's @b stride value. Since its created with one + * quarter of the canvas's original width + * @dontinclude evas-images2.c + * @skip define WIDTH + * @until define HEIGHT + * you can check this value. + * + * The image on the top left also has a subtlety: it is @b pre-loaded + * on this example. + * @dontinclude evas-images2.c + * @skip d.logo = + * @until show + * On real use cases we wouldn't be just printing something like this + * @dontinclude evas-images2.c + * @skip static void + * @until } + * naturally. + * + * The 's' command will save one of the images on the disk, in the png + * format: + * @dontinclude evas-images2.c + * @skip if (strcmp(ev->keyname, "a") == 0) + * @until } + * + * The full example follows. + * + * @include evas-images2.c + * @example evas-images2.c + */ + +/** + * @page Example_Evas_Events Evas events (canvas and object ones) and some canvas operations example + * @dontinclude evas-events.c + * + * In this example we illustrate how to interact with canvas' (and its + * objects') events, including the key input ones. We also demonstrate + * precise point collision on objects and canvas "obscured regions", + * here. + * + * The example application consists of a window with a white + * background and an image -- the Enlightenment logo. The application + * begins with this image switching back and forth into two sizes: the + * exact canvas' size and one quarter of it (when it's placed on the + * top left quadrant). Thus, we'll have an @b animation going on, + * with image states set to change each 2 elapsed seconds. + * + * There's a global variable to aid accessing our desired context + * variables from anywhere in the code: + * @dontinclude evas-events.c + * @skip test_data + * @until {0} + * + * What interests us there are the @c canvas pointer, our image handle + * -- @c img -- and the background one, @c bg. + * + * The first interesting thing on the example is the registration of a + * callback on each canvas resizing event, where we put our canvas' + * size and the background rectangle's one in synchrony, so that we + * don't get bogus content on rendering with canvas resizes: + * @dontinclude evas-events.c + * @skip resize_set + * @until resize_set + * @dontinclude evas-events.c + * @skip here to keep + * @until } + * + * Than, after grabbing our canvas pointer from the Ecore Evas helper + * infrastructure, we registrate an event callbacks on it: + * @skip evas_event_callback_add(d.canvas, EVAS_CALLBACK_RENDER_FLUSH_PRE, + * @until two canvas event callbacks + * @dontinclude evas-events.c + * @skip render flush callback + * @until } + * It will be called whenever our canvas has to flush its rendering + * pipeline. In this example, two ways of observing that message + * which is printed in the cited callback are: + * - to resize the example's window (thus resizing the canvas' viewport) + * - let the animation run + * + * When one resizes the canvas, there's at least one operation it has + * to do which will require new calculation for rendering: the + * resizing of the background rectangle, in a callback we already + * shown you. + * + * The creation of our background rectangle is so that we give it a @b name, + * via evas_object_name_set() and we give it the canvas @b focus: + * @dontinclude evas-events.c + * @skip bg = evas_object_rectangle_add + * @until focus_set + * + * Still exemplifying events and callbacks, we register a callback on + * the canvas event of an object being focused: + * @dontinclude evas-events.c + * @skip add(d.canvas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS + * @until } + * @dontinclude evas-events.c + * @skip called when + * @until } + * + * In that call, @c event_info is going to be the focused object's + * handle, in this case our background rectangle. We print its name, + * so you can check it's the same. We check that pointer is the same + * reported by Evas' API with regard to the newest focused + * object. Finally, we check whether that object is really flagged as + * focused, now using an Evas object API function. + * + * The animation we talked about comes from a timer we register just + * before we start the example's main loop. As we said, the resizing + * of the image will also force the canvas to repaint itself, thus + * flushing the rendering pipeline whenever the timer ticks: + * @dontinclude evas-events.c + * @skip d.resize_timer = ecore + * @until d.resize_timer = ecore + * @dontinclude evas-events.c + * @skip put some action + * @until } + * When you start this example, this animation will be + * running, by default. To interact with the program, there's a + * command line interface. A help string can be asked for with the + * 'h' key: + * @dontinclude evas-events.c + * @skip static const char *commands + * @until ; + * These are the commands the example will accept at any time, except + * when one triggers the 'f' one. This command will exemplify + * evas_event_freeze(), which interrupts @b all input events + * processing for the canvas (in the example, just for 3 seconds). Try + * to issue events for it during that freeze time: + * @dontinclude evas-events.c + * @skip if (strcmp(ev->keyname, "f") == 0) + * @until } + * The 'd' command will unregister those two canvas callbacks for you, + * so you won't see the messages about the focused object and the + * rendering process anymore: + * @dontinclude evas-events.c + * @skip if (strcmp(ev->keyname, "d") == 0) + * @until } + * In this example, we start using a focused object to handle the input + * events -- the background rectangle. We register a callback on an key input + * event occurring on it, so that we can act on each key stroke: + * @skip object_event_callback_add + * @until } + * @dontinclude evas-events.c + * @skip examine the keys pressed + * @until key grab + * We do so by examining the @c ev->keyname string (remember the event + * information struct for key down events is the #Evas_Event_Key_Down + * one). There's one more trick for grabbing input events on this + * example -- evas_object_key_grab(). The 'c' command will, when + * firstly used, @b unfocus the background rectangle. Unfocused + * objects on an Evas canvas will @b never receive key events. We + * grab, then, the keys we're interested at to the object forcefully: + * @skip if (d.focus) + * @until got here by key grabs + * This shows how one can handle input not depending on focus issues + * -- you can grab them globally. Switch back and forth focus and + * forced key grabbing with the 'c' key, and observe the messages + * printed about the focused object. Observe, also, that we register + * two more @b object callbacks, this time on the image object + * (Enlightenment logo), where we just print messages telling the mouse + * pointer has entered or exited it area: + * @skip evas_object_show(d.img); + * @until mouse_out, NULL + * @dontinclude evas-events.c + * @skip mouse enters the object's area + * @until mouse exits the object's area + * Experiment with moving the mouse pointer over the image, letting it + * enter and exit its area (stop the animation with 'a', for a better + * experience). When you start the example, Evas will consider this + * area by being the whole boundary rectangle around the picture. If + * you issue the 'p' command, though, you get a demonstration of Evas' + * precise point collision detection on objects. With + * evas_object_precise_is_inside_get(), one can make Evas consider the + * transparent areas of an object (the middle of the logo's E letter, + * in the case) as not belonging to it when calculating mouse + * in/out/up/down events: + * @dontinclude evas-events.c + * @skip if (strcmp(ev->keyname, "p") == 0) + * @until } + * To finish the example, try the command bound to Control + 'o', + * which exemplifies Evas' obscured regions. When firstly + * pressed, you'll get the same contents, in a region in the middle of + * the canvas, at the time the key was pressed, until you toggle the + * effect off again (make sure the animation is running on to get the + * idea better). When you toggle this effect off, we also demonstrate + * the use of evas_render_updates(), which will force immediate + * updates on the canvas rendering, bringing back the obscured + * region's contents to normal. + * @skip mods = evas_key_modifier_get(evas); + * @until end of obscured region command + * + * What follows is the complete code for this example. + * + * @include evas-events.c + * @example evas-events.c + */ + +/** + * @page Example_Evas_Object_Manipulation Evas objects basic manipulation example + * + * @include evas-object-manipulation.c + * @example evas-object-manipulation.c + */ + +/** + * @page Example_Evas_Aspect_Hints Evas aspect hints example + * + * @include evas-aspect-hints.c + * @example evas-aspect-hints.c + */ + +/** + * @page Example_Evas_Size_Hints Evas alignment, minimum size, maximum size, padding and weight hints example + * + * In this code, we place a (vertical) box with two rectangles as + * child elements. It has a command line interface with which to act + * on those rectangles' size hints: + * @dontinclude evas-hints.c + * @skip static const char commands + * @until ; + * + * That should be self explanatory. Change those values (possibly + * resizing the box, which will resize together with the example's + * window) to get how size hints are honored by a container object, + * which in this case is the Evas box. + * + * More on this smart object can be found on @ref Example_Evas_Box. + * The full code for this example follows. + * + * @include evas-hints.c + * @example evas-hints.c + */ + +/** + * @page Example_Evas_Box Evas box example + * + * In this example, we demonstrate the use of Evas box objects. We + * cover changing boxes' layouts (with a custom layout, besides the + * ones provided by Evas), box padding and alignment influence on the + * layouts, insertion and removal of box items. + * + * The interesting part of the code starts, naturally, when we add a + * box object to the canvas. Just after it, we place five rectangles, + * with random colors, inside of it. Those rectangles get a minimum + * size hint of 50 pixels on each axis, which will be respected by + * most of the box's possible layouts: + * @dontinclude evas-box.c + * @skip evas_object_box_add + * @until } + * @until } + * + * Just like in other Evas examples, we have a white background on the + * canvas and a red border around the container object of interest, + * the box, to mark its boundaries. Resizing of the canvas will keep + * the box's proportion with regard to the whole canvas', so that you + * can experiment with different sizes of the box to accomodate its + * children: + * @dontinclude evas-box.c + * @skip adjust canvas' contents on resizes + * @until } + * + * Again, one interacts with this program by means of key commands: + * @dontinclude evas-box.c + * @skip static const char *commands + * @until ; + * + * Let's start with the @b numeric ones, each of which will impose a + * different layout on the box object. + * + * The initial layout the box starts at is the one triggered by the + * key @c '1' -- the horizontal layout. Thus, the initial appearance + * of this program, demonstrating this layout, is something like: + * + * @image html evas-box-example-00.png + * @image rtf evas-box-example-00.png + * @image latex evas-box-example-00.eps + * + * The vertical layout (@c '2' key) is very similar, but just + * disposing the items vertically: + * + * @image html evas-box-example-01.png + * @image rtf evas-box-example-01.png + * @image latex evas-box-example-01.eps + * + * Note the influence of the (default) @c 0.5 box alignment property, + * which will let the children line in the middle of the box's + * area. Also, because the space required by them extrapolates the + * box's height (we resized it to be smaller), they'll be drawn out if + * its bounds. + * + * Next, comes the horizontal @b homogeneous layout (@c '3' key). See + * how it reserves an equal amount of space for each child to take: + * + * @image html evas-box-example-02.png + * @image rtf evas-box-example-02.png + * @image latex evas-box-example-02.eps + * + * Its vertical equivalent can be triggered by the @c '4' key. The + * next different layout of interest is the horizontal maximum size + * homogeneous (@c '5' key). It will reserve cells to children sized + * equally to the dimensions of the child with bigger size (or minimum + * size hints). For this example, all cells would be just the size of + * our rectangles' minimum size hints and, to prove that, insert a new + * (smaller) rectangle at position 3, say, with @c Ctrl and @c 3 keys + * together: + * + * @image html evas-box-example-03.png + * @image rtf evas-box-example-03.png + * @image latex evas-box-example-03.eps + * + * The code for the commands inserting and deleting box items is: + * @dontinclude evas-box.c + * @skip mods, "Shift" + * @until } + * @until } + * @dontinclude evas-box.c + * @skip new rectangle to be put in the box + * @until } + * In that code, we exemplify evas_object_box_children_get(), to fetch + * a child element at an exact position. After the element removal + * from the box (leaving it unparented again), we delete it and free + * that list. The code inserting a new rectangle, there, is + * straightforward. + * + * Try the @c '6' key for the vertical equivalent of the last shown + * layout. Then, comes the @b flow layout, triggered by the @c '7' + * key. We make our box small to demonstrate the effect on the items + * layouting: + * + * @image html evas-box-example-04.png + * @image rtf evas-box-example-04.png + * @image latex evas-box-example-04.eps + * + * The next two numerical commands are for the vertical equivalent of + * the last and the stack one, respectively. Try them out to get their + * looks. + * + * The last numerical key, @c '0', shows the effect of a @b custom + * layout on the box. We wrote one that would split the width and + * height of the box equally and, then, place the items in the cells + * in the diagonal: + * @dontinclude evas-box.c + * @skip keyname, "0" + * @until } + * @dontinclude evas-box.c + * @skip custom 'diagonal' layout + * @until } + * @until } + * + * @image html evas-box-example-05.png + * @image rtf evas-box-example-05.png + * @image latex evas-box-example-05.eps + * + * Finally, the @c 'a' and @c 'p' commands will change the box's + * alignment and padding property values, respectively. For each of + * the layouts above, see the effects they make by setting different + * values on those properties. + * + * The full code for this example follows. For an exercise on the + * effect of children box elements' size hints on a box layout, + * try the @ref Example_Evas_Size_Hints. + * + * @include evas-box.c + * @example evas-box.c + */ + +/** + * @page Example_Evas_Stacking Evas object stacking functions (and some event handling) + * @dontinclude evas-stacking.c + * + * In this example, we illustrate how to stack objects in a custom + * manner and how to deal with layers. + * + * We have three objects of interest in it -- white background, red + * rectangle, green rectangle and blue rectangle. + * @skip d.bg = evas_object_rectangle_add(d.canvas); + * @until evas_object_resize(d.bg, WIDTH, HEIGHT); + * @skip d.rects[2] = evas_object_rectangle_add(d.canvas); + * @until evas_object_show(d.rects[0]); + * @dontinclude evas-stacking.c + * Like in other Evas examples, one interacts with it by means of key + * commands: + * @skip static const char *commands + * @until ; + * At any given point, like seem above, you'll be operating one rectangle only. + * You may stacking it below an adjacent object with "b": + * @skip evas_object_stack_below(d.rects[d.cur_rect], neighbour); + * @until evas_object_stack_below(d.rects[d.cur_rect], neighbour); + * @dontinclude evas-stacking.c + * "a" will do the opposite: + * @skip evas_object_stack_above(d.rects[d.cur_rect], neighbour); + * @until evas_object_stack_above(d.rects[d.cur_rect], neighbour); + * To bring it directly to the top/bottom, use "t"/"m", respectively: + * @dontinclude evas-stacking.c + * @skip evas_object_raise(d.rects[d.cur_rect]); + * @until evas_object_raise(d.rects[d.cur_rect]); + * @skip evas_object_lower(d.rects[d.cur_rect]); + * @until evas_object_lower(d.rects[d.cur_rect]); + * At any time, use the "s" command to see the status of the + * ordering. It will show the background's ordering too. Note that it + * also shows the @b layer for this object. It starts at a @b + * different layer than the others. Use "l" to change its layer + * (higher layer numbers mean higher layers). If the background is on + * the same layer as the others (0), you'll see it interact with them + * on the ordering. If it's in the layer above, no matter what you do, + * you'll see nothing but the white rectangle: it covers the other + * layers. For the initial layer (-1), it will never mess nor occlude + * the others. + * + * Let's make some tests with those commands. The rectangle which starts + * selected and which will receive our commands is the @b red one. It + * starts stacked above all the others, like seem above: + * + * @image html evas-stacking-example-00.png + * @image rtf evas-stacking-example-00.png + * @image latex evas-stacking-example-00.eps + * + * Stack it one level below, with 'b', and you'll get: + * + * @image html evas-stacking-example-01.png + * @image rtf evas-stacking-example-01.png + * @image latex evas-stacking-example-01.eps + * Note how the rectangle which laid above it, the green one, is now + * on top of it. Now change the rectangle to operate on to the blue + * one, with two consecutive 'c' commands. Note that it's the lowest + * one on the stack of rectangles. Issue the 'a' command for it, thus + * re-stacking it one level above: + * + * @image html evas-stacking-example-02.png + * @image rtf evas-stacking-example-02.png + * @image latex evas-stacking-example-02.eps + * You can send it to the top of its layer directly with the 't' command: + * + * @image html evas-stacking-example-03.png + * @image rtf evas-stacking-example-03.png + * @image latex evas-stacking-example-03.eps + * Now put it back to the bottom of that layer with 'm': + * + * @image html evas-stacking-example-04.png + * @image rtf evas-stacking-example-04.png + * @image latex evas-stacking-example-04.eps + * Like said above, we have two layers used at the beginning of the + * example: the default one (0) and the one immediately below it (-1), + * for the white background. Let's change this setup by issuing the + * 'l' command, which will change the background's layer to 1, i.e., a + * layer @b above the one holding the other rectangles: + * + * @image html evas-stacking-example-05.png + * @image rtf evas-stacking-example-05.png + * @image latex evas-stacking-example-05.eps + * See how it now covers everything else. Press 'l' again, taking it + * now to layer 0. It's still covering everything because it lands the + * layer as the highest one on the objects stack. As we have the blue + * rectangle as the one receiving stacking commands, hit 't' and + * you'll see it again: + * + * @image html evas-stacking-example-06.png + * @image rtf evas-stacking-example-06.png + * @image latex evas-stacking-example-06.eps + * By bringing the background back to layer -1 ('l'), you'll get: + * + * @image html evas-stacking-example-07.png + * @image rtf evas-stacking-example-07.png + * @image latex evas-stacking-example-07.eps + * + * The last two commands available are "p" and "r", which will make + * the target rectangle to @b pass (ignore) and @b repeat the mouse + * events occurring on it (the commands will cycle through on and off + * states). This is demonstrated with the following + * #EVAS_CALLBACK_MOUSE_DOWN callback, registered on each of the + * colored rectangles: + * @dontinclude evas-stacking.c + * @skip static void + * @until } + * Try to change these properties on the three rectangles while + * experimenting with mouse clicks on their intersection region. + * + * The full example follows. + * + * @include evas-stacking.c + * @example evas-stacking.c + */ + +/** + * @page Example_Evas_Map_Overview Evas Map - Overview + * @dontinclude evas-map-utils.c + * + * Down to the very bottom, Map is simple: it takes an object and transforms + * the way it will be shown on screen. But using it properly can be a bit + * troublesome. + * + * For the most common operations there are utility functions that help in + * setting up the map to achieve the desired effects. Now we'll go through + * an overview of the map API and some of the things that can be done with + * it. + * + * The full code can be found @ref evas-map-utils.c "here". + * + * To show how some functions work, this example listens to keys pressed to + * toggle several options. + * @skip typedef + * @until App_Data + * @until ; + * + * In this program, we divide the window in four quadrants, each holding an + * object that will have different map configurations applied to them in each + * call to an animator function. + * @skip static Eina_Bool + * @until evas_output_size_get + * + * Let's first create a map and set some of our options to it. Only four + * points maps are supported, so we'll stick to that magic number. We can + * set a color for each vertex or apply one for all of them at once + * @until evas_map_util_points_color_set + * + * For the first object, we'll have a plain rectangle. At its creation, this + * rectangle was set to be semi-transparent, but whether its own alpha is + * used will be defined by the map's alpha setting. If the map's alpha is + * disabled, then the object will be completely opaque. The map's own color, + * however, will use any alpha set to it. + * + * So we get our object, initialize our map geometry to match the rectangle + * and make it rotate around its own center, then apply the map to the + * object so it takes effect. + * @until evas_object_map_enable_set + * + * The second object is an image. Here we don't have any color set for the + * object, but the image itself contains an alpha channel that will not be + * affected by the map settings, so even with alpha set to be off, the image + * will still be transparent. Color applied to the map will tint it though. + * Since setting a map copies it into the object, we can reuse the same one + * we created before. We initialize it to the new object while all other + * options are kept the same. Notice that no rotation will be done here, as + * that's just an utility function that takes the coordinates set for each + * point of the map and transforms it accordingly. + * @until evas_map_util_points_populate_from_object_full + * + * This time the object is a bit farther into the screen, by using a @c z + * value higher than 0 to init the map. We also need to map the image used + * by the object, so Evas knows how to transform it properly. For this we + * use the evas_map_point_image_uv_set() to tell the map what coordinate + * within the image corresponds to each point of the map. + * @until evas_map_point_image_uv_set(m, 3 + * + * This object will also be rotated, but in all three axis and around some + * other point, not its center, chosen mostly at random. If enabled, lighting + * will be applied to, from a light source at the center of the window. + * @until evas_object_map_enable_set + * + * For the third object we are doing, once more, a 3D rotation, but this time + * perspective will be applied to our map to make it look more realistic. + * The lighting source also follows the mouse cursor and it's possible to + * toggle backface culling, so that the object is hidden whenever we are + * not seeing its front face. + * @until evas_object_map_enable_set + * + * And we free this map, since since we messed too much with it and for the + * last object we want something cleaner. + * @until evas_map_free + * + * The last object is actually two. One image, with an image set to it, and + * one image proxying the first one with evas_object_image_source_set(). This + * way, the second object will show whatever content its source has. + * This time we'll be using a map more manually to simulate a simple reflection + * of the original image. + * + * We know that the reflection object is placed just like the original, so + * we take a shortcut by just getting the geometry of our to-be-mapped object. + * We also need to get the image size of the source. + * @until evas_object_image_size_get + * + * For this we'll create a map shaped so that it begins at the base of our + * image and it expands horizontally as it grows (downwards) in height. + * @until evas_map_point_coord_set(m, 3 + * + * Since the reflection should show the image inverted, we need to map it + * this way. The first point of the map (top-left) will be mapped to the + * mapped to the first pixel of the last row. There's no horizontal reflection + * and we want the full width of the image, but as we map its upper side ww + * will only take two thirds of the image. + * @until evas_map_point_image_uv_set(m, 3 + * + * Finally, to fade out our reflection we set the colors for each point in + * the map. The two at the top need to be visible, but we'll tone them down + * a bit and make them a bit translucent. The other two will go straight to + * full transparency. Evas interpolates the colors from one point to the next, + * so this will make them fade out. + * @until evas_object_map_enable_set + * + * Close up by freeing the map and do some other things needed to keep stuff + * moving in our animations and we are done. + * @until } + * + * The rest of the program is setup and listening to key events. Nothing that + * matters within the scope of this example, so we are going to skip it. + * Refer to it @ref evas-map-utils.c "here" however to see how everything + * fits together. + * + * @example evas-map-utils.c + */ + +/** + * @page Example_Evas_Smart_Objects Evas object smart objects + * @dontinclude evas-smart-object.c + * + * In this example, we illustrate how to create and handle Evas smart objects. + * + * A smart object is one that provides custom functions to handle + * clipping, hiding, moving, resizing, color setting and more on @b + * child elements, automatically, for the smart object's user. They + * could be as simple as a group of objects that move together (see + * @ref Evas_Smart_Object_Clipped) or implementations of whole complex + * UI widgets, providing some intelligence (thus the name) and + * extension to simple Evas objects. + * + * Here, we create one as an example. What it does is to control (at + * maximum) 2 child objects, with regard to their geometries and + * colors. There can be a "left" child and a "right" one. The former + * will always occupy the top left quadrant of the smart object's + * area, while the latter will occupy the bottom right. The smart + * object will also contain an @b internal decorative border object, + * which will also be controlled by it, naturally. + * + * Here is where we add it to the canvas: + * @skip d.smt = evas_smart_example_add(d.evas); + * @until show + * + * The magic starts to happen in the @c evas_smart_example_add() + * function, which is one in the example smart object's defined @b + * interface. These should be the functions you would export to the + * users of your smart object. We made three for this one: + * - @c evas_smart_example_add(): add a new instance of the example + * smart object to a canvas + * - @c evas_smart_example_remove(): remove a given child of the smart + * object from it + * - @c evas_smart_example_set_left(): set the left child of the smart + * object + * - @c evas_smart_example_set_right(): set the right child of the + * smart object + * + * The object's creation takes place as: + * @dontinclude evas-smart-object.c + * @skip add a new example smart object to a canvas + * @until } + * + * Smart objects are defined by smart classes, which are structs + * defining their interfaces, or smart functions (see + * #Evas_Smart_Class, the base class for any smart object). As you + * see, one has to use the evas_object_smart_add() function to + * instantiate smart objects. Its second parameter is what matters -- + * an #Evas_Smart struct, which contains all the smart class + * definitions (smart functions, smart callbacks, and the like). Note, + * however, that @c _evas_smart_example_smart_class_new() seems not to + * be defined in our example's code. That's because it came from a very + * handy helper macro: + * @dontinclude evas-smart-object.c + * @skip EVAS_SMART_SUBCLASS_NEW + * @until _smart_callbacks + * What it does is to @b subclass a given existing smart class, thus + * specializing it. This is very common and useful in Evas. There is a + * built-in smart object, the "clipped smart object", which implements + * a behavior mostly desired by many other smart object implementors: + * it will clip its children to its area and move them along with it, + * on evas_object_move() calls. Then, our example smart object will + * get that behavior for free. + * + * The first argument to the macro, + * @dontinclude evas-smart-object.c + * @skip _evas_smart_example_type + * @until _evas_smart_example_type + * will define the new smart class' name. The second tells the macro + * what is the @b prefix of the function it will be declaring with a @c + * _smart_set_user() suffix. On this function, we may override/extend + * any desired method from our parent smart class: + * @dontinclude evas-smart-object.c + * @skip setting our smart interface + * @until } + * + * The first function pointer's code will take place at an example + * smart object's @b creation time: + * @dontinclude evas-smart-object.c + * @skip create and setup + * @until } + * + * The #EVAS_SMART_DATA_ALLOC macro will take care of allocating our + * smart object data, which will be available on other contexts for us + * (mainly in our interface functions): + * @dontinclude evas-smart-object.c + * @skip typedef struct _Evas_Smart_Example_Data + * @until }; + * + * See that, as we're inheriting from the clipped smart object's + * class, we @b must have their data struct as our first member. Other + * data of interest for us is a child members array and the border + * object's handle. The latter is what is created in the last + * mentioned function. Note how to tell Evas the border will be + * managed by our smart object from that time on: + * evas_object_smart_member_add(priv->border, o);. + * The counterpart of this function is exemplified on the smart + * object's interface function to remove children: + * @skip remove a child element + * @until set to + * + * At the end of that function we make use of an constant defined by + * the #EVAS_SMART_SUBCLASS_NEW: @c _evas_smart_example_parent_sc. It + * has the same prefix we passed to the macro, as you can see, and it + * holds a pointer to our @b parent smart class. Then, we can call the + * specialized method, itself, after our code. The @c del, @c hide, @c + * show and @c resize specializations are straightforward, we let the + * reader take a look at them below to check their behavior. What's + * interesting is the @c calculate one: + * @dontinclude evas-smart-object.c + * @skip act on child objects' properties + * @until setting + * + * This code will take place whenever the smart object itself is + * flagged "dirty", i.e., must be recalculated for rendering (that + * could come from changes on its clipper, resizing, moving, + * etc). There, we make sure the decorative border lies on the edges of + * the smart object and the children, if any, lie on their respective + * quadrants. + * + * After instantiating our smart object, we do some checks to exemplify + * some of the API on smart objects: + * @dontinclude evas-smart-object.c + * @skip ret = evas_object_smart_type_check + * @until "no" + * The evas_object_smart_type_check() one will assure we have the + * string naming our smart class really set to the live object. The + * evas_object_smart_clipped_clipper_get() exemplifies usage of + * "static clippers" -- clipped smart objects have their global + * clippers flagged static. + * + * Other important things we also exemplify here are smart + * callbacks and smart callback @b introspection: + * @dontinclude evas-smart-object.c + * @skip EVT_CHILDREN_NUMBER_CHANGED + * @until ; + * + * Here we declare our array of smart callback descriptions, which has + * one element only, in this case. That callback will take place, as + * the name indicates, whenever the number of member objects in our + * smart object example instance changes. That global array variable + * must be the last argument to #EVAS_SMART_SUBCLASS_NEW, so that it's + * registered as the smart class's callbacks description. + * + * After we instantiate the smart object, we take a look on those + * descriptions and register a callback on that unique smart event: + * @dontinclude evas-smart-object.c + * @skip for (; + * @until focus_set + * + * The code of the callback will just print how many member objects we + * have, which is an integer argument of the callback itself, as + * flagged by its description: + * @dontinclude evas-smart-object.c + * @skip callback on number of member objects changed + * @until } + * + * One of the points at which we issue that callback is inside the @c + * evas_smart_example_remove(), code that was already shown. + * + * As in other examples, to interact with this one there's a command + * line interface. A help string can be asked for with the 'h' key: + * @dontinclude evas-smart-object.c + * @skip static const char *commands = + * @until ; + * Use 'l' and 'r' keys, to create new rectangles and place them on + * the left (@c evas_smart_example_set_left()) or right (@c + * evas_smart_example_set_right()) spots of our smart object, + * respectively. The 'w' command will remove all member objects from + * the smart object and delete them. The keyboard arrows will move the + * smart object along the canvas. See how it takes any child objects + * with it during its movement. The 'd' and 'i' keys will increase or + * decrease the smart object's size -- see how it affects the + * children's sizes, too. Finally, 'c' will change the color of the + * smart object's clipper (which is the exact internal clipper coming + * from a clipped smart object): + * @dontinclude evas-smart-object.c + * @skip d.clipper = + * @until .a); + * + * "Real life" examples of smart objects are Edje and Emotion objects: + * they both have independent libraries implementing their + * behavior. The full example follows. + * + * @include evas-smart-object.c + * @example evas-smart-object.c + */ + +/** + * @page Example_Evas_Smart_Interfaces Evas object smart interfaces + * @dontinclude evas-smart-interface.c + * + * In this example, we illustrate how to create and handle Evas smart + * @b interfaces. Note that we use the same code base of the @ref + * Example_Evas_Smart_Objects example, here. We just augment it with + * an interfaces demonstration. + * + * A smart interface is just a functions interface a given smart + * objcet is declaring to support and or use. In Evas, interfaces are + * very simple: no interface inheritance, no interface + * overriding. Their purpose is to extend an object's capabilities and + * behaviour beyound the sub-classing schema. + * + * Here, together with a custom smart object, we create and declare + * the object as using an Evas interface. It'll have a custom + * function, too, besides the @c add() and del() obligatory ones. To + * demonstrate interface data, which is bound to object @b instances, + * we'll have a string as this data. + * + * Here is where we declare our interface: + * @skip static const char iface1_data[] + * @until (Evas_Smart_Interface *)&iface1, NULL + * @until }; + * + * Note that there's error checking for interfaces creation, by means of + * the @c add() method's return value (@c _iface1_add(), here). + * + * Now note that here we are filling in the interface's fields dinamically. + * Let's move on to that code region: + * + * @dontinclude evas-smart-interface.c + * @skip iface = (Evas_Smart_Example_Interface *)&iface1; + * @until d.smt = evas_smart_example_add(d.evas); + * + * As important as setting the function pointers, is declaring the @c + * private_size as to match exactly the size of the data blob we want + * to have allocated for us by Evas. This will happen automatically + * inside @c evas_smart_example_add(). Later, on this code, we deal + * exactly with that data blob, more specifically writing on it (as + * it's not done inside @c _iface1_add(), here: + * + * @dontinclude evas-smart-interface.c + * @skip iface = (Evas_Smart_Example_Interface *)evas_object_smart_interface_get + * @until } + * + * Before accessing the interface data, we exercise the interface + * fetching call evas_object_smart_interface_get(), with the name + * string we used to be interface's name. With that handle in hands, + * we issue evas_object_smart_interface_data_get() and write the + * string we want as data on that memory region. That will make up for + * the string you get on @c _iface1_del(). + * + * The full example follows. + * + * @include evas-smart-interface.c + * @example evas-smart-interface.c + */ + +/** + * @page Example_Evas_Text Evas text object example + * + * In this example, we illustrate how to use text objects in various + * manners. + * + * We place, in the canvas, a text object along with a border image to + * delimit its geometry. After we instantiate the text object, we set + * lots of properties on it to the initial ones from a preset list, + * which has the following declaration: + * @dontinclude evas-text.c + * @skip init values + * @until }; + * + * Then, we set the text string itself, on it, with + * evas_object_text_text_set(). We set an explicit size of 30 points + * for our font, as you could see, what we check back with the + * getter evas_object_text_font_get(). + * + * Look at how it translates to code: + * @dontinclude evas-text.c + * @skip evas_object_text_add + * @until fprintf + * + * Like in other Evas examples, one interacts with it by means of key + * commands: + * @dontinclude evas-text.c + * @skip static const char *commands + * @until ; + * + * Use the 't' key to exercise the evas_object_text_style_set() + * function on the text -- it will cycle through all styles on + * #Evas_Text_Style_Type (note we start on #EVAS_TEXT_STYLE_PLAIN, + * thus with no effects on it) and, with other keys, you'll be able to + * set properties applicable to individual styles on the text object. + * + * The 'z' key will change the text's @b size, keeping the font family + * for it. Use 'f' to change the font, keeping the last size + * set. There are three font families the example will cycle through: + * + * The 'b' command shows us that evas_object_color_set(), on a given + * text object, will change the text's @b base color. Experiment with + * it, which will cycle through the colors in the .text list in + * @c init_data. + * + * The 's', 'o', 'w' and 'g' keys will make the text object to cycle + * to the preset values on colors for shadow, outline, glow and 'glow + * 2' effects, respectively. Naturally, they will only take effect on + * the text styles which resemble them. + * + * The full example follows. + * + * @include evas-text.c + * @example evas-text.c + */ + +/** + * @page tutorial_table Table Smart Object example + * + * This example will arrange rectangles of different sizes(and colors) in a + * table. While it's possible to create the same layout we are doing here by + * positioning each rectangle independently, using a table makes it a lot + * easier, since the table will control layout of all the objects, allowing you + * to move, resize or hide the entire table. + * + * We'll start with creating the table, setting it to + * EVAS_OBJECT_TABLE_HOMOGENEOUS_NONE to have maximum flexibility and setting + * its padding to 0: + * @dontinclude evas-table.c + * @skip object_table + * @until show + * + * We then create each rectangle and add it to the table: + * @until table_pack + * @until table_pack + * @until table_pack + * @until table_pack + * @note Each rectangle has a different minimum size based on how many rows and + * columns it will occupy. + * + * The full source for this example follow: + * @include evas-table.c + * @example evas-table.c + */