+ /* tell registered root windows that they no longer have a desktop. */
+ for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); )
+ {
+ i->m_desktop = 0;
+ i = m_root.erase(i);
+ }
+ /* destroy all buffers */
+ setCompositionMode(-1);
+}
+
+void eWidgetDesktop::createBufferForWidget(eWidget *widget, int layer)
+{
+ removeBufferForWidget(widget, layer);
+
+ eWidgetDesktopCompBuffer *comp = widget->m_comp_buffer[layer] = new eWidgetDesktopCompBuffer;
+
+ eDebug("create buffer for widget layer %d, %d x %d\n", layer, widget->size().width(), widget->size().height());
+
+ eRect bbox = eRect(widget->position(), widget->size());
+ comp->m_position = bbox.topLeft();
+ comp->m_dirty_region = gRegion(eRect(ePoint(0, 0), bbox.size()));
+ comp->m_screen_size = bbox.size();
+ /* TODO: configurable bit depth. */
+
+ /* clone palette. FIXME. */
+ ePtr<gPixmap> pm = new gPixmap(comp->m_screen_size, 32, 1), pm_screen;
+ pm->surface->clut.data = new gRGB[256];
+ pm->surface->clut.colors = 256;
+ pm->surface->clut.start = 0;
+
+ m_screen.m_dc->getPixmap(pm_screen);
+
+ memcpy(pm->surface->clut.data, pm_screen->surface->clut.data, 256 * sizeof(gRGB));
+
+ comp->m_dc = new gDC(pm);
+}
+
+void eWidgetDesktop::removeBufferForWidget(eWidget *widget, int layer)
+{
+ if (widget->m_comp_buffer[layer])
+ {
+ delete widget->m_comp_buffer[layer];
+ widget->m_comp_buffer[layer] = 0;
+ }
+}
+
+void eWidgetDesktop::redrawComposition(int notified)
+{
+ if (m_comp_mode != cmBuffered)
+ return;
+
+ ASSERT(m_screen.m_dc);
+
+ gPainter p(m_screen.m_dc);
+ p.resetClip(eRect(ePoint(0, 0), m_screen.m_screen_size));
+ p.setBackgroundColor(m_screen.m_background_color);
+ p.clear();
+
+ for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i)
+ {
+ if (!i->isVisible())
+ continue;
+ for (int layer = 0; layer < MAX_LAYER; ++layer)
+ {
+ ePtr<gPixmap> pm;
+ if (!i->m_comp_buffer[layer])
+ continue;
+ i->m_comp_buffer[layer]->m_dc->getPixmap(pm);
+ p.blit(pm, i->m_comp_buffer[layer]->m_position, eRect(), gPixmap::blitAlphaBlend);
+ }
+ }
+
+ // flip activates on next vsync.
+ p.flip();
+ p.waitVSync();
+
+ if (notified)
+ p.notify();
+
+ for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i)
+ if (i->m_animation.m_active)
+ i->m_animation.tick(1);
+}
+
+void eWidgetDesktop::notify()
+{
+ redrawComposition(1);
+}
+
+void eWidgetDesktop::clearVisibility(eWidget *widget)
+{
+ widget->m_visible_with_childs = gRegion();
+ for (ePtrList<eWidget>::iterator i(widget->m_childs.begin()); i != widget->m_childs.end(); ++i)
+ clearVisibility(*i);