When the GTK layer receives an exposure event from GDK, it first finds the !GTK_NO_WINDOW widget that corresponds to the event's window. Then, it emits the expose-event signal for that widget. As described above, that widget will first draw its background, and then ask each of its GTK_NO_WINDOW children to draw themselves.
If each of the drawing calls made by each subwidget's expose-event handler were sent directly to the windowing system, flicker could result. This is because areas may get redrawn repeatedly: the background, then decorative frames, then text labels, etc. To avoid flicker, GTK+ employs a double buffering system at the GDK level. Widgets normally don't know that they are drawing to an off-screen buffer; they just issue their normal drawing commands, and the buffer gets sent to the windowing system when all drawing operations are done.
Two basic functions in GDK form the core of the double-buffering mechanism: gdk_window_begin_paint_region() and gdk_window_end_paint(). The first function tells a GdkWindow to create a temporary off-screen buffer for drawing. All subsequent drawing operations to this window get automatically redirected to that buffer. The second function actually paints the buffer onto the on-screen window, and frees the buffer.