Hi max, my windowing system does almost exactly as you describe. Here is the Draw() method from my top level application window. ace_buffer_create() and ace_win_update() are the key routines.
Code:
void Aw::Window::Draw(cairo_t */*cr*/)
{
//anvil_syslog(0, "Window::Draw\n");
if (!m_shown)
{
ace_win_show(m_ace_window);
m_shown = true;
}
Aw::Size size = getSize();
if (m_ace_bufferp == nullptr || m_ace_bufferp->size < size.m_width * size.m_height * sizeof(uint32_t))
{
m_ace_bufferp = ace_buffer_create(theApp->getConnection(), size.m_width * size.m_height * sizeof(uint32_t));
//anvil_syslog(0, "ace_buffer_create done %016lx\n", m_ace_bufferp);
}
m_surface = cairo_image_surface_create_for_data (
(unsigned char *)m_ace_bufferp->pixel_buf,
CAIRO_FORMAT_ARGB32,
m_width,//m_top_window->width,
m_height,//m_top_window->height,
m_width * 4);
m_cr = cairo_create(m_surface);
// Fill with our colour
const double colour = 0.8;
cairo_set_source_rgb(m_cr, colour, colour, colour);
cairo_rectangle(m_cr, 0, 0, size.m_width, size.m_height);
cairo_fill(m_cr);
drawChild(m_cr);
ace_win_update(m_ace_window, m_ace_bufferp, m_width, m_height, m_width*4);
cairo_destroy(m_cr);
cairo_surface_destroy(m_surface);
}
Note that this is just prototype code, but it works quite well and is fast enough. I will get around to improving it one day. I have built a few Apps with it including a terminal emulator and a calculator.