void dfb_window_destroy( CoreWindow *window, bool unref ) { DFBWindowEvent evt; if (window->destroyed) { DEBUGMSG("DirectFB/core/windows: in dfb_window_destroy (%p), " "already destroyed!\n", window); return; } DEBUGMSG("DirectFB/core/windows: dfb_window_destroy (%p) entered\n", window); window->destroyed = true; evt.type = DWET_DESTROYED; dfb_window_dispatch( window, &evt ); if (window->surface) { dfb_surface_unlink( window->surface ); window->surface = NULL; } if (unref) fusion_object_unref( &window->object ); DEBUGMSG("DirectFB/core/windows: dfb_window_destroy (%p) exitting\n", window); }
static void surface_client_destructor( FusionObject *object, bool zombie, void *ctx ) { CoreSurfaceClient *client = (CoreSurfaceClient*) object; CoreSurface *surface; int index; D_MAGIC_ASSERT( client, CoreSurfaceClient ); surface = client->surface; CORE_SURFACE_ASSERT( surface ); D_DEBUG_AT( Core_SurfClient, "destroying %p (%dx%d%s)\n", client, surface->config.size.w, surface->config.size.h, zombie ? " ZOMBIE" : ""); CoreSurfaceClient_Deinit_Dispatch( &client->call ); dfb_surface_lock( surface ); index = fusion_vector_index_of( &surface->clients, client ); D_ASSERT( index >= 0 ); fusion_vector_remove( &surface->clients, index ); dfb_surface_check_acks( surface ); dfb_surface_unlock( surface ); dfb_surface_unlink( &client->surface ); D_MAGIC_CLEAR( client ); fusion_object_destroy( object ); }
DFBResult dfb_layer_region_set_surface( CoreLayerRegion *region, CoreSurface *surface ) { DFBResult ret; D_ASSERT( region != NULL ); D_ASSERT( surface != NULL ); /* Lock the region. */ if (dfb_layer_region_lock( region )) return DFB_FUSION; if (region->surface != surface) { /* Setup hardware for the new surface if the region is realized. */ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) { ret = set_region( region, ®ion->config, CLRCF_SURFACE | CLRCF_PALETTE, surface ); if (ret) { dfb_layer_region_unlock( region ); return ret; } } /* Throw away the old surface. */ if (region->surface) { /* Detach the global listener. */ dfb_surface_detach_global( region->surface, ®ion->surface_reaction ); /* Unlink surface from structure. */ dfb_surface_unlink( ®ion->surface ); } /* Take the new surface. */ if (surface) { /* Link surface into structure. */ if (dfb_surface_link( ®ion->surface, surface )) { D_WARN( "region lost it's surface" ); dfb_layer_region_unlock( region ); return DFB_FUSION; } /* Attach the global listener. */ dfb_surface_attach_global( region->surface, DFB_LAYER_REGION_SURFACE_LISTENER, region, ®ion->surface_reaction ); } } /* Unlock the region. */ dfb_layer_region_unlock( region ); return DFB_OK; }
static void region_destructor( FusionObject *object, bool zombie ) { CoreLayerRegion *region = (CoreLayerRegion*) object; CoreLayerContext *context = region->context; CoreLayer *layer = dfb_layer_at( context->layer_id ); CoreLayerShared *shared = layer->shared; (void) shared; D_DEBUG_AT( Core_Layers, "destroying region %p (%s, %dx%d, " "%s, %s, %s, %s%s)\n", region, shared->description.name, region->config.width, region->config.height, D_FLAGS_IS_SET( region->state, CLRSF_CONFIGURED ) ? "configured" : "unconfigured", D_FLAGS_IS_SET( region->state, CLRSF_ENABLED ) ? "enabled" : "disabled", D_FLAGS_IS_SET( region->state, CLRSF_ACTIVE ) ? "active" : "inactive", D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) ? "realized" : "not realized", zombie ? " - ZOMBIE" : "" ); /* Hide region etc. */ if (D_FLAGS_IS_SET( region->state, CLRSF_ENABLED )) dfb_layer_region_disable( region ); /* Remove the region from the context. */ dfb_layer_context_remove_region( region->context, region ); /* Throw away its surface. */ if (region->surface) { /* Detach the global listener. */ dfb_surface_detach_global( region->surface, ®ion->surface_reaction ); /* Unlink from structure. */ dfb_surface_unlink( ®ion->surface ); } /* Unlink the context from the structure. */ dfb_layer_context_unlink( ®ion->context ); /* Free driver's region data. */ if (region->region_data) SHFREE( region->region_data ); /* Deinitialize the lock. */ fusion_skirmish_destroy( ®ion->lock ); /* Destroy the object. */ fusion_object_destroy( object ); }
/* 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; }