Ecore_Evas: Creating a Canvas for Wayland Applications

While there are some developers who are familiar with using Ecore_Evas to create a canvas for applications, we often find that new EFL users face some confusion when first trying to create an application. This article aims to provide a simple example of how to create your first EFL Wayland application.

For those not familiar with the Ecore_Evas library, it is a set of functions that make it easy to tie together Ecore’s main loop and input handling to Evas; as such, it’s a natural base for EFL applications. While this combination makes it easy to create the basic aspects all applications need, for normal applications (those that use buttons, checkboxes and layouts) one should consider using Elementary. Ecore_Evas is extremely well suited for applications that are not based on widgets. It has a main loop that delivers events, does basic window handling, and leaves all of the drawing up to the user. This works very well if used in conjunction with Edje or when doing custom drawing such as what’s done for games, for example.

A typical example of an Ecore_Evas application may look like this

/**
 * Ecore example illustrating the basics of ecore evas usage.
 *
 * You'll need at least one Evas engine built for it (excluding the
 * buffer one). See stdout/stderr for output.
 *
 * @verbatim
 * gcc -o ecore_evas_basics_example ecore_evas_basics_example.c `pkg-config --libs --cflags ecore evas ecore-evas`
 * @endverbatim
 */

#include 
#include 
#include 

static Eina_Bool
_stdin_cb(void *data EINA_UNUSED, Ecore_Fd_Handler *handler EINA_UNUSED)
{
   Eina_List *l;
   Ecore_Evas *ee;
   char c;

   int ret = scanf("%c", &c);
   if (ret < 1) return ECORE_CALLBACK_RENEW;

   if (c == 'h')
     EINA_LIST_FOREACH(ecore_evas_ecore_evas_list_get(), l, ee)
       ecore_evas_hide(ee);
   else if (c == 's')
     EINA_LIST_FOREACH(ecore_evas_ecore_evas_list_get(), l, ee)
       ecore_evas_show(ee);

   return ECORE_CALLBACK_RENEW;
}

static void
_on_delete(Ecore_Evas *ee)
{
   free(ecore_evas_data_get(ee, "key"));
   ecore_main_loop_quit();
}

int
main(void)
{
   Ecore_Evas *ee;
   Evas *canvas;
   Evas_Object *bg;
   Eina_List *engines, *l;
   char *data;

   if (ecore_evas_init() <= 0)
     return 1;

   engines = ecore_evas_engines_get();
   printf("Available engines:\n");
   EINA_LIST_FOREACH(engines, l, data)
     printf("%s\n", data);
   ecore_evas_engines_free(engines);

   ee = ecore_evas_new(NULL, 0, 0, 200, 200, NULL);
   ecore_evas_title_set(ee, "Ecore Evas basics Example");
   ecore_evas_show(ee);

   data = malloc(sizeof(char) * 6);
   sprintf(data, "%s", "hello");
   ecore_evas_data_set(ee, "key", data);
   ecore_evas_callback_delete_request_set(ee, _on_delete);

   printf("Using %s engine!\n", ecore_evas_engine_name_get(ee));

   canvas = ecore_evas_get(ee);
   if (ecore_evas_ecore_evas_get(canvas) == ee)
     printf("Everything is sane!\n");

   bg = evas_object_rectangle_add(canvas);
   evas_object_color_set(bg, 0, 0, 255, 255);
   evas_object_resize(bg, 200, 200);
   evas_object_show(bg);
   ecore_evas_object_associate(ee, bg, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);

   ecore_main_fd_handler_add(STDIN_FILENO, ECORE_FD_READ, _stdin_cb, NULL, NULL, NULL);

   ecore_main_loop_begin();

   ecore_evas_free(ee);
   ecore_evas_shutdown();

   return 0;
}

This example application will use the first available Ecore_Evas engine to create a canvas that contains a blue rectangle.

Ecore_Evas Creating a Canvas for Wayland Applications - shot-2016-12-13_08-42-35

While this is not a very exciting example, it does illustrate how to create a basic Ecore_Evas application quite well.

How to Use Wayland with Ecore_Evas

With a simple modification of one line, this example application can run in a Wayland environment. The following line is changed to facilitate this.

ee = ecore_evas_new(NULL, 0, 0, 200, 200, NULL);

To run in Wayland, it should read

ee = ecore_evas_new("wayland_shm", 0, 0, 200, 200, NULL);

This essentially tells ecore_evas to utilize the Wayland_Shm engine to create a new canvas; this is an Evas engine that uses Wayland and Shared-Memory for drawing. There are other Evas Wayland engines available, such as the "wayland_egl" engine which uses Hardware Accelerated drawing (namely EGL).

What many new EFL developers do not realize is that there is an even easier way to make this application run in a Wayland environment, without changing a single line of code! While running in a Wayland environment (Weston, Enlightenment-Wayland, Gnome-Wayland, etc) the following command should be run from the terminal

export ECORE_EVAS_ENGINE=wayland_shm

Then, the application can be run, and when ecore_evas_new executes it will check for the ECORE_EVAS_ENGINE environment variable and attempt to use the engine specified there.

This means application developers who utilize Ecore_Evas can easily make any application run in a Wayland environment. It's possible to choose to make it Wayland specific by modifying the function call that creates the canvas, or it's possible to simply export an environment variable to change the engine that's in use. Personally, I have always found it easier to set the environment variable because this makes it possible to test the application under various windowing systems (such as X11, Wayland, Framebuffer) without modifying and recompiling the code.

For more information on how to utilize Ecore_Evas to create a basic EFL application, please see the Ecore_Evas documentation.

Author: Chris Michael

Chris Michael has been an EFL/Enlightenment developer for over 13 years and is now working for the Samsung Open Souce Group.

One thought on “Ecore_Evas: Creating a Canvas for Wayland Applications”

Comments are closed.