[Simulator] Using 3 or more simulated displays in the PC simulator

Hi,

hope somebody here tried it and succeeded already at this task.

Description

I have the simulator running with 2 (fake) displays (2 display drivers, 2 display buffers, 2 monitors). Is the 2 monitors step necessary or could I draw the 2 displays on 1 “monitor” ?

My main question would be, if it is easily possible to add another display. Do I have to add a monitor_flush3() function for that ? Sorry, it is my first day of trying lvgl and I obviously did not read the whole documentation document.

What MCU/Processor/Board and compiler are you using?

Just the simulator on Fedora Linux, it compiles fine.

What LVGL version are you using?

I am using this example : https://github.com/lvgl/lv_sim_vscode_sdl
Uses LVGL v7

What do you want to achieve?

Extend the example in order to have 3-4 simulated displays.

What have you tried so far?

I am currently stuck on the 2 simulated display solution; I set the flag

MONITOR_DUAL to 1 and added a second display driver, display buffer, which uses monitor_flush2() instead of monitor_flush(). Is it now mandatory to add a monitor_flush3() for a 3rd fake display ?

Code to reproduce

static void hal_init(void) {
  /* Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/
  monitor_init();

  /*Create a display buffer*/
  static lv_disp_buf_t disp_buf1;
  static lv_color_t buf1_1[LV_HOR_RES_MAX * 300];
  lv_disp_buf_init(&disp_buf1, buf1_1, NULL, LV_HOR_RES_MAX * 300);

  /*Create a display*/
  lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv); /*Basic initialization*/
  disp_drv.buffer = &disp_buf1;
  disp_drv.flush_cb = monitor_flush;
  disp_handle = lv_disp_drv_register(&disp_drv);

    /*Create a display buffer*/
  static lv_disp_buf_t disp_buf2;
  static lv_color_t buf1_2[LV_HOR_RES_MAX * 180];
  lv_disp_buf_init(&disp_buf2, buf1_2, NULL, LV_HOR_RES_MAX * 180);

  /*Create a display*/
  lv_disp_drv_t disp_drv2;
  lv_disp_drv_init(&disp_drv2); /*Basic initialization*/
  disp_drv2.buffer = &disp_buf2;
  disp_drv2.flush_cb = monitor_flush2;
  disp2_handle = lv_disp_drv_register(&disp_drv2);

//now add a third buffer, display, flush-call ?
...
}

Screenshot and/or video

Now I got 2, but I want 3-4 displays and would appreciate suggestions for correctly simulating several physical displays.

LVGL doesn’t have an inherent limit on the number of the displays, but the monitor driver is currently hardcoded to support only 1 or 2, so yes, you would have to duplicate the logic again for the third display.

Thank you for the quick response. And do you by chance know, how I would tie the mouse driver to one particular display on focus ? I mean is this possible at all ? Atm, the mouse events from one display are also handled by the other display on the same coordinates.

The behavior you are describing is a flaw with the current implementation, as the mouse really should be tied to one particular display at a time. I don’t have time to investigate it in detail, but at first glance, it seems that the interaction between the monitor and mouse drivers needs to be tweaked so the latter knows when there are multiple displays.

Thank you. I think, the cause lies also in this function :

static void sdl_event_handler(lv_task_t * t){…} in monitor.c

There is a not implemented switch branch : case SDL_WINDOWEVENT_TAKE_FOCUS

Hmm. I’ll see, if I can tweak it.

Hi,

do you by chance know, whether multi monitor in the simulator is at all supported in the CodeBlocks Version for Windows ? The window driver there has a quite different implementation and I am not sure, whether that is supported at the moment in the Windows version. I would rather try to tweak the Linux implementation (with SDL2) in that case. Thanks in advance for any hint.

As far as I know, the Windows driver does not support multiple monitors.

Thank you very much, so I will pursue fiddling with the Linux implementation. At the moment I am struggling with resizing the different simulated displays. There is the macro (for width)

LV_HOR_RES_MAX defined in lv_conf.h and this is used in different places and the macro MONITOR_HOR_RES defined in lv_drv_conf.h

If I reduce the MONITOR_HOR_RES, the width of the simulated display will adjust accordingly, but the elements will be hidden (overflow to the right) because the width of the objects seemingly depend on LV_HOR_RES_MAX. Any tipps, what I should tweak ? I have the impression, that LV_HOR_RES_MAX is used in too many places (for my usecase), but this could be wrong.