Fortunate, the disko provides its own surface which can be work with the cairo. This can be seen in its flash support. The createSurface can be used to create a directfb surface.
this->window->getLayer()->createSurface(&(this->flash_temp_surface), this->width, this->height, MMSFB_PF_ARGB, 0);
Then, we can use lock to acquire the framebuffer from the directfb.
this->flash_temp_surface->lock(MMSFB_LOCK_WRITE, &ptr, &pitch);
this->flash_temp_surface->unlock();
Then we can use cairo_image_surface_create_for_data to create a cairo surface from this buffer.
this->cairosurface = cairo_image_surface_create_for_data((unsigned char*)ptr, CAIRO_FORMAT_ARGB32,
this->width, this->height, pitch);
Finally, a cairo instance is created with this cairo surface
this->cairo = cairo_create((cairo_surface_t *)cairosurface);
In this way, we create a cairo surface on top of the directfb framebuffer. All remaining cairo operation is applied against this surface. By this way, we can not enjoy the acceleration provided by a direct DFB integration. However, it's good enough for non-accelerated platform.
The madbutterfly can be implemented in the same way. If the acceleration is required, we should create a cairo surface directly from the cairo directfb backend. In this way, we can create a cairo directfb surface and use the window cliping to limit its drawing area to be within the window.