+ for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i)
+ {
+ if (!(i->m_vis & eWidget::wVisShow))
+ {
+ clearVisibility(i);
+ continue;
+ }
+
+ gRegion visible_before = i->m_visible_with_childs;
+
+ calcWidgetClipRegion(*i, m_screen.m_background_region);
+
+ gRegion redraw = (i->m_visible_with_childs - visible_before) | (visible_before - i->m_visible_with_childs);
+
+ redraw.moveBy(i->position());
+
+ invalidate(redraw);
+ }
+
+ gRegion redraw = (background_before - m_screen.m_background_region) | (m_screen.m_background_region - background_before);
+ invalidate(redraw);
+ } else if (m_comp_mode == cmBuffered)
+ {
+ if (!root->m_vis & eWidget::wVisShow)
+ {
+ clearVisibility(root);
+ for (int i = 0; i < MAX_LAYER; ++i)
+ removeBufferForWidget(root, i);
+ return;
+ }
+
+ for (int i = 0; i < MAX_LAYER; ++i)
+ {
+ eWidgetDesktopCompBuffer *comp = root->m_comp_buffer[i];
+
+ /* TODO: layers might not be required to have the screen size, for memory reasons. */
+ if ((i == 0 && !comp) || (comp && (root->size() != comp->m_screen_size)))
+ createBufferForWidget(root, 0);
+
+ comp = root->m_comp_buffer[i]; /* it might have changed. */
+
+ /* CHECKME: don't we need to recalculate everything? after all, our buffer has changed and is likely to be cleared */
+ gRegion visible_before = root->m_visible_with_childs;
+
+ comp->m_background_region = gRegion(eRect(comp->m_position, comp->m_screen_size));
+
+ gRegion visible_new = root->m_visible_with_childs - visible_before;
+ gRegion visible_lost = visible_before - root->m_visible_with_childs;
+ visible_new.moveBy(root->position());
+ visible_lost.moveBy(root->position());
+
+ invalidate(visible_new, root, i);
+ invalidate(visible_lost, root, i);
+
+ calcWidgetClipRegion(root, comp->m_background_region);
+ }
+ }
+}
+
+void eWidgetDesktop::invalidateWidgetLayer(const gRegion ®ion, const eWidget *widget, int layer)
+{
+ if (m_comp_mode == cmImmediate)
+ {
+ invalidate(region);
+ return;
+ }
+ eWidgetDesktopCompBuffer *comp = widget->m_comp_buffer[layer];
+ if (comp)
+ comp->m_dirty_region |= region;
+}
+
+void eWidgetDesktop::invalidateWidget(const gRegion ®ion, const eWidget *widget, int layer)
+{
+ if (m_comp_mode == cmImmediate)
+ {
+ invalidate(region);
+ return;
+ }
+
+ if (!(widget->m_vis & eWidget::wVisShow))
+ return;
+
+ gRegion mregion = region;
+ if (layer == -1)
+ for (int layer = 0; layer < MAX_LAYER; ++layer)
+ invalidateWidgetLayer(mregion, widget, layer);
+ else
+ invalidateWidgetLayer(mregion, widget, layer);
+}
+
+void eWidgetDesktop::invalidate(const gRegion ®ion, const eWidget *widget, int layer)
+{
+ if (region.empty())
+ return;
+
+ if (m_timer && !m_require_redraw)
+ m_timer->start(0, 1); // start singleshot redraw timer
+
+ m_require_redraw = 1;
+
+ if (m_comp_mode == cmImmediate)
+ {
+ /* in immediate mode, we don't care for widget and layer, we use the topmost. */
+ m_screen.m_dirty_region |= region;
+ } else
+ {
+ if (!widget)
+ for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i)
+ invalidateWidget(region, i);
+ else
+ invalidateWidget(region, widget, layer);
+ }
+}
+
+void eWidgetDesktop::setBackgroundColor(eWidgetDesktopCompBuffer *comp, gRGB col)
+{
+ comp->m_background_color = col;
+
+ /* if there's something visible from the background, redraw it with the new color. */
+ if (comp->m_dc && comp->m_background_region.valid() && !comp->m_background_region.empty())
+ {
+ /* todo: split out "setBackgroundColor / clear"... maybe? */
+ gPainter painter(comp->m_dc);
+ painter.resetClip(comp->m_background_region);
+ painter.setBackgroundColor(comp->m_background_color);
+ painter.clear();
+ }
+}
+
+void eWidgetDesktop::setBackgroundColor(gRGB col)
+{
+ setBackgroundColor(&m_screen, col);
+
+ if (m_comp_mode == cmBuffered)
+ for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i)
+ {
+ for (int l = 0; l < MAX_LAYER; ++l)
+ if (i->m_comp_buffer[l])
+ setBackgroundColor(i->m_comp_buffer[l], l ? gRGB(0, 0, 0, 0) : col); /* all layers above 0 will have a transparent background */
+ }
+}
+
+void eWidgetDesktop::setPalette(gPixmap &pm)
+{
+// if (m_comp_mode == cmImmediate)
+ {
+ ASSERT(m_screen.m_dc);
+ gPainter painter(m_screen.m_dc);
+ painter.setPalette(&pm);
+ }
+
+ if (m_comp_mode == cmBuffered)
+ {
+ for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i)
+ {
+ for (int l = 0; l < MAX_LAYER; ++l)
+ {
+ if (!i->m_comp_buffer[l])
+ continue;
+ ASSERT(i->m_comp_buffer[l]->m_dc);
+ gPainter painter(i->m_comp_buffer[l]->m_dc);
+ painter.setPalette(&pm);
+ }
+ }
+ }