Esempio n. 1
0
static void *
ScreenUpdateLoop( DirectThread *thread, void *arg )
{
     pthread_mutex_lock( &dfb_sdl->update.lock );

     D_DEBUG_AT( SDL_Updates, "Entering %s()...\n", __FUNCTION__ );

     while (!dfb_sdl->update.quit) {
          if (dfb_sdl->update.pending) {
               DFBRectangle update = DFB_RECTANGLE_INIT_FROM_REGION( &dfb_sdl->update.region );

               dfb_sdl->update.pending = false;

               D_DEBUG_AT( SDL_Updates, "Got update %d,%d - %dx%d...\n", DFB_RECTANGLE_VALS( &update ) );

               pthread_mutex_unlock( &dfb_sdl->update.lock );


               update_screen( update.x, update.y, update.w, update.h );


               pthread_mutex_lock( &dfb_sdl->update.lock );
          }
          else
               pthread_cond_wait( &dfb_sdl->update.cond, &dfb_sdl->update.lock );
     }

     D_DEBUG_AT( SDL_Updates, "Returning from %s()...\n", __FUNCTION__ );

     pthread_mutex_unlock( &dfb_sdl->update.lock );

     return NULL;
}
Esempio n. 2
0
void
dfb_gfx_copy_regions_stereo( CoreSurface           *source,
                             CoreSurfaceBufferRole  from,
                             DFBSurfaceStereoEye    source_eye,
                             CoreSurface           *destination,
                             CoreSurfaceBufferRole  to,
                             DFBSurfaceStereoEye    destination_eye,
                             const DFBRegion       *regions,
                             unsigned int           num,
                             int                    x,
                             int                    y )
{
     unsigned int i, n = 0;
     DFBRectangle rect = { 0, 0, source->config.size.w, source->config.size.h };
     DFBRectangle rects[num];
     DFBPoint     points[num];

     D_ASSERT( !dfb_config->task_manager );

     for (i=0; i<num; i++) {
          DFB_REGION_ASSERT( &regions[i] );

          rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( &regions[i] );

          if (dfb_rectangle_intersect( &rects[n], &rect )) {
               points[n].x = x + rects[n].x - rect.x;
               points[n].y = y + rects[n].y - rect.y;

               n++;
          }
     }

     if (n > 0) {
          StateClient *client = state_client_tls.Get();

          D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO );

          client->state.clip.x2     = destination->config.size.w - 1;
          client->state.clip.y2     = destination->config.size.h - 1;
          client->state.source      = source;
          client->state.destination = destination;
          client->state.from        = from;
          client->state.from_eye    = source_eye;
          client->state.to          = to;
          client->state.to_eye      = destination_eye;

          CoreGraphicsStateClient_Blit( &client->client, rects, points, n );

          CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_NONE );

          /* Signal end of sequence. */
          dfb_state_stop_drawing( &client->state );

          client->state.destination = NULL;
          client->state.source      = NULL;
     }
}
Esempio n. 3
0
void
dfb_gfx_copy_regions( CoreSurface           *source,
                      CoreSurfaceBufferRole  from,
                      CoreSurface           *destination,
                      CoreSurfaceBufferRole  to,
                      const DFBRegion       *regions,
                      unsigned int           num,
                      int                    x,
                      int                    y )
{
     unsigned int i, n = 0;
     DFBRectangle rect = { 0, 0, source->config.size.w, source->config.size.h };
     DFBRectangle rects[num];
     DFBPoint     points[num];

     for (i=0; i<num; i++) {
          DFB_REGION_ASSERT( &regions[i] );

          rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( &regions[i] );

          if (dfb_rectangle_intersect( &rects[n], &rect )) {
               points[n].x = x + rects[n].x - rect.x;
               points[n].y = y + rects[n].y - rect.y;

               n++;
          }
     }

     if (n > 0) {
          pthread_mutex_lock( &copy_lock );

          if (!copy_state_inited) {
               dfb_state_init( &copy_state, NULL );
               copy_state_inited = true;
          }

          copy_state.modified   |= SMF_CLIP | SMF_SOURCE | SMF_DESTINATION;

          copy_state.clip.x2     = destination->config.size.w - 1;
          copy_state.clip.y2     = destination->config.size.h - 1;
          copy_state.source      = source;
          copy_state.destination = destination;
          copy_state.from        = from;
          copy_state.to          = to;

          dfb_gfxcard_batchblit( rects, points, n, &copy_state );
     
          /* Signal end of sequence. */
          dfb_state_stop_drawing( &copy_state );

          pthread_mutex_unlock( &copy_lock );
     }
}
Esempio n. 4
0
DFBResult
dfb_x11_update_screen_handler( DFBX11 *x11, UpdateScreenData *data )
{
     DFBRectangle rect;

     D_DEBUG_AT( X11_Update, "%s( %p )\n", __FUNCTION__, data );

     rect = DFB_RECTANGLE_INIT_FROM_REGION( &data->region );

     if (data->lock)
          update_screen( x11, &rect, data->lock, data->xw );

     data->lock = NULL;

     return DFB_OK;
}
Esempio n. 5
0
static void
foo_update( StretRegion     *region,
            void            *region_data,
            void            *update_data,
            unsigned long    arg,
            int              x,
            int              y,
            const DFBRegion *updates,
            int              num )
{
     int                      i;
     DFBRegion                clip;
     DFBDimension             size;
     bool                     visible;
     WMShared                *shared;
     UniqueContext           *context;
     UniqueWindow            *window = region_data;
     CardState               *state  = update_data;
     DFBSurfaceBlittingFlags  flags  = DSBLIT_NOFX;

     D_ASSERT( region != NULL );
     D_ASSERT( region_data != NULL );
     D_ASSERT( update_data != NULL );
     D_ASSERT( updates != NULL );

     D_MAGIC_ASSERT( window, UniqueWindow );
     D_MAGIC_ASSERT( state, CardState );

     shared = window->shared;

     D_MAGIC_ASSERT( shared, WMShared );
     D_ASSERT( shared->foo_surface != NULL );

     context = window->context;

     D_MAGIC_ASSERT( context, UniqueContext );

     visible = D_FLAGS_IS_SET( window->flags, UWF_VISIBLE );

     D_DEBUG_AT( UniQuE_Foo, "foo_update( region %p, window %p, visible %s, num %d )\n",
                 region, window, visible ? "yes" : "no", num );
#if D_DEBUG_ENABLED
     for (i=0; i<num; i++) {
          D_DEBUG_AT( UniQuE_Foo, "    (%d)  %4d,%4d - %4dx%4d\n",
                      i, DFB_RECTANGLE_VALS_FROM_REGION( &updates[i] ) );
     }
#endif

     if (!visible)
          return;

     stret_region_get_size( region, &size );

     /* Use per pixel alpha blending. */
     flags |= DSBLIT_BLEND_ALPHACHANNEL;

     /* Use global alpha blending. */
     if (window->opacity != 0xFF) {
          flags |= DSBLIT_BLEND_COLORALPHA;

          /* Set opacity as blending factor. */
          if (state->color.a != window->opacity) {
               state->color.a   = window->opacity;
               state->modified |= SMF_COLOR;
          }
     }

     /* Use colorizing if the color is not white. */
     if (context->color.r != 0xff || context->color.g != 0xff || context->color.b != 0xff) {
          flags |= DSBLIT_COLORIZE;

          state->color.r = context->color.r;
          state->color.g = context->color.g;
          state->color.b = context->color.b;

          state->modified |= SMF_COLOR;
     }

     /* Set blitting flags. */
     dfb_state_set_blitting_flags( state, flags );

     /* Set blitting source. */
     state->source    = shared->foo_surface;
     state->modified |= SMF_SOURCE;

     switch (arg) {
          case UFI_N:
          case UFI_E:
          case UFI_S:
          case UFI_W:
               clip = state->clip;

/*               for (i=0; i<num; i++) {
                    DFBRegion    update = DFB_REGION_INIT_TRANSLATED( &updates[i], x, y );
                    DFBRectangle source = shared->foo_rects[arg];
                    DFBRectangle dest   = { x, y, size.w, size.h };

                    dfb_state_set_clip( state, &update );

                    dfb_gfxcard_stretchblit( &source, &dest, state );
               }*/
               for (i=0; i<num; i++) {
                    DFBRegion    update = DFB_REGION_INIT_TRANSLATED( &updates[i], x, y );
                    DFBRectangle source = shared->foo_rects[arg];

                    dfb_state_set_clip( state, &update );

                    dfb_gfxcard_tileblit( &source, x, y, x + size.w - 1, y + size.h - 1, state );
               }

               dfb_state_set_clip( state, &clip );
               break;

          case UFI_NE:
          case UFI_SE:
          case UFI_SW:
          case UFI_NW:
               for (i=0; i<num; i++) {
                    DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &updates[i] );

                    dfb_rectangle_translate( &rect, shared->foo_rects[arg].x, shared->foo_rects[arg].y );

                    dfb_gfxcard_blit( &rect, x + updates[i].x1, y + updates[i].y1, state );
               }
               break;

          default:
               D_BUG( "invalid arg" );
     }

     /* Reset blitting source. */
     state->source    = NULL;
     state->modified |= SMF_SOURCE;
}
Esempio n. 6
0
/* HACK: implementation dumped in here for now, will move into context */
static DFBResult
wm_update_cursor( CoreWindowStack       *stack,
                  void                  *wm_data,
                  void                  *stack_data,
                  CoreCursorUpdateFlags  flags )
{
     DFBResult         ret;
     DFBRegion         old_region;
     WMData           *wmdata   = wm_data;
     StackData        *data     = stack_data;
     bool              restored = false;
     CoreLayer        *layer;
     CoreLayerRegion  *region;
     CardState        *state;
     CoreSurface      *surface;
     UniqueContext    *context;

     D_ASSERT( stack != NULL );
     D_ASSERT( stack->context != NULL );
     D_ASSERT( wm_data != NULL );
     D_ASSERT( stack_data != NULL );

     D_MAGIC_ASSERT( data, StackData );

     context = data->context;

     D_MAGIC_ASSERT( context, UniqueContext );

     /* Optimize case of invisible cursor moving. */
     if (!(flags & ~(CCUF_POSITION | CCUF_SHAPE)) && (!stack->cursor.opacity || !stack->cursor.enabled)) {
          context->cursor_bs_valid = false;
          return DFB_OK;
     }

     layer   = dfb_layer_at( context->layer_id );
     state   = &layer->state;
     region  = context->region;
     surface = context->surface;

     D_ASSERT( region != NULL );
     D_ASSERT( surface != NULL );

     if (flags & CCUF_ENABLE) {
          CoreSurface            *cursor_bs;
          DFBSurfaceCapabilities  caps = DSCAPS_NONE;

          dfb_surface_caps_apply_policy( stack->cursor.policy, &caps );

          D_ASSERT( context->cursor_bs == NULL );

          /* Create the cursor backing store surface. */
          ret = dfb_surface_create_simple( wmdata->core, stack->cursor.size.w, stack->cursor.size.h,
                                           region->config.format, region->config.colorspace, 
                                           caps, CSTF_SHARED | CSTF_CURSOR,
                                           0, /* FIXME: no shared cursor objects, no cursor id */
                                           NULL, &cursor_bs );
          if (ret) {
               D_ERROR( "WM/Default: Failed creating backing store for cursor!\n" );
               return ret;
          }

          ret = dfb_surface_globalize( cursor_bs );
          D_ASSERT( ret == DFB_OK );

          /* Ensure valid back buffer for now.
           * FIXME: Keep a flag to know when back/front have been swapped and need a sync.
           */
          switch (region->config.buffermode) {
               case DLBM_BACKVIDEO:
               case DLBM_TRIPLE:
                    dfb_gfx_copy( surface, surface, NULL );
                    break;

               default:
                    break;
          }

          context->cursor_bs = cursor_bs;
     }
     else {
          D_ASSERT( context->cursor_bs != NULL );

          /* restore region under cursor */
          if (context->cursor_drawn) {
               DFBRectangle rect = { 0, 0,
                                     context->cursor_region.x2 - context->cursor_region.x1 + 1,
                                     context->cursor_region.y2 - context->cursor_region.y1 + 1 };

               D_ASSERT( stack->cursor.opacity || (flags & CCUF_OPACITY) );
               D_ASSERT( context->cursor_bs_valid );

               dfb_gfx_copy_to( context->cursor_bs, surface, &rect,
                                context->cursor_region.x1, context->cursor_region.y1, false );

               context->cursor_drawn = false;

               old_region = context->cursor_region;
               restored   = true;
          }

          if (flags & CCUF_SIZE) {
               ret = dfb_surface_reformat( context->cursor_bs,
                                           stack->cursor.size.w, stack->cursor.size.h,
                                           context->cursor_bs->config.format );
               if (ret) {
                    D_ERROR( "WM/Default: Failed resizing backing store for cursor!\n" );
                    return ret;
               }
          }
     }

     if (flags & (CCUF_ENABLE | CCUF_POSITION | CCUF_SIZE | CCUF_OPACITY)) {
          context->cursor_bs_valid  = false;

          context->cursor_region.x1 = stack->cursor.x - stack->cursor.hot.x;
          context->cursor_region.y1 = stack->cursor.y - stack->cursor.hot.y;
          context->cursor_region.x2 = context->cursor_region.x1 + stack->cursor.size.w - 1;
          context->cursor_region.y2 = context->cursor_region.y1 + stack->cursor.size.h - 1;

          if (!dfb_region_intersect( &context->cursor_region, 0, 0, stack->width - 1, stack->height - 1 )) {
               D_BUG( "invalid cursor region" );
               return DFB_BUG;
          }
     }

     D_ASSERT( context->cursor_bs != NULL );

     if (flags & CCUF_DISABLE) {
          dfb_surface_unlink( &context->cursor_bs );
     }
     else if (stack->cursor.opacity) {
          /* backup region under cursor */
          if (!context->cursor_bs_valid) {
               DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &context->cursor_region );

               D_ASSERT( !context->cursor_drawn );

               /* FIXME: this requires using blitted flipping all the time,
                  but fixing it seems impossible, for now DSFLIP_BLIT is forced
                  in repaint_stack() when the cursor is enabled. */
               dfb_gfx_copy_to( surface, context->cursor_bs, &rect, 0, 0, true );

               context->cursor_bs_valid = true;
          }

          /* Set destination. */
          state->destination  = surface;
          state->modified    |= SMF_DESTINATION;

          /* Set clipping region. */
          dfb_state_set_clip( state, &context->cursor_region );

          /* draw cursor */
          unique_draw_cursor( stack, context, state, &context->cursor_region );

          /* Reset destination. */
          state->destination  = NULL;
          state->modified    |= SMF_DESTINATION;

          context->cursor_drawn = true;

          if (restored) {
               if (dfb_region_region_intersects( &old_region, &context->cursor_region ))
                    dfb_region_region_union( &old_region, &context->cursor_region );
               else
                    dfb_layer_region_flip_update( region, &context->cursor_region, DSFLIP_BLIT );

               dfb_layer_region_flip_update( region, &old_region, DSFLIP_BLIT );
          }
          else
               dfb_layer_region_flip_update( region, &context->cursor_region, DSFLIP_BLIT );
     }
     else if (restored)
          dfb_layer_region_flip_update( region, &old_region, DSFLIP_BLIT );

     return DFB_OK;
}
Esempio n. 7
0
static void
root_update( StretRegion     *region,
             void            *region_data,
             void            *update_data,
             unsigned long    arg,
             int              x,
             int              y,
             const DFBRegion *updates,
             int              num )
{
     int              i;
     CoreWindowStack *stack;
     UniqueContext   *context = region_data;
     CardState       *state   = update_data;

     D_ASSERT( region != NULL );
     D_ASSERT( region_data != NULL );
     D_ASSERT( update_data != NULL );
     D_ASSERT( updates != NULL );

     D_ASSERT( x == 0 );
     D_ASSERT( y == 0 );

     D_MAGIC_ASSERT( context, UniqueContext );
     D_MAGIC_ASSERT( state, CardState );

     stack = context->stack;

     D_ASSERT( stack != NULL );
     D_ASSERT( stack->bg.image != NULL || (stack->bg.mode != DLBM_IMAGE &&
                                           stack->bg.mode != DLBM_TILE) );

     D_DEBUG_AT( UniQuE_Root, "root_update( region %p, num %d )\n", region, num );
#if D_DEBUG_ENABLED
     for (i=0; i<num; i++) {
          D_DEBUG_AT( UniQuE_Root, "    (%d)  %4d,%4d - %4dx%4d\n",
                      i, DFB_RECTANGLE_VALS_FROM_REGION( &updates[i] ) );
     }
#endif

     switch (stack->bg.mode) {
          case DLBM_COLOR: {
               CoreSurface *dest  = state->destination;
               DFBColor    *color = &stack->bg.color;
               DFBRectangle rects[num];

               /* Set the background color. */
               if (DFB_PIXELFORMAT_IS_INDEXED( dest->config.format ))
                    dfb_state_set_color_index( state,
                                               dfb_palette_search( dest->palette, color->r,
                                                                   color->g, color->b, color->a ) );
               else
                    dfb_state_set_color( state, color );

               for (i=0; i<num; i++)
                    dfb_rectangle_from_region( &rects[i], &updates[i] );

               /* Simply fill the background. */
               dfb_gfxcard_fillrectangles( rects, num, state );

               break;
          }

          case DLBM_IMAGE: {
               CoreSurface *bg = stack->bg.image;

               /* Set blitting source. */
               state->source    = bg;
               state->modified |= SMF_SOURCE;

               /* Set blitting flags. */
               dfb_state_set_blitting_flags( state, DSBLIT_NOFX );

               /* Check the size of the background image. */
               if (bg->config.size.w == stack->width && bg->config.size.h == stack->height) {
                    for (i=0; i<num; i++) {
                         DFBRectangle dst = DFB_RECTANGLE_INIT_FROM_REGION( &updates[i] );

                         /* Simple blit for 100% fitting background image. */
                         dfb_gfxcard_blit( &dst, dst.x, dst.y, state );
                    }
               }
               else {
                    DFBRegion clip = state->clip;

                    for (i=0; i<num; i++) {
                         DFBRectangle src = { 0, 0, bg->config.size.w, bg->config.size.h };
                         DFBRectangle dst = { 0, 0, stack->width, stack->height };

                         /* Change clipping region. */
                         dfb_state_set_clip( state, &updates[i] );

                         /* Stretch blit for non fitting background images. */
                         dfb_gfxcard_stretchblit( &src, &dst, state );
                    }

                    /* Restore clipping region. */
                    dfb_state_set_clip( state, &clip );
               }

               /* Reset blitting source. */
               state->source    = NULL;
               state->modified |= SMF_SOURCE;

               break;
          }

          case DLBM_TILE: {
               CoreSurface  *bg   = stack->bg.image;
               DFBRegion     clip = state->clip;

               /* Set blitting source. */
               state->source    = bg;
               state->modified |= SMF_SOURCE;

               /* Set blitting flags. */
               dfb_state_set_blitting_flags( state, DSBLIT_NOFX );

               for (i=0; i<num; i++) {
                    DFBRectangle src = { 0, 0, bg->config.size.w, bg->config.size.h };

                    /* Change clipping region. */
                    dfb_state_set_clip( state, &updates[i] );

                    /* Tiled blit (aligned). */
                    dfb_gfxcard_tileblit( &src, 0, 0, stack->width, stack->height, state );
               }

               /* Restore clipping region. */
               dfb_state_set_clip( state, &clip );

               /* Reset blitting source. */
               state->source    = NULL;
               state->modified |= SMF_SOURCE;

               break;
          }

          case DLBM_DONTCARE:
               break;

          default:
               D_BUG( "unknown background mode" );
               break;
     }
}
Esempio n. 8
0
void
dfb_gfx_copy_regions_client( CoreSurface             *source,
                             CoreSurfaceBufferRole    from,
                             DFBSurfaceStereoEye      source_eye,
                             CoreSurface             *destination,
                             CoreSurfaceBufferRole    to,
                             DFBSurfaceStereoEye      destination_eye,
                             const DFBRegion         *regions,
                             unsigned int             num,
                             int                      x,
                             int                      y,
                             CoreGraphicsStateClient *_client )
{
     unsigned int             i, n = 0;
     DFBRectangle             rect = { 0, 0, source->config.size.w, source->config.size.h };
     DFBRectangle             rects[num];
     DFBPoint                 points[num];
     CoreGraphicsStateClient *client = _client ? _client : &state_client_tls.Get()->client;
     CardState               *state  = client->state;
     CardState                backup;

     for (i=0; i<num; i++) {
          DFB_REGION_ASSERT( &regions[i] );

          rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( &regions[i] );

          if (dfb_rectangle_intersect( &rects[n], &rect )) {
               points[n].x = x + rects[n].x;
               points[n].y = y + rects[n].y;

               n++;
          }
     }

     if (n > 0) {
          backup.clip          = state->clip;
          backup.source        = state->source;
          backup.destination   = state->destination;
          backup.from          = state->from;
          backup.from_eye      = state->from_eye;
          backup.to            = state->to;
          backup.to_eye        = state->to_eye;
          backup.blittingflags = state->blittingflags;


          D_FLAGS_SET( state->modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO | SMF_BLITTING_FLAGS );

          state->clip.x1     = 0;
          state->clip.y1     = 0;
          state->clip.x2     = destination->config.size.w - 1;
          state->clip.y2     = destination->config.size.h - 1;
          state->source      = source;
          state->destination = destination;
          state->from        = from;
          state->from_eye    = source_eye;
          state->to          = to;
          state->to_eye      = destination_eye;
          state->blittingflags = DSBLIT_NOFX;

          CoreGraphicsStateClient_Blit( client, rects, points, n );

          if (!_client)
               CoreGraphicsStateClient_Flush( client, 0, CGSCFF_NONE );

          D_FLAGS_SET( state->modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO | SMF_BLITTING_FLAGS );

          state->clip          = backup.clip;
          state->source        = backup.source;
          state->destination   = backup.destination;
          state->from          = backup.from;
          state->from_eye      = backup.from_eye;
          state->to            = backup.to;
          state->to_eye        = backup.to_eye;
          state->blittingflags = backup.blittingflags;
     }
}
Esempio n. 9
0
static void
window_update( StretRegion     *region,
               void            *region_data,
               void            *update_data,
               unsigned long    arg,
               int              x,
               int              y,
               const DFBRegion *updates,
               int              num )
{
     int                      i;
     DFBSurfaceBlittingFlags  flags  = DSBLIT_NOFX;
     UniqueWindow            *window = region_data;
     CardState               *state  = update_data;
     bool                     alpha  = arg;
     bool                     visible;

     D_ASSERT( updates != NULL );

     D_MAGIC_ASSERT( region, StretRegion );
     D_MAGIC_ASSERT( window, UniqueWindow );
     D_MAGIC_ASSERT( state, CardState );

     D_ASSERT( window->surface != NULL );

     visible = D_FLAGS_IS_SET( window->flags, UWF_VISIBLE );

     D_DEBUG_AT( UniQuE_Window, "window_update( region %p, window %p, visible %s, num %d )\n",
                 region, window, visible ? "yes" : "no", num );
#if D_DEBUG_ENABLED
     for (i=0; i<num; i++) {
          D_DEBUG_AT( UniQuE_Window, "    (%d)  %4d,%4d - %4dx%4d\n",
                      i, DFB_RECTANGLE_VALS_FROM_REGION( &updates[i] ) );
     }
#endif

     if (!visible)
          return;

     /* Use per pixel alpha blending. */
     if (alpha && (window->options & DWOP_ALPHACHANNEL))
          flags |= DSBLIT_BLEND_ALPHACHANNEL;

     /* Use global alpha blending. */
     if (window->opacity != 0xFF) {
          flags |= DSBLIT_BLEND_COLORALPHA;

          /* Set opacity as blending factor. */
          if (state->color.a != window->opacity) {
               state->color.a   = window->opacity;
               state->modified |= SMF_COLOR;
          }
     }

     /* Use source color keying. */
     if (window->options & DWOP_COLORKEYING) {
          flags |= DSBLIT_SRC_COLORKEY;

          /* Set window color key. */
          dfb_state_set_src_colorkey( state, window->color_key );
     }

     /* Use automatic deinterlacing. */
     if (window->surface->config.caps & DSCAPS_INTERLACED)
          flags |= DSBLIT_DEINTERLACE;

     /* Set blitting flags. */
     dfb_state_set_blitting_flags( state, flags );

     /* Set blitting source. */
     state->source    = window->surface;
     state->modified |= SMF_SOURCE;

     for (i=0; i<num; i++) {
          DFBRectangle src = DFB_RECTANGLE_INIT_FROM_REGION( &updates[i] );

          /* Blit from the window to the region being updated. */
          dfb_gfxcard_blit( &src, x + src.x, y + src.y, state );
     }

     /* Reset blitting source. */
     state->source    = NULL;
     state->modified |= SMF_SOURCE;
}