예제 #1
0
파일: x11input.c 프로젝트: kuii/dfbNEON
static void
handle_expose( const XExposeEvent *expose )
{
     CoreLayer               *layer = 0;
     const DisplayLayerFuncs *funcs = 0;
     CoreLayerContext        *context;
     int                      i;

     /* find the correct layer */
     for( i=0; i<dfb_layer_num(); i++ ) {
          X11LayerData *lds;

          layer = dfb_layer_at( i );
          lds   = (X11LayerData*)(layer->layer_data);
          if( lds->xw && (lds->xw->window == expose->window) )
               break;
     }

     /* layer not found? */
     if( i==dfb_layer_num() )
          return;

     funcs = layer->funcs;

     D_ASSERT( funcs != NULL );
     D_ASSERT( funcs->UpdateRegion != NULL );

     /* Get the currently active context. */
     if (dfb_layer_get_active_context( layer, &context ) == DFB_OK) {
          CoreLayerRegion *region;

          /* Get the first region. */
          if (dfb_layer_context_get_primary_region( context,
                                                    false, &region ) == DFB_OK)
          {
               /* Lock the region to avoid tearing due to concurrent updates. */
               dfb_layer_region_lock( region );

               /* Get the surface of the region. */
               if (region->surface && region->left_buffer_lock.buffer) {
                    DFBRegion update = { expose->x, expose->y,
                                         expose->x + expose->width  - 1,
                                         expose->y + expose->height - 1 };

                    funcs->UpdateRegion( layer, layer->driver_data, layer->layer_data,
                                         region->region_data, region->surface, &update, &region->left_buffer_lock, NULL, NULL );
               }

               /* Unlock the region. */
               dfb_layer_region_unlock( region );

               /* Release the region. */
               dfb_layer_region_unref( region );
          }

          /* Release the context. */
          dfb_layer_context_unref( context );
     }
}
DFBResult
IDirectFBSurface_Layer_Construct( IDirectFBSurface       *thiz,
                                  IDirectFBSurface       *parent,
                                  DFBRectangle           *wanted,
                                  DFBRectangle           *granted,
                                  CoreLayerRegion        *region,
                                  DFBSurfaceCapabilities  caps,
                                  CoreDFB                *core )
{
     DFBResult    ret;
     CoreSurface *surface;

     DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBSurface_Layer);

     D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );

     if (dfb_layer_region_ref( region ))
          return DFB_FUSION;

     ret = dfb_layer_region_get_surface( region, &surface );
     if (ret) {
          dfb_layer_region_unref( region );
          DIRECT_DEALLOCATE_INTERFACE(thiz);
          return ret;
     }

     ret = IDirectFBSurface_Construct( thiz, parent, wanted, granted, NULL,
                                       surface, surface->config.caps | caps, core );
     if (ret) {
          dfb_surface_unref( surface );
          dfb_layer_region_unref( region );
          return ret;
     }

     dfb_surface_unref( surface );

     data->region = region;

     thiz->Release       = IDirectFBSurface_Layer_Release;
     thiz->Flip          = IDirectFBSurface_Layer_Flip;
     thiz->GetSubSurface = IDirectFBSurface_Layer_GetSubSurface;

     return DFB_OK;
}
static void
IDirectFBSurface_Layer_Destruct( IDirectFBSurface *thiz )
{
     IDirectFBSurface_Layer_data *data = (IDirectFBSurface_Layer_data*) thiz->priv;

     D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );

     dfb_layer_region_unref( data->region );
     IDirectFBSurface_Destruct( thiz );
}
예제 #4
0
static DFBResult
IDirectFBDisplayLayer_GetSurface( IDirectFBDisplayLayer  *thiz,
                                  IDirectFBSurface      **interface )
{
     DFBResult         ret;
     CoreLayerRegion  *region;
     IDirectFBSurface *surface;

     D_DEBUG_AT( Layer, "%s( %p )\n", __FUNCTION__, thiz );

     DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)

     if (!interface)
          return DFB_INVARG;

     if (data->level == DLSCL_SHARED) {
          D_WARN( "letting unprivileged IDirectFBDisplayLayer::GetSurface() "
                   "call pass until cooperative level handling is finished" );
     }

     ret = CoreLayerContext_GetPrimaryRegion( data->context, true, &region );
     if (ret)
          return ret;

     DIRECT_ALLOCATE_INTERFACE( surface, IDirectFBSurface );

     ret = IDirectFBSurface_Layer_Construct( surface, NULL, NULL, NULL,
                                             region, DSCAPS_NONE, data->core, data->idirectfb );

     // Fix to only perform single buffered clearing using a background when
     // configured to do so AND the display layer region is frozen.  Also
     // added support for this behavior when the cooperative level is
     // DLSCL_ADMINISTRATIVE.
     if (region->config.buffermode == DLBM_FRONTONLY &&
         data->level != DLSCL_SHARED &&
         D_FLAGS_IS_SET( region->state, CLRSF_FROZEN )) {
          // If a window stack is available, give it the opportunity to
          // render the background (optionally based on configuration) and
          // flip the display layer so it is visible.  Otherwise, just
          // directly flip the display layer and make it visible.
          if (data->stack) {
               CoreWindowStack_RepaintAll( data->stack );
          }
          else {
               CoreLayerRegion_FlipUpdate2( region, NULL, NULL, DSFLIP_NONE, -1 );
          }
     }

     *interface = ret ? NULL : surface;

     dfb_layer_region_unref( region );

     return ret;
}
예제 #5
0
static void
IDirectFBDisplayLayer_Destruct( IDirectFBDisplayLayer *thiz )
{
     IDirectFBDisplayLayer_data *data = (IDirectFBDisplayLayer_data*)thiz->priv;

     D_DEBUG_AT( Layer, "IDirectFBDisplayLayer_Destruct()\n" );

     D_DEBUG_AT( Layer, "  -> unref region...\n" );

     dfb_layer_region_unref( data->region );

     D_DEBUG_AT( Layer, "  -> unref context...\n" );

     dfb_layer_context_unref( data->context );

     DIRECT_DEALLOCATE_INTERFACE( thiz );

     D_DEBUG_AT( Layer, "  -> done.\n" );
}
예제 #6
0
static DFBResult
IDirectFBDisplayLayer_SetCooperativeLevel( IDirectFBDisplayLayer           *thiz,
                                           DFBDisplayLayerCooperativeLevel  level )
{
     DFBResult         ret;
     CoreLayerContext *context;
     CoreLayerRegion  *region;

     D_DEBUG_AT( Layer, "%s( %p )\n", __FUNCTION__, thiz );

     DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)

     if (data->level == level)
          return DFB_OK;

     switch (level) {
          case DLSCL_SHARED:
          case DLSCL_ADMINISTRATIVE:
               if (data->level == DLSCL_EXCLUSIVE) {
                    ret = CoreLayer_GetPrimaryContext( data->layer, false, &context );
                    if (ret)
                         return ret;

                    ret = CoreLayerContext_GetPrimaryRegion( context, true, &region );
                    if (ret) {
                         dfb_layer_context_unref( context );
                         return ret;
                    }

                    dfb_layer_region_unref( data->region );
                    dfb_layer_context_unref( data->context );

                    data->context = context;
                    data->region  = region;
                    data->stack   = dfb_layer_context_windowstack( data->context );
               }

               break;

          case DLSCL_EXCLUSIVE:
               ret = CoreLayer_CreateContext( data->layer, &context );
               if (ret)
                    return ret;

               if (data->switch_exclusive) {
                    ret = CoreLayer_ActivateContext( data->layer, context );
                    if (ret) {
                         dfb_layer_context_unref( context );
                         return ret;
                    }
               }

               ret = CoreLayerContext_GetPrimaryRegion( context, true, &region );
               if (ret) {
                    dfb_layer_context_unref( context );
                    return ret;
               }

               dfb_layer_region_unref( data->region );
               dfb_layer_context_unref( data->context );

               data->context = context;
               data->region  = region;
               data->stack   = dfb_layer_context_windowstack( data->context );

               break;

          default:
               return DFB_INVARG;
     }

     data->level = level;

     return DFB_OK;
}
예제 #7
0
static DFBResult
wm_init_stack( CoreWindowStack *stack,
               void            *wm_data,
               void            *stack_data )
{
     DFBResult         ret;
     StackData        *data   = stack_data;
     WMData           *wmdata = wm_data;
     CoreLayerContext *context;
     CoreLayerRegion  *region;

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

     context = stack->context;

     D_ASSERT( context != NULL );

     ret = dfb_layer_context_get_primary_region( context, true, &region );
     if (ret) {
          D_DERROR( ret, "WM/UniQuE: Could not get the primary region!\n" );
          return ret;
     }

     /* Create the unique context. */
     ret = unique_context_create( wmdata->core, stack, region, context->layer_id,
                                  wmdata->shared, &data->context );
     dfb_layer_region_unref( region );
     if (ret) {
          D_DERROR( ret, "WM/UniQuE: Could not create the context!\n" );
          return ret;
     }

     /* Attach the global context listener. */
     ret = unique_context_attach_global( data->context,
                                         UNIQUE_WM_MODULE_CONTEXT_LISTENER,
                                         data, &data->context_reaction );
     if (ret) {
          unique_context_unref( data->context );
          D_DERROR( ret, "WM/UniQuE: Could not attach global context listener!\n" );
          return ret;
     }

     /* Inherit all local references from the layer context. */
     ret = unique_context_inherit( data->context, context );
     unique_context_unref( data->context );
     if (ret) {
          unique_context_detach_global( data->context, &data->context_reaction );
          D_DERROR( ret, "WM/UniQuE: Could not inherit from layer context!\n" );
          return ret;
     }



     data->stack = stack;

     D_MAGIC_SET( data, StackData );

     return DFB_OK;
}
예제 #8
0
static void
handle_expose_Async( void *ctx,
                     void *ctx2 )
{
     DFBX11                  *x11    = ctx;
     DFBX11Shared            *shared = x11->shared;
     const XExposeEvent      *expose = ctx2;
     CoreLayer               *layer;
     CoreLayerContext        *context;
     int                      i;
     X11LayerData            *lds;

     D_DEBUG_AT( X11_Input, "%s( %d,%d-%dx%d )\n", __FUNCTION__, expose->x, expose->y, expose->width, expose->height );

     //D_INFO_LINE_MSG("handle_expose %d,%d-%dx%d", expose->x, expose->y, expose->width, expose->height);

     /* find the correct layer */
     for (i=0; i<shared->outputs; i++) {
          if (shared->output[i].xw && (shared->output[i].xw->window == expose->window))
               break;
     }

     /* layer not found? */
     if (i == shared->outputs)
          return;

     lds = shared->output[i].layers[0];

     layer = dfb_layer_at( lds->layer_id );
     D_ASSERT( layer != NULL );

     /* Get the currently active context. */
     if (dfb_layer_get_active_context( layer, &context ) == DFB_OK) {
          CoreLayerRegion *region;

          /* Get the first region. */
          if (dfb_layer_context_get_primary_region( context, false, &region ) == DFB_OK) {
               /* Lock the region. */
               dfb_layer_region_lock( region );

               /* Get the surface of the region. */
               if (region->surface && D_FLAGS_ARE_SET( region->state, CLRSF_REALIZED )) {
                    if (dfb_config->task_manager) {
                         DFBRegion update = { expose->x, expose->y,
                                              expose->x + expose->width  - 1,
                                              expose->y + expose->height - 1 };

                         /* Tell the driver about the update if the region is realized. */
                         D_DEBUG_AT( X11_Input, "  -> Issuing display task...\n" );

                         dfb_surface_lock( region->surface );

                         DisplayTask_Generate( region, &update, &update, DSFLIP_NONE, -1, NULL );

                         dfb_surface_unlock( region->surface );
                    }
                    else {
                         //if (lds->lock_left.buffer) {
                              DFBRegion update = { expose->x, expose->y,
                                                   expose->x + expose->width  - 1,
                                                   expose->y + expose->height - 1 };

                         //     dfb_x11_update_screen( x11, lds, &update, &update, &lds->lock_left, &lds->lock_right );
                         //}
                         dfb_x11_update_screen( x11, lds, &update, &update, NULL, NULL );
                    }
               }

               /* Unlock the region. */
               dfb_layer_region_unlock( region );

               /* Release the region. */
               dfb_layer_region_unref( region );
          }

          /* Release the context. */
          dfb_layer_context_unref( context );
     }
}