#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include #include #include #include #include #include int main() { int err; const int fd = open("/dev/dri/card1", O_RDWR | O_CLOEXEC); assert(fd != -1); drmModeRes *res = drmModeGetResources(fd); assert(res != nullptr); drmModeConnector *conn = drmModeGetConnector(fd, res->connectors[0]); assert(conn != nullptr); drmModeModeInfo mode = conn->modes[0]; uint32_t conn_id = conn->connector_id; struct drm_mode_create_dumb create_req = { .width = mode.hdisplay, .height = mode.vdisplay, .bpp = 32, }; err = ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_req); assert(err != -1); uint32_t fb_id; err = drmModeAddFB( fd, create_req.width, create_req.height, 24, 32, create_req.pitch, create_req.handle, &fb_id); assert(err == 0); err = drmModeSetCrtc(fd, res->crtcs[0], fb_id, 0, 0, &conn_id, 1, &mode); assert(err == 0); drmModeCrtc *crtc = drmModeGetCrtc(fd, res->crtcs[0]); assert(crtc != nullptr); struct drm_mode_map_dumb map_req = { .handle = create_req.handle }; err = ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map_req); assert(err != -1); uint32_t *const fb = mmap( 0, create_req.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map_req.offset); assert(fb != MAP_FAILED); for (int y = 0; y < mode.vdisplay; ++y) { for (int x = 0; x < mode.hdisplay; ++x) { const uint8_t r = (x * 255) / mode.hdisplay; const uint8_t g = (y * 255) / mode.vdisplay; const uint8_t b = 128; fb[y * (create_req.pitch / 4) + x] = (r << 16) | (g << 8) | b; } } getchar(); munmap(fb, create_req.size); struct drm_mode_destroy_dumb delete_req = { .handle = create_req.handle }; ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &delete_req); drmModeSetCrtc( fd, crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, &conn_id, 1, &crtc->mode); drmModeFreeCrtc(crtc); drmModeFreeConnector(conn); drmModeFreeResources(res); close(fd); return 0; }