Skip to content

Instantly share code, notes, and snippets.

@magcius
Created August 13, 2012 19:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save magcius/3343639 to your computer and use it in GitHub Desktop.
Save magcius/3343639 to your computer and use it in GitHub Desktop.
Draw in a buffer we created ourselves
/* gcc -o drawinbuffer drawinbuffer.c $(pkg-config --cflags --libs glib-2.0 libdrm) */
#include <glib.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
int
main (int argc, char **argv)
{
int i;
int fd;
drmModeRes *resources = NULL;
drmModeConnector *connector = NULL;
drmModeEncoder *encoder = NULL;
drmModeCrtc *crtc = NULL;
struct drm_mode_create_dumb create_dumb_buffer_request = { 0 };
struct drm_mode_map_dumb map_dumb_buffer_request = { 0 };
uint32_t buffer_id = 0;
unsigned char *pixels;
fd = open ("/dev/dri/card0", O_RDWR);
if (fd < 0)
{
g_warning ("Unable to open DRI device");
exit (1);
}
resources = drmModeGetResources (fd);
/* Find the first active connector to display on. */
for (i = 0; i < resources->count_connectors; i++)
{
connector = drmModeGetConnector (fd, resources->connectors[i]);
if (connector == NULL)
continue;
if (connector->connection == DRM_MODE_CONNECTED &&
connector->count_modes > 0)
break;
drmModeFreeConnector(connector);
}
if (i == resources->count_connectors)
{
g_warning ("Could not find an active connector");
exit (1);
}
/* Find the CRTC. */
encoder = drmModeGetEncoder (fd, connector->encoder_id);
crtc = drmModeGetCrtc (fd, encoder->crtc_id);
/* Create ourselves a new buffer on the card. */
create_dumb_buffer_request.width = crtc->mode.hdisplay;
create_dumb_buffer_request.height = crtc->mode.vdisplay;
create_dumb_buffer_request.bpp = 32;
create_dumb_buffer_request.flags = 0;
if (drmIoctl (fd, DRM_IOCTL_MODE_CREATE_DUMB,
&create_dumb_buffer_request) < 0)
{
g_warning ("Could not allocate frame buffer %m");
exit (1);
}
/* Tell DRM that the buffer on the card is a framebuffer,
* and its properties. */
if (drmModeAddFB (fd,
create_dumb_buffer_request.width,
create_dumb_buffer_request.height,
24, /* depth */
create_dumb_buffer_request.bpp,
create_dumb_buffer_request.pitch,
create_dumb_buffer_request.handle,
&buffer_id) != 0)
{
g_warning ("Could not tell DRM about frame buffer %m");
exit (1);
}
/* Draw on the buffer */
map_dumb_buffer_request.handle = create_dumb_buffer_request.handle;
if (drmIoctl (fd, DRM_IOCTL_MODE_MAP_DUMB,
&map_dumb_buffer_request) < 0)
{
g_warning ("Could not map buffer %m");
exit (1);
}
pixels = mmap (0, create_dumb_buffer_request.size,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, map_dumb_buffer_request.offset);
if (pixels == MAP_FAILED)
{
g_warning ("Could not mmap buffer %m");
exit (1);
}
{
int x, y;
int stride = create_dumb_buffer_request.pitch;
/* Draw a red rectangle */
for (y = 20; y < 100; y++)
{
for (x = 20; x < 100; x++)
{
unsigned char *ptr = &pixels[y * stride + x * 4];
uint32_t *pixel = (uint32_t *) ptr;
/* ARGB */
*pixel = 0xFFFF0000;
}
}
}
/* Set the CRTC to show this buffer for five seconds. */
if (drmModeSetCrtc (fd,
crtc->crtc_id,
buffer_id,
0, 0, /* x, y */
&connector->connector_id, 1, /* connector */
&crtc->mode) != 0)
{
g_warning ("Could not set CRTC to display buffer %m");
exit (1);
}
sleep (5);
/* After five seconds, revert back to the old buffer. */
/* The CRTC structure has all the information that we
* need to revert back to the old buffer. */
if (drmModeSetCrtc (fd,
crtc->crtc_id,
crtc->buffer_id,
crtc->x,
crtc->y,
&connector->connector_id, 1, /* connector */
&crtc->mode) != 0)
{
g_warning ("Could not revert back to the old buffer");
exit (1);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment