#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include struct buffer_object { uint32_t width; uint32_t height; uint32_t pitch; uint32_t handle; uint32_t size; uint32_t *vaddr; uint32_t fb_id; }; struct buffer_object buf[3]; static int modeset_create_fb(int fd, struct buffer_object *bo, uint32_t color) { struct drm_mode_create_dumb create = { }; struct drm_mode_map_dumb map = { }; uint32_t i; create.width = bo->width; create.height = bo->height; create.bpp = 32; drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create); bo->pitch = create.pitch; bo->size = create.size; bo->handle = create.handle; drmModeAddFB(fd, bo->width, bo->height, 24, 32, bo->pitch, bo->handle, &bo->fb_id); map.handle = create.handle; drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map); bo->vaddr = mmap(0, create.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map.offset); for (i = 0; i < (bo->size / 4); i++) bo->vaddr[i] = color; return 0; } static void modeset_destroy_fb(int fd, struct buffer_object *bo) { struct drm_mode_destroy_dumb destroy = { }; drmModeRmFB(fd, bo->fb_id); munmap(bo->vaddr, bo->size); destroy.handle = bo->handle; drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy); } int main(int argc, char **argv) { char *dri_card="/dev/dri/card0"; int fd; uint32_t conn_id; uint32_t crtc_id; drmModeConnector *conn; drmModeRes *res; if( argc != 2 ) { printf("Usage: %s /dev/dri/card0\n", argv[0]); return 1; } else { dri_card = argv[1]; } fd = open(dri_card, O_RDWR | O_CLOEXEC); if( fd < 0) { printf("Open '%s' failure: %s\n", dri_card, strerror(errno)); return 0; } res = drmModeGetResources(fd); if( !res ) { printf("drmModeGetResources() failure\n"); return 0; } crtc_id = res->crtcs[0]; conn_id = res->connectors[0]; conn = drmModeGetConnector(fd, conn_id); if( !conn ) { printf("drmModeGetConnector() failure\n"); return 0; } buf[0].width = conn->modes[0].hdisplay; buf[0].height = conn->modes[0].vdisplay; buf[1].width = conn->modes[0].hdisplay; buf[1].height = conn->modes[0].vdisplay; buf[2].width = conn->modes[0].hdisplay; buf[2].height = conn->modes[0].vdisplay; printf("DRM create framebuffer now.\n"); modeset_create_fb(fd, &buf[0], 0xff0000); modeset_create_fb(fd, &buf[1], 0x00ff00); modeset_create_fb(fd, &buf[2], 0x0000ff); printf("Show red screen on LCD.\n"); drmModeSetCrtc(fd, crtc_id, buf[0].fb_id, 0, 0, &conn_id, 1, &conn->modes[0]); getchar(); printf("Show green screen on LCD.\n"); drmModeSetCrtc(fd, crtc_id, buf[1].fb_id, 0, 0, &conn_id, 1, &conn->modes[0]); getchar(); printf("Show blue screen on LCD.\n"); drmModeSetCrtc(fd, crtc_id, buf[2].fb_id, 0, 0, &conn_id, 1, &conn->modes[0]); getchar(); printf("DRM destroy framebuffer now.\n"); modeset_destroy_fb(fd, &buf[0]); modeset_destroy_fb(fd, &buf[1]); modeset_destroy_fb(fd, &buf[2]); drmModeFreeConnector(conn); return 0; drmModeFreeResources(res); close(fd); return 0; }