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, ®ion ) == 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, ®ion->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 ); }
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, ®ion ); 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; }
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" ); }
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, ®ion ); 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, ®ion ); 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; }
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, ®ion ); 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; }
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, ®ion ) == 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 ); } }