Ejemplo n.º 1
0
bool
dfb_unsafe_region_intersect( DFBRegion *region,
                             int x1, int y1, int x2, int y2 )
{
     if (region->x1 > region->x2) {
          int temp = region->x1;
          region->x1 = region->x2;
          region->x2 = temp;
     }

     if (region->y1 > region->y2) {
          int temp = region->y1;
          region->y1 = region->y2;
          region->y2 = temp;
     }

     return dfb_region_intersect( region, x1, y1, x2, y2 );
}
Ejemplo n.º 2
0
static void
repaint_stack( CoreWindowStack     *stack,
               DFBRegion           *region,
               DFBSurfaceFlipFlags  flags )
{
     DisplayLayer *layer   = dfb_layer_at( stack->layer_id );
     CoreSurface  *surface = dfb_layer_surface( layer );
     CardState    *state   = dfb_layer_state( layer );

     if (!dfb_region_intersect( region, 0, 0,
                                surface->width - 1, surface->height - 1 ))
          return;

     if (dfb_layer_lease( layer ))
          return;

     state->clip      = *region;
     state->modified |= SMF_CLIP;

     update_region( stack, state, stack->num_windows - 1,
                    region->x1, region->y1, region->x2, region->y2 );

     if (surface->caps & DSCAPS_FLIPPING) {
          if (region->x1 == 0 &&
              region->y1 == 0 &&
              region->x2 == surface->width - 1 &&
              region->y2 == surface->height - 1 && 0)
          {
               dfb_layer_flip_buffers( layer, flags );
          }
          else {
               DFBRectangle rect = { region->x1, region->y1,
                                     region->x2 - region->x1 + 1,
                                     region->y2 - region->y1 + 1 };

               if (flags & DSFLIP_WAITFORSYNC)
                    dfb_fbdev_wait_vsync();
               
               dfb_back_to_front_copy( surface, &rect );
          }
     }

     dfb_layer_release( layer, false );
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
static void
update_region( CoreWindowStack *stack,
               CardState       *state,
               int              start,
               int              x1,
               int              y1,
               int              x2,
               int              y2 )
{
     int       i      = start;
     DFBRegion region = { x1, y1, x2, y2 };

     /* check for empty region */
     DFB_ASSERT (x1 <= x2  &&  y1 <= y2);

     while (i >= 0) {
          if (VISIBLE_WINDOW(stack->windows[i])) {
               int       wx2    = stack->windows[i]->x +
                                  stack->windows[i]->width - 1;
               int       wy2    = stack->windows[i]->y +
                                  stack->windows[i]->height - 1;

               if (dfb_region_intersect( &region, stack->windows[i]->x,
                                         stack->windows[i]->y, wx2, wy2 ))
                    break;
          }

          i--;
     }

     if (i >= 0) {
          if (TRANSLUCENT_WINDOW(stack->windows[i]))
               update_region( stack, state, i-1, x1, y1, x2, y2 );
          else {
               /* left */
               if (region.x1 != x1)
                    update_region( stack, state, i-1, x1, region.y1, region.x1-1, region.y2 );

               /* upper */
               if (region.y1 != y1)
                    update_region( stack, state, i-1, x1, y1, x2, region.y1-1 );

               /* right */
               if (region.x2 != x2)
                    update_region( stack, state, i-1, region.x2+1, region.y1, x2, region.y2 );

               /* lower */
               if (region.y2 != y2)
                    update_region( stack, state, i-1, x1, region.y2+1, x2, y2 );
          }

          {
               CoreWindow              *window = stack->windows[i];
               DFBSurfaceBlittingFlags  flags  = DSBLIT_NOFX;
               DFBRectangle             srect  = { region.x1 - window->x,
                                                   region.y1 - window->y,
                                                   region.x2 - region.x1 + 1,
                                                   region.y2 - region.y1 + 1 };

               if (window->options & DWOP_ALPHACHANNEL)
                    flags |= DSBLIT_BLEND_ALPHACHANNEL;

               if (window->opacity != 0xFF) {
                    flags |= DSBLIT_BLEND_COLORALPHA;

                    if (state->color.a != window->opacity) {
                         state->color.a = window->opacity;
                         state->modified |= SMF_COLOR;
                    }
               }

               if (window->options & DWOP_COLORKEYING) {
                    flags |= DSBLIT_SRC_COLORKEY;

                    if (state->src_colorkey != window->color_key) {
                         state->src_colorkey = window->color_key;
                         state->modified |= SMF_SRC_COLORKEY;
                    }
               }

               if (state->blittingflags != flags) {
                    state->blittingflags  = flags;
                    state->modified      |= SMF_BLITTING_FLAGS;
               }

               state->source    = window->surface;
               state->modified |= SMF_SOURCE;

               dfb_gfxcard_blit( &srect, region.x1, region.y1, state );

               state->source = NULL;
          }
     }
     else {
          switch (stack->bg.mode) {
               case DLBM_COLOR: {
                    DFBRectangle rect = { x1, y1, x2 - x1 + 1, y2 - y1 + 1 };

                    state->color     = stack->bg.color;
                    state->modified |= SMF_COLOR;

                    dfb_gfxcard_fillrectangle( &rect, state );
                    break;
               }
               case DLBM_IMAGE: {
                    DFBRectangle rect = { x1, y1, x2 - x1 + 1, y2 - y1 + 1 };

                    if (state->blittingflags != DSBLIT_NOFX) {
                         state->blittingflags  = DSBLIT_NOFX;
                         state->modified      |= SMF_BLITTING_FLAGS;
                    }

                    state->source    = stack->bg.image;
                    state->modified |= SMF_SOURCE;

                    dfb_gfxcard_blit( &rect, x1, y1, state );
                    
                    state->source = NULL;
                    break;
               }
               case DLBM_TILE: {
                    DFBRectangle rect = { 0, 0,
                                          stack->bg.image->width,
                                          stack->bg.image->height };

                    if (state->blittingflags != DSBLIT_NOFX) {
                         state->blittingflags  = DSBLIT_NOFX;
                         state->modified      |= SMF_BLITTING_FLAGS;
                    }

                    state->source    = stack->bg.image;
                    state->modified |= SMF_SOURCE;

                    dfb_gfxcard_tileblit( &rect,
                                          (x1 / rect.w) * rect.w,
                                          (y1 / rect.h) * rect.h,
                                          (x2 / rect.w + 1) * rect.w,
                                          (y2 / rect.h + 1) * rect.h,
                                          state );
                    
                    state->source = NULL;
                    break;
               }
               default:
                    ;
          }
     }
}