1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
/**
* Copyright 2025 buffybox contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "display.h"
#include "log.h"
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
lv_display_t *bbx_display_create(bbx_backends_backend_id_t backend_id, bbx_display_config_t *config) {
lv_display_t *disp = NULL;
switch (backend_id) {
#if LV_USE_LINUX_FBDEV
case BBX_BACKENDS_BACKEND_FBDEV:
bbx_log(BBX_LOG_LEVEL_VERBOSE, "Using framebuffer backend");
disp = lv_linux_fbdev_create();
if (!disp) {
bbx_log(BBX_LOG_LEVEL_ERROR, "Failed to create framebuffer display");
return NULL;
}
if (access("/dev/fb0", F_OK) != 0) {
bbx_log(BBX_LOG_LEVEL_ERROR, "/dev/fb0 is not available");
return NULL;
}
lv_linux_fbdev_set_file(disp, "/dev/fb0");
if (config && config->fbdev_force_refresh) {
lv_linux_fbdev_set_force_refresh(disp, true);
}
break;
#endif /* LV_USE_LINUX_FBDEV */
#if LV_USE_LINUX_DRM
case BBX_BACKENDS_BACKEND_DRM:
bbx_log(BBX_LOG_LEVEL_VERBOSE, "Using DRM backend");
disp = lv_linux_drm_create();
if (!disp) {
bbx_log(BBX_LOG_LEVEL_ERROR, "Failed to create DRM display");
return NULL;
}
char drm_path[16];
bool found = false;
for (int i = 0; i < 9; i++) {
sprintf(drm_path, "/dev/dri/card%d", i);
if (access(drm_path, F_OK) == 0) {
found = true;
break;
}
}
if (!found) {
bbx_log(BBX_LOG_LEVEL_ERROR, "/dev/dri/card* are not available");
return NULL;
}
lv_linux_drm_set_file(disp, drm_path, -1);
break;
#endif /* LV_USE_LINUX_DRM */
default:
bbx_log(BBX_LOG_LEVEL_ERROR, "Unable to find suitable backend");
return NULL;
}
/* Apply configuration overrides if provided */
if (config) {
/* Set display offset */
lv_display_set_offset(disp, config->x_offset, config->y_offset);
/* Override resolution if specified */
if (config->hor_res > 0 || config->ver_res > 0) {
lv_display_set_physical_resolution(disp,
lv_display_get_horizontal_resolution(disp),
lv_display_get_vertical_resolution(disp));
lv_display_set_resolution(disp, config->hor_res, config->ver_res);
}
/* Override DPI if specified */
if (config->dpi > 0) {
lv_display_set_dpi(disp, config->dpi);
}
}
return disp;
}
|