Multi layer/multi display support
Multi layer support and multi display support work the same way. Each layer / display can be accessed with its own color settings, its own size and its own display driver. Initialization of more than one layer is quite simple: The maximum number of available layers GUI_NUM_LAYERS should be defined in GUIConf.h and each layer needs a display driver device which should be created during the initialization in the configuration routine LCD_X_Config(). There is no limitation regarding the maximum number of available layers. Windows can be placed in any layer or display, drawing operations can be used on any layer or display. Since there are really only smaller differences from this point of view, multiple layers and multiple displays are handled the same way (Using the same API routines) and are simply referred to as multiple layers, even if the particular embedded system uses multiple displays.
Selecting a layer for drawing operations
When drawing directly, per default layer 0 is used. An other layer can be selected by using GUI_SelLayer()1.
Sample
The following sample shows how to select a layer for drawing operations:
void MainTask(void) {
GUI_Init();
/* Draw something on default layer 0 */
GUI_SetBkColor(GUI_GREEN);
GUI_Clear();
GUI_DispStringHCenterAt("Layer 0", 100, 46);
/* Draw something on layer 1 */
GUI_SelLayer(1); /* Select layer 1 */
GUI_SetBkColor(GUI_RED);
GUI_Clear();
GUI_SetColor(GUI_BLUE);
GUI_FillRect(20, 20, 179, 79);
GUI_SetColor(GUI_WHITE);
GUI_SetTextMode(GUI_TM_TRANS);
GUI_DispStringHCenterAt("Layer 1", 100, 46);
while(1) {
GUI_Delay(100);
}
} Screenshot of above sample

Selecting a layer for a window
The window manager automatically keeps track of which window is located in which layer. This is done in a fairly easy way: If the window manager is used, every layer has a top level (desktop) window. Any other window in this layer is visible only if it is a descendent (a child or grandchild or ...) of one of these desktop windows. Which layer a window is in depends solely on which desktop window it is a descendent of.
Sample
The following sample shows how to create 3 windows on 2 different desktop windows:
hWin0 = WM_CreateWindowAsChild( 10, 20, 80, 70, WM_GetDesktopWindowEx(0), WM_CF_SHOW, _cbWin0, 0); /* Create 2 child windows on destop 1 */ hWin1 = WM_CreateWindowAsChild( 10, 20, 80, 70, WM_GetDesktopWindowEx(1), WM_CF_SHOW, _cbWin1, 0); hWin2 = WM_CreateWindowAsChild(110, 20, 80, 70, WM_GetDesktopWindowEx(1), WM_CF_SHOW, _cbWin2, 0);
Screenshot of above sample
| Screenshot | Window hierarchy |
![]() | ![]() |
Moving a window from one layer to an other
This can sometime be very desireable and can easily be accomplished: If a window is detached from its parent (The desktop window of one layer or any descenedent of this ldesktop window) and attached to a window which lies in an other layer, this window actually moves from one layer to an other layer.
Sample
The following sample shows how to detach a window from its parent window and how to attach it to a new parent window:
/* Create 1 child window on destop 0 */ hWin0 = WM_CreateWindowAsChild( 10, 20, 80, 70, WM_GetDesktopWindowEx(0), WM_CF_SHOW, _cbWin0, 0); /* Create 2 child windows on destop 1 */ hWin1 = WM_CreateWindowAsChild( 10, 20, 80, 70, WM_GetDesktopWindowEx(1), WM_CF_SHOW, _cbWin1, 0); hWin2 = WM_CreateWindowAsChild(110, 20, 80, 70, WM_GetDesktopWindowEx(1), WM_CF_SHOW, _cbWin2, 0); GUI_Delay(1000); /* Detach window 2 from desktop 1 and attach it to desktop 0 */ WM_AttachWindow(hWin2, WM_GetDesktopWindowEx(0));
Any other window in this layer is visible only if it is a descendent (a child or grandchild or ...) of one of these desktop windows. Which layer a window is in depends solely on which desktop window it is a descendent of.
| Screenshot | Window hierarchy |
![]() | ![]() |
The next table shows the screenshot and the window hierarchy of the above sample after attaching the window to the new parent:
| Screenshot | Window hierarchy |
![]() | ![]() |
Using multi layer support
emWin does not distinguish between multiple layers or multiple displays. When using multiple layers normally the size and the driver for each layer is the same. The viewer shows each layer in a separate window. The composite window of the viewer shows all layers; layers with higher index are on top of layers with lower index and can have transparent pixels:

Transparency
Transparency means that at the position of pixels with color index 0 in a layer > 0, the color of the background layer is visible. Since for all but layer 0 Index 0 means transparency, Index 0 can not be used to display colors. This also means that the color conversion should never yield 0 as best match for a color, since this would result in a transparent pixel. This means that only some fixed palette modes or a custom palette mode should be used and that you need to be careful when defining you own palette. You need to make sure that the color conversion (24 bit RGB -> Index) never yields 0 as result.
Example
The following example shows how to use transparency. It draws 3 color bars in layer 0. Layer 1 is filled with white and 3 transparent items are drawn.
GUI_SelectLayer(0);
GUI_SetColor(GUI_RED);
GUI_FillRect(0, 0, 199, 33);
GUI_SetColor(GUI_GREEN);
GUI_FillRect(0, 34, 199, 66);
GUI_SetColor(GUI_BLUE);
GUI_FillRect(0, 67, 199, 99);
GUI_SelectLayer(1);
GUI_SetBkColor(GUI_WHITE);
GUI_Clear();
GUI_SetColor(GUI_BLACK);
GUI_DispStringHCenterAt("Layer 1", 100, 4);
GUI_SetColor(GUI_TRANSPARENT);
GUI_FillCircle(100, 50, 35);
GUI_FillRect(10, 10, 40, 90);
GUI_FillRect(160, 10, 190, 90);
Screenshot of the above example
The table below shows the contents of the separate layers and the composite view, as the result appears on the display:
| Layer 0 | Layer 1 | Layer 2 |
![]() | ![]() | ![]() |
Alpha blending
Alpha blending is a method of combining two colors allowing for transparency effects. Assumed 2 colors C0 and C1 should be combined with alpha blending A (a value between 0 and 1 where 0 means invisible and 1 means 100% visible) the resulting color Cr can be calculated as follows:
Cr = C0 * (1 - A) + C1 * A
Logical colors are handled internally as 32 bit values. The lower 24 bits are used for the color information and the alpha blending is managed in the upper 8 bits. An alpha value of 0x00 means opaque and 0xFF means completely transparent (invisible).
Different methods
There are 3 different methods of managing the alpha information:
- Layer alpha blending: On systems with layer alpha blending the alpha value is fixed to the layer and can be set with the function LCD_SetAlphaEx().
- Lookup table (LUT) alpha blending: This kind of alpha blending uses the LUT for managing the alpha information.
- Pixel alpha blending: Each pixel of the layer to be combined with the background consists of alpha blending information.
Example
The following example shows how to use pixel alpha blending. It draws a circle in layer 0 and a yellow triangle build of horizontal lines with a vertical gradient of alpha values:
GUI_SetColor(GUI_BLUE);
GUI_FillCircle(100, 50, 49);
GUI_SetBkColor(GUI_TRANSPARENT);
GUI_Clear();
for (i = 0; i < 100; i++) {
U32 Alpha;
Alpha = (i * 255 / 100) << 24;
GUI_SetColor(GUI_YELLOW | Alpha);
GUI_DrawHLine(i, 100 - i, 100 + i);
}
Screenshots of the above example
The table below shows the contents of the separate layers and the composite view,
as the result appears on the display:
Hardware cursors
The term ’Hardware cursor’ means the use of cursor images in a separate layer with
a transparent background. If a hardware supports of multiple layers and the ability of
layer positioning emWin can be configured to use a separate layer for managing the
cursor. The main advantages of this kind of cursor support are a better performance
because only a few registers need to be changed on a movement and the ability of
custom drawings in the cursor layer.
| Layer 0 | Layer 1 | Layer 2 |
![]() | ![]() | ![]() |
Multi layer/multi display support










