DFBResult dfb_palette_create( CoreDFB *core, unsigned int size, CorePalette **ret_palette ) { CorePalette *palette; D_DEBUG_AT( Core_Palette, "%s( %d )\n", __FUNCTION__, size ); D_ASSERT( ret_palette ); palette = dfb_core_create_palette( core ); if (!palette) return DFB_FUSION; palette->shmpool = dfb_core_shmpool( core ); if (size) { palette->entries = SHCALLOC( palette->shmpool, size, sizeof(DFBColor) ); if (!palette->entries) { fusion_object_destroy( &palette->object ); return D_OOSHM(); } palette->entries_yuv = SHCALLOC( palette->shmpool, size, sizeof(DFBColorYUV) ); if (!palette->entries_yuv) { SHFREE( palette->shmpool, palette->entries ); fusion_object_destroy( &palette->object ); return D_OOSHM(); } } palette->num_entries = size; /* reset cache */ palette->search_cache.index = -1; D_MAGIC_SET( palette, CorePalette ); /* activate object */ fusion_object_activate( &palette->object ); /* return the new palette */ *ret_palette = palette; D_DEBUG_AT( Core_Palette, " -> %p\n", palette ); return DFB_OK; }
DFBResult unique_decoration_create( UniqueWindow *window, UniqueDecorationFlags flags, UniqueDecoration **ret_decoration ) { DFBResult ret; UniqueDecoration *decoration; UniqueContext *context; D_ASSERT( window != NULL ); D_ASSERT( D_FLAGS_ARE_IN( flags, UDF_ALL ) ); D_ASSERT( ret_decoration != NULL ); context = window->context; D_MAGIC_ASSERT( context, UniqueContext ); /* Create a decoration object. */ decoration = unique_wm_create_decoration(); if (!decoration) return DFB_FUSION; /* Initialize deocration data. */ decoration->flags = flags; ret = unique_window_link( &decoration->window, window ); if (ret) goto error; ret = unique_context_link( &decoration->context, window->context ); if (ret) goto error; D_MAGIC_SET( decoration, UniqueDecoration ); /* Change global reaction lock. */ fusion_object_set_lock( &decoration->object, &context->stack->context->lock ); /* activate object */ fusion_object_activate( &decoration->object ); /* return the new decoration */ *ret_decoration = decoration; return DFB_OK; error: if (decoration->context) unique_context_unlink( &decoration->context ); if (decoration->window) unique_window_unlink( &decoration->window ); fusion_object_destroy( &decoration->object ); return ret; }
static void palette_destructor( FusionObject *object, bool zombie, void *ctx ) { CorePaletteNotification notification; CorePalette *palette = (CorePalette*) object; D_MAGIC_ASSERT( palette, CorePalette ); D_DEBUG_AT( Core_Palette, "destroying %p (%d)%s\n", palette, palette->num_entries, zombie ? " (ZOMBIE)" : ""); D_ASSERT( palette->entries != NULL ); D_ASSERT( palette->entries_yuv != NULL ); notification.flags = CPNF_DESTROY; notification.palette = palette; dfb_palette_dispatch( palette, ¬ification, dfb_palette_globals ); if (palette->hash_attached) { dfb_colorhash_invalidate( NULL, palette ); dfb_colorhash_detach( NULL, palette ); } SHFREE( palette->shmpool, palette->entries_yuv ); SHFREE( palette->shmpool, palette->entries ); D_MAGIC_CLEAR( palette ); fusion_object_destroy( object ); }
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_create( CoreLayerContext *context, CoreLayerRegion **ret_region ) { CoreLayer *layer; CoreLayerRegion *region; D_ASSERT( context != NULL ); D_ASSERT( ret_region != NULL ); layer = dfb_layer_at( context->layer_id ); /* Create the object. */ region = dfb_core_create_layer_region( layer->core ); if (!region) return DFB_FUSION; /* Link the context into the structure. */ if (dfb_layer_context_link( ®ion->context, context )) { fusion_object_destroy( ®ion->object ); return DFB_FUSION; } /* Initialize the lock. */ if (fusion_skirmish_init( ®ion->lock, "Layer Region", dfb_core_world(layer->core) )) { dfb_layer_context_unlink( ®ion->context ); fusion_object_destroy( ®ion->object ); return DFB_FUSION; } /* Change global reaction lock. */ fusion_object_set_lock( ®ion->object, ®ion->lock ); region->state = CLRSF_FROZEN; /* Activate the object. */ fusion_object_activate( ®ion->object ); /* Add the region to the context. */ dfb_layer_context_add_region( context, region ); /* Return the new region. */ *ret_region = 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 ); }
static void surface_destructor( FusionObject *object, bool zombie, void *ctx ) { int i; CoreSurface *surface = (CoreSurface*) object; D_MAGIC_ASSERT( surface, CoreSurface ); D_DEBUG_AT( Core_Surface, "destroying %p (%dx%d%s)\n", surface, surface->config.size.w, surface->config.size.h, zombie ? " ZOMBIE" : ""); Core_Resource_RemoveSurface( surface ); CoreSurface_Deinit_Dispatch( &surface->call ); dfb_surface_lock( surface ); surface->state |= CSSF_DESTROYED; /* announce surface destruction */ dfb_surface_notify( surface, CSNF_DESTROY ); /* unlink palette */ if (surface->palette) { dfb_palette_detach_global( surface->palette, &surface->palette_reaction ); dfb_palette_unlink( &surface->palette ); } /* destroy buffers */ for (i=0; i<MAX_SURFACE_BUFFERS; i++) { if (surface->buffers[i]) dfb_surface_buffer_decouple( surface->buffers[i] ); } dfb_system_surface_data_destroy( surface, surface->data ); /* release the system driver specific surface data */ if (surface->data) { SHFREE( surface->shmpool, surface->data ); surface->data = NULL; } direct_serial_deinit( &surface->serial ); dfb_surface_unlock( surface ); fusion_skirmish_destroy( &surface->lock ); D_MAGIC_CLEAR( surface ); fusion_object_destroy( object ); }
/* * Window destructor. */ static void window_destructor( FusionObject *object, bool zombie ) { CoreWindow *window = (CoreWindow*) object; DEBUGMSG("DirectFB/core/windows: destroying %p (%dx%d)%s\n", window, window->width, window->height, zombie ? " (ZOMBIE)" : ""); dfb_window_deinit( window ); dfb_window_destroy( window, false ); fusion_object_destroy( object ); }
static void decoration_destructor( FusionObject *object, bool zombie, void *ctx ) { UniqueDecoration *decoration = (UniqueDecoration*) object; D_MAGIC_ASSERT( decoration, UniqueDecoration ); D_DEBUG_AT( UniQuE_Decoration, "destroying %p%s\n", decoration, zombie ? " (ZOMBIE)" : ""); unique_window_unlink( &decoration->window ); unique_context_unlink( &decoration->context ); D_MAGIC_CLEAR( decoration ); fusion_object_destroy( object ); }
static void thread_destructor( FusionObject *object, bool zombie, void *ctx ) { ComaThread *thread = (ComaThread*) object; D_MAGIC_ASSERT( thread, ComaThread ); D_DEBUG_AT( Coma_Thread, "%s( %p [%u] )%s\n", __FUNCTION__, thread, object->id, zombie ? " ZOMBIE!" : "" ); if (thread->mem) SHFREE( thread->shmpool, thread->mem ); D_MAGIC_CLEAR( thread ); fusion_object_destroy( object ); }
DFBResult dfb_surface_client_create( CoreDFB *core, CoreSurface *surface, CoreSurfaceClient **ret_client ) { DFBResult ret; CoreSurfaceClient *client; CORE_SURFACE_ASSERT( surface ); D_ASSERT( ret_client != NULL ); D_DEBUG_AT( Core_SurfClient, "%s( %p %dx%d %s )\n", __FUNCTION__, surface, surface->config.size.w, surface->config.size.h, dfb_pixelformat_name( surface->config.format ) ); client = dfb_core_create_surface_client( core ); if (!client) return DFB_FUSION; ret = dfb_surface_link( &client->surface, surface ); if (ret) { fusion_object_destroy( &client->object ); return ret; } D_MAGIC_SET( client, CoreSurfaceClient ); *ret_client = client; CoreSurfaceClient_Init_Dispatch( core, client, &client->call ); dfb_surface_lock( surface ); client->flip_count = surface->flips; fusion_vector_add( &surface->clients, client ); dfb_surface_unlock( surface ); fusion_object_activate( &client->object ); return DFB_OK; }
static void surface_destructor( FusionObject *object, bool zombie, void *ctx ) { int i; CoreSurface *surface = (CoreSurface*) object; D_MAGIC_ASSERT( surface, CoreSurface ); D_DEBUG_AT( Core_Surface, "destroying %p (%dx%d%s)\n", surface, surface->config.size.w, surface->config.size.h, zombie ? " ZOMBIE" : ""); dfb_surface_lock( surface ); surface->state |= CSSF_DESTROYED; /* announce surface destruction */ dfb_surface_notify( surface, CSNF_DESTROY ); /* unlink palette */ if (surface->palette) { dfb_palette_detach_global( surface->palette, &surface->palette_reaction ); dfb_palette_unlink( &surface->palette ); } /* destroy buffers */ for (i=0; i<MAX_SURFACE_BUFFERS; i++) { if (surface->buffers[i]) dfb_surface_buffer_destroy( surface->buffers[i] ); } direct_serial_deinit( &surface->serial ); dfb_surface_unlock( surface ); fusion_skirmish_destroy( &surface->lock ); D_MAGIC_CLEAR( surface ); fusion_object_destroy( object ); }
DFBResult dfb_surface_create( CoreDFB *core, const CoreSurfaceConfig *config, CoreSurfaceTypeFlags type, unsigned long resource_id, CorePalette *palette, CoreSurface **ret_surface ) { DFBResult ret = DFB_BUG; int i, data_size; int buffers; CoreSurface *surface; char buf[64]; D_ASSERT( core != NULL ); D_FLAGS_ASSERT( type, CSTF_ALL ); D_MAGIC_ASSERT_IF( palette, CorePalette ); D_ASSERT( ret_surface != NULL ); D_DEBUG_AT( Core_Surface, "dfb_surface_create( %p, %p, %p )\n", core, config, ret_surface ); surface = dfb_core_create_surface( core ); if (!surface) return DFB_FUSION; surface->data = NULL; if (config) { D_FLAGS_ASSERT( config->flags, CSCONF_ALL ); surface->config.flags = config->flags; if (config->flags & CSCONF_SIZE) { D_DEBUG_AT( Core_Surface, " -> %dx%d\n", config->size.w, config->size.h ); surface->config.size = config->size; } if (config->flags & CSCONF_FORMAT) { D_DEBUG_AT( Core_Surface, " -> %s\n", dfb_pixelformat_name( config->format ) ); surface->config.format = config->format; } if (config->flags & CSCONF_CAPS) { D_DEBUG_AT( Core_Surface, " -> caps 0x%08x\n", config->caps ); if (config->caps & DSCAPS_ROTATED) D_UNIMPLEMENTED(); surface->config.caps = config->caps & ~DSCAPS_ROTATED; } if (config->flags & CSCONF_PREALLOCATED) { D_DEBUG_AT( Core_Surface, " -> prealloc %p [%d]\n", config->preallocated[0].addr, config->preallocated[0].pitch ); direct_memcpy( surface->config.preallocated, config->preallocated, sizeof(config->preallocated) ); surface->config.preallocated_pool_id = config->preallocated_pool_id; type |= CSTF_PREALLOCATED; } } if (surface->config.caps & DSCAPS_SYSTEMONLY) surface->type = (type & ~CSTF_EXTERNAL) | CSTF_INTERNAL; else if (surface->config.caps & DSCAPS_VIDEOONLY) surface->type = (type & ~CSTF_INTERNAL) | CSTF_EXTERNAL; else surface->type = type & ~(CSTF_INTERNAL | CSTF_EXTERNAL); if (surface->config.caps & DSCAPS_SHARED) surface->type |= CSTF_SHARED; surface->resource_id = resource_id; if (surface->config.caps & DSCAPS_TRIPLE) buffers = 3; else if (surface->config.caps & DSCAPS_DOUBLE) buffers = 2; else { buffers = 1; surface->config.caps &= ~DSCAPS_ROTATED; } surface->notifications = CSNF_ALL & ~CSNF_FLIP; surface->alpha_ramp[0] = 0x00; surface->alpha_ramp[1] = 0x55; surface->alpha_ramp[2] = 0xaa; surface->alpha_ramp[3] = 0xff; if (surface->config.caps & DSCAPS_STATIC_ALLOC) surface->config.min_size = surface->config.size; surface->shmpool = dfb_core_shmpool( core ); direct_serial_init( &surface->serial ); snprintf( buf, sizeof(buf), "Surface %dx%d %s", surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(surface->config.format) ); fusion_ref_set_name( &surface->object.ref, buf ); fusion_skirmish_init2( &surface->lock, buf, dfb_core_world(core), fusion_config->secure_fusion ); // fusion_skirmish_add_permissions( &surface->lock, 0, FUSION_SKIRMISH_PERMIT_PREVAIL | FUSION_SKIRMISH_PERMIT_DISMISS ); D_MAGIC_SET( surface, CoreSurface ); if (dfb_config->warn.flags & DCWF_CREATE_SURFACE && dfb_config->warn.create_surface.min_size.w <= surface->config.size.w && dfb_config->warn.create_surface.min_size.h <= surface->config.size.h) D_WARN( "create-surface %4dx%4d %6s, buffers %d, caps 0x%08x, type 0x%08x", surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(surface->config.format), buffers, surface->config.caps, surface->type ); if (palette) { dfb_surface_set_palette( surface, palette ); } else if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) { ret = dfb_surface_init_palette( core, surface ); if (ret) goto error; } /* Create the system driver specific surface data information */ data_size = dfb_system_surface_data_size(); if (data_size) { surface->data = SHCALLOC( surface->shmpool, 1, data_size ); if (!surface->data) { ret = D_OOSHM(); goto error; } } dfb_system_surface_data_init(surface,surface->data); dfb_surface_lock( surface ); /* Create the Surface Buffers. */ for (i=0; i<buffers; i++) { ret = dfb_surface_buffer_create( core, surface, CSBF_NONE, &surface->buffers[i] ); if (ret) { D_DERROR( ret, "Core/Surface: Error creating surface buffer!\n" ); goto error; } surface->num_buffers++; dfb_surface_buffer_globalize( surface->buffers[i] ); switch (i) { case 0: surface->buffer_indices[CSBR_FRONT] = i; case 1: surface->buffer_indices[CSBR_BACK] = i; case 2: surface->buffer_indices[CSBR_IDLE] = i; } } dfb_surface_unlock( surface ); CoreSurface_Init_Dispatch( core, surface, &surface->call ); fusion_object_activate( &surface->object ); *ret_surface = surface; return DFB_OK; error: for (i=0; i<MAX_SURFACE_BUFFERS; i++) { if (surface->buffers[i]) dfb_surface_buffer_decouple( surface->buffers[i] ); } /* release the system driver specific surface data */ if (surface->data) { dfb_system_surface_data_destroy( surface, surface->data ); SHFREE( surface->shmpool, surface->data ); surface->data = NULL; } fusion_skirmish_destroy( &surface->lock ); direct_serial_deinit( &surface->serial ); D_MAGIC_CLEAR( surface ); fusion_object_destroy( &surface->object ); return ret; }
DFBResult dfb_surface_create( CoreDFB *core, const CoreSurfaceConfig *config, CoreSurfaceTypeFlags type, unsigned long resource_id, CorePalette *palette, CoreSurface **ret_surface ) { DFBResult ret = DFB_BUG; int i; int buffers; CoreSurface *surface; char buf[64]; D_ASSERT( core != NULL ); D_FLAGS_ASSERT( type, CSTF_ALL ); D_MAGIC_ASSERT_IF( palette, CorePalette ); D_ASSERT( ret_surface != NULL ); D_DEBUG_AT( Core_Surface, "dfb_surface_create( %p, %p, %p )\n", core, config, ret_surface ); surface = dfb_core_create_surface( core ); if (!surface) return DFB_FUSION; if (config) { D_FLAGS_ASSERT( config->flags, CSCONF_ALL ); surface->config.flags = config->flags; if (config->flags & CSCONF_SIZE) { D_DEBUG_AT( Core_Surface, " -> %dx%d\n", config->size.w, config->size.h ); surface->config.size = config->size; } if (config->flags & CSCONF_FORMAT) { D_DEBUG_AT( Core_Surface, " -> %s\n", dfb_pixelformat_name( config->format ) ); surface->config.format = config->format; } if (config->flags & CSCONF_CAPS) { D_DEBUG_AT( Core_Surface, " -> caps 0x%08x\n", config->caps ); surface->config.caps = config->caps; } if (config->flags & CSCONF_PREALLOCATED) { D_DEBUG_AT( Core_Surface, " -> prealloc %p [%d]\n", config->preallocated[0].addr, config->preallocated[0].pitch ); direct_memcpy( surface->config.preallocated, config->preallocated, sizeof(config->preallocated) ); type |= CSTF_PREALLOCATED; } } if (surface->config.caps & DSCAPS_SYSTEMONLY) surface->type = (type & ~CSTF_EXTERNAL) | CSTF_INTERNAL; else if (surface->config.caps & DSCAPS_VIDEOONLY) surface->type = (type & ~CSTF_INTERNAL) | CSTF_EXTERNAL; else surface->type = type & ~(CSTF_INTERNAL | CSTF_EXTERNAL); if (surface->config.caps & DSCAPS_SHARED) surface->type |= CSTF_SHARED; surface->resource_id = resource_id; if (surface->config.caps & DSCAPS_TRIPLE) buffers = 3; else if (surface->config.caps & DSCAPS_DOUBLE) buffers = 2; else buffers = 1; surface->notifications = CSNF_ALL & ~CSNF_FLIP; surface->alpha_ramp[0] = 0x00; surface->alpha_ramp[1] = 0x55; surface->alpha_ramp[2] = 0xaa; surface->alpha_ramp[3] = 0xff; if (surface->config.caps & DSCAPS_STATIC_ALLOC) surface->config.min_size = surface->config.size; surface->shmpool = dfb_core_shmpool( core ); direct_serial_init( &surface->serial ); snprintf( buf, sizeof(buf), "Surface %dx%d %s", surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(surface->config.format) ); fusion_ref_set_name( &surface->object.ref, buf ); fusion_skirmish_init( &surface->lock, buf, dfb_core_world(core) ); fusion_object_set_lock( &surface->object, &surface->lock ); D_MAGIC_SET( surface, CoreSurface ); if (dfb_config->warn.flags & DCWF_CREATE_SURFACE && dfb_config->warn.create_surface.min_size.w <= surface->config.size.w && dfb_config->warn.create_surface.min_size.h <= surface->config.size.h) D_WARN( "create-surface %4dx%4d %6s, buffers %d, caps 0x%08x, type 0x%08x", surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(surface->config.format), buffers, surface->config.caps, surface->type ); if (palette) { dfb_surface_set_palette( surface, palette ); } else if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) { ret = dfb_surface_init_palette( core, surface ); if (ret) goto error; } /* Create the Surface Buffers. */ for (i=0; i<buffers; i++) { CoreSurfaceBuffer *buffer; ret = dfb_surface_buffer_new( surface, CSBF_NONE, &buffer ); if (ret) { D_DERROR( ret, "Core/Surface: Error creating surface buffer!\n" ); goto error; } surface->buffers[surface->num_buffers++] = buffer; switch (i) { case 0: surface->buffer_indices[CSBR_FRONT] = i; case 1: surface->buffer_indices[CSBR_BACK] = i; case 2: surface->buffer_indices[CSBR_IDLE] = i; } } fusion_object_activate( &surface->object ); *ret_surface = surface; return DFB_OK; error: D_MAGIC_CLEAR( surface ); for (i=0; i<MAX_SURFACE_BUFFERS; i++) { if (surface->buffers[i]) dfb_surface_buffer_destroy( surface->buffers[i] ); } fusion_skirmish_destroy( &surface->lock ); direct_serial_deinit( &surface->serial ); fusion_object_destroy( &surface->object ); return ret; }
DFBResult dfb_window_create( CoreWindowStack *stack, int x, int y, int width, int height, DFBWindowCapabilities caps, DFBSurfaceCapabilities surface_caps, DFBSurfacePixelFormat pixelformat, CoreWindow **window ) { DFBResult ret; CoreSurface *surface; CoreSurfacePolicy surface_policy; CoreWindow *w; DisplayLayer *layer = dfb_layer_at( stack->layer_id ); CoreSurface *layer_surface = dfb_layer_surface( layer ); surface_caps &= DSCAPS_INTERLACED | DSCAPS_SEPERATED | DSCAPS_STATIC_ALLOC | DSCAPS_SYSTEMONLY | DSCAPS_VIDEOONLY; if (caps & DWCAPS_ALPHACHANNEL) { if (pixelformat == DSPF_UNKNOWN) pixelformat = DSPF_ARGB; else if (! DFB_PIXELFORMAT_HAS_ALPHA(pixelformat)) return DFB_INVARG; surface_policy = stack->wsp_alpha; } else { surface_policy = stack->wsp_opaque; if (pixelformat == DSPF_UNKNOWN) pixelformat = layer_surface->format; } if (surface_caps & DSCAPS_VIDEOONLY) surface_policy = CSP_VIDEOONLY; else if (surface_caps & DSCAPS_SYSTEMONLY) surface_policy = CSP_SYSTEMONLY; else if (layer_surface->back_buffer->policy == CSP_SYSTEMONLY) surface_policy = CSP_SYSTEMONLY; if (caps & DWCAPS_DOUBLEBUFFER) surface_caps |= DSCAPS_FLIPPING; /* Create the window object. */ w = (CoreWindow*) fusion_object_create( stack->pool ); /* Create the window's surface using the layer's palette. */ if (! (caps & DWCAPS_INPUTONLY)) { ret = dfb_surface_create( width, height, pixelformat, surface_policy, surface_caps, layer_surface->palette, &surface ); if (ret) { fusion_object_destroy( &w->object ); return ret; } dfb_surface_link( &w->surface, surface ); dfb_surface_unref( surface ); } w->id = new_window_id( stack ); w->x = x; w->y = y; w->width = width; w->height = height; w->caps = caps; w->opacity = 0; if (caps & DWCAPS_ALPHACHANNEL) w->options = DWOP_ALPHACHANNEL; w->stack = stack; w->events = DWET_ALL; *window = w; return DFB_OK;; }