From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/wm/unique/unique.c | 1064 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1064 insertions(+) create mode 100755 Source/DirectFB/wm/unique/unique.c (limited to 'Source/DirectFB/wm/unique/unique.c') diff --git a/Source/DirectFB/wm/unique/unique.c b/Source/DirectFB/wm/unique/unique.c new file mode 100755 index 0000000..bb0c5ec --- /dev/null +++ b/Source/DirectFB/wm/unique/unique.c @@ -0,0 +1,1064 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include +#include + + +D_DEBUG_DOMAIN( WM_Unique, "WM/UniQuE", "UniQuE - Universal Quark Emitter" ); + + +DFB_WINDOW_MANAGER( unique ); + +/**************************************************************************************************/ + +typedef struct { + int magic; + + CoreWindowStack *stack; + + UniqueContext *context; + + GlobalReaction context_reaction; +} StackData; + +typedef struct { + int magic; + + UniqueContext *context; + + UniqueWindow *window; + + GlobalReaction window_reaction; +} WindowData; + +/**************************************************************************************************/ + +static ReactionResult +context_notify( WMData *data, + const UniqueContextNotification *notification, + void *ctx ) +{ + StackData *stack_data = ctx; + + D_ASSERT( data != NULL ); + + D_ASSERT( notification != NULL ); + D_ASSERT( notification->context != NULL ); + + D_MAGIC_ASSERT( stack_data, StackData ); + + D_ASSERT( notification->context == stack_data->context ); + + D_MAGIC_ASSERT( stack_data->context, UniqueContext ); + + D_ASSERT( ! D_FLAGS_IS_SET( notification->flags, ~UCNF_ALL ) ); + + D_DEBUG_AT( WM_Unique, "context_notify( wm_data %p, stack_data %p )\n", data, stack_data ); + + if (notification->flags & UCNF_DESTROYED) { + D_DEBUG_AT( WM_Unique, " -> context destroyed.\n" ); + + if (notification->context == stack_data->context) + stack_data->context = NULL; + + return RS_REMOVE; + } + + return RS_OK; +} + +static ReactionResult +window_notify( WMData *data, + const UniqueWindowNotification *notification, + void *ctx ) +{ + WindowData *window_data = ctx; + + D_ASSERT( data != NULL ); + + D_ASSERT( notification != NULL ); + D_ASSERT( notification->window != NULL ); + + D_MAGIC_ASSERT( window_data, WindowData ); + + D_ASSERT( notification->window == window_data->window ); + + D_MAGIC_ASSERT( window_data->window, UniqueWindow ); + + D_ASSERT( ! D_FLAGS_IS_SET( notification->flags, ~UWNF_ALL ) ); + + D_DEBUG_AT( WM_Unique, "window_notify( wm_data %p, window_data %p )\n", data, window_data ); + + if (notification->flags & UWNF_DESTROYED) { + D_DEBUG_AT( WM_Unique, " -> window destroyed.\n" ); + + window_data->window = NULL; + + return RS_REMOVE; + } + + return RS_OK; +} + +/**************************************************************************************************/ + +static void +initialize_data( CoreDFB *core, WMData *data, WMShared *shared ) +{ + D_ASSERT( data != NULL ); + + /* Initialize local data. */ + data->core = core; + data->world = dfb_core_world( core ); + data->shared = shared; + data->module_abi = UNIQUE_WM_ABI_VERSION; + + /* Set module callbacks. */ + data->context_notify = context_notify; + data->window_notify = window_notify; +} + +/**************************************************************************************************/ + +static void +wm_get_info( CoreWMInfo *info ) +{ + info->version.major = 0; + info->version.minor = 4; + info->version.binary = UNIQUE_WM_ABI_VERSION; + + snprintf( info->name, DFB_CORE_WM_INFO_NAME_LENGTH, "UniQuE" ); + snprintf( info->vendor, DFB_CORE_WM_INFO_VENDOR_LENGTH, "Denis Oliver Kropp" ); + + info->wm_data_size = sizeof(WMData); + info->wm_shared_size = sizeof(WMShared); + info->stack_data_size = sizeof(StackData); + info->window_data_size = sizeof(WindowData); +} + +static DFBResult +wm_initialize( CoreDFB *core, void *wm_data, void *shared_data ) +{ + WMData *data = wm_data; + WMShared *shared = shared_data; + + D_DEBUG_AT( WM_Unique, "wm_initialize()\n" ); + + initialize_data( core, data, shared ); + + D_MAGIC_SET( shared, WMShared ); + + return unique_wm_module_init( core, data, shared, true ); +} + +static DFBResult +wm_join( CoreDFB *core, void *wm_data, void *shared_data ) +{ + WMData *data = wm_data; + WMShared *shared = shared_data; + + D_DEBUG_AT( WM_Unique, "wm_join()\n" ); + + initialize_data( core, data, shared ); + + return unique_wm_module_init( core, data, shared, false ); +} + +static DFBResult +wm_shutdown( bool emergency, void *wm_data, void *shared_data ) +{ + WMShared *shared = shared_data; + + (void) shared; + + D_DEBUG_AT( WM_Unique, "wm_shutdown()\n" ); + + unique_wm_module_deinit( wm_data, shared_data, true, emergency ); + + D_MAGIC_CLEAR( shared ); + + return DFB_OK; +} + +static DFBResult +wm_leave( bool emergency, void *wm_data, void *shared_data ) +{ + D_DEBUG_AT( WM_Unique, "wm_leave()\n" ); + + unique_wm_module_deinit( wm_data, shared_data, false, emergency ); + + return DFB_OK; +} + +static DFBResult +wm_suspend( void *wm_data, void *shared_data ) +{ + D_DEBUG_AT( WM_Unique, "wm_suspend()\n" ); + + return DFB_OK; +} + +static DFBResult +wm_resume( void *wm_data, void *shared_data ) +{ + D_DEBUG_AT( WM_Unique, "wm_resume()\n" ); + + return DFB_OK; +} + +static DFBResult +wm_post_init( void *wm_data, void *shared_data ) +{ + D_DEBUG_AT( WM_Unique, "wm_post_init()\n" ); + + 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 DFBResult +wm_close_stack( CoreWindowStack *stack, + void *wm_data, + void *stack_data ) +{ + StackData *data = stack_data; + + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + + D_MAGIC_ASSERT( data, StackData ); + + D_ASSUME( data->context == NULL ); + + if (data->context) + unique_context_detach_global( data->context, &data->context_reaction ); + + D_MAGIC_CLEAR( data ); + + return DFB_OK; +} + +static DFBResult +wm_set_active( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + bool active ) +{ + StackData *data = stack_data; + + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + + D_MAGIC_ASSERT( data, StackData ); + + D_DEBUG_AT( WM_Unique, "%s( stack %p, wm_data %p, stack_data %p, %sactive )\n", + __FUNCTION__, stack, wm_data, stack_data, active ? "" : "in" ); + + if (!data->context) { + D_ASSERT( !active ); + return DFB_OK; + } + + return unique_context_set_active( data->context, active ); +} + +static DFBResult +wm_resize_stack( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + int width, + int height ) +{ + StackData *data = stack_data; + + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + + D_MAGIC_ASSERT( data, StackData ); + + if (!data->context) + return DFB_DESTROYED; + + return unique_context_resize( data->context, width, height ); +} + +static DFBResult +wm_process_input( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + const DFBInputEvent *event ) +{ + StackData *data = stack_data; + + (void) data; + + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + D_ASSERT( event != NULL ); + + D_MAGIC_ASSERT( data, StackData ); + + return DFB_OK; +} + +static DFBResult +wm_flush_keys( CoreWindowStack *stack, + void *wm_data, + void *stack_data ) +{ + StackData *data = stack_data; + + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + + D_MAGIC_ASSERT( data, StackData ); + + if (!data->context) + return DFB_DESTROYED; + + return unique_context_flush_keys( data->context ); +} + +static DFBResult +wm_window_at( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + int x, + int y, + CoreWindow **ret_window ) +{ + DFBResult ret; + UniqueWindow *window; + StackData *data = stack_data; + + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + D_ASSERT( ret_window != NULL ); + + D_MAGIC_ASSERT( data, StackData ); + + if (!data->context) + return DFB_DESTROYED; + + ret = unique_context_window_at( data->context, x, y, &window ); + if (ret) + return ret; + + D_MAGIC_ASSERT( window, UniqueWindow ); + + *ret_window = window->window; + + return DFB_OK; +} + +static DFBResult +wm_window_lookup( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + DFBWindowID window_id, + CoreWindow **ret_window ) +{ + DFBResult ret; + UniqueWindow *window; + StackData *data = stack_data; + + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + D_ASSERT( ret_window != NULL ); + + D_MAGIC_ASSERT( data, StackData ); + + if (!data->context) + return DFB_DESTROYED; + + ret = unique_context_lookup_window( data->context, window_id, &window ); + if (ret) + return ret; + + D_MAGIC_ASSERT( window, UniqueWindow ); + + *ret_window = window->window; + + return DFB_OK; +} + +static DFBResult +wm_enum_windows( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + CoreWMWindowCallback callback, + void *callback_ctx ) +{ + StackData *data = stack_data; + + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + D_ASSERT( callback != NULL ); + + D_MAGIC_ASSERT( data, StackData ); + + if (!data->context) + return DFB_DESTROYED; + + return unique_context_enum_windows( data->context, callback, callback_ctx ); +} + +/**************************************************************************************************/ + +static DFBResult +wm_get_insets( CoreWindowStack *stack, + CoreWindow *window, + DFBInsets *insets ) +{ + if( insets ) { + insets->l=0; + insets->t=0; + insets->r=0; + insets->b=0; + } + return DFB_OK; +} + +static DFBResult +wm_preconfigure_window( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + CoreWindow *window, + void *window_data ) +{ + return DFB_OK; +} + +static DFBResult +wm_set_window_property( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + CoreWindow *window, + void *window_data, + const char *key, + void *value, + void **ret_old_value ) +{ + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + D_ASSERT( window != NULL ); + D_ASSERT( window_data != NULL ); + D_ASSERT( key != NULL ); + + fusion_object_set_property((FusionObject*)window, + key,value,ret_old_value); + return DFB_OK; +} + +static DFBResult +wm_get_window_property( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + CoreWindow *window, + void *window_data, + const char *key, + void **ret_value ) +{ + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + D_ASSERT( window != NULL ); + D_ASSERT( window_data != NULL ); + D_ASSERT( key != NULL ); + D_ASSERT( ret_value != NULL ); + + *ret_value=fusion_object_get_property((FusionObject*)window,key); + return DFB_OK; +} + + +static DFBResult +wm_remove_window_property( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + CoreWindow *window, + void *window_data, + const char *key, + void **ret_value ) +{ + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + D_ASSERT( window != NULL ); + D_ASSERT( window_data != NULL ); + D_ASSERT( key != NULL ); + + fusion_object_remove_property((FusionObject*)window,key,ret_value); + return DFB_OK; +} + +static DFBResult +wm_add_window( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + CoreWindow *window, + void *window_data ) +{ + DFBResult ret; + StackData *sdata = stack_data; + WindowData *data = window_data; + WMData *wmdata = wm_data; + + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + D_ASSERT( window != NULL ); + D_ASSERT( window_data != NULL ); + + D_MAGIC_ASSERT( sdata, StackData ); + D_MAGIC_ASSERT( sdata->context, UniqueContext ); + + data->context = sdata->context; + + /* Create the unique window. */ + ret = unique_window_create( wmdata->core, window, data->context, + window->caps, &window->config, &data->window ); + if (ret) { + D_DERROR( ret, "WM/UniQuE: Could not create window!\n" ); + return ret; + } + + /* Attach the global window listener. */ + ret = unique_window_attach_global( data->window, + UNIQUE_WM_MODULE_WINDOW_LISTENER, + data, &data->window_reaction ); + if (ret) { + unique_window_unref( data->window ); + D_DERROR( ret, "WM/UniQuE: Could not attach global window listener!\n" ); + return ret; + } + + /* Inherit all local references from the layer window. */ + ret = unique_window_inherit( data->window, window ); + unique_window_unref( data->window ); + if (ret) { + unique_window_detach_global( data->window, &data->window_reaction ); + D_DERROR( ret, "WM/UniQuE: Could not inherit from core window!\n" ); + return ret; + } + + unique_window_get_config( data->window, &window->config ); + + + D_MAGIC_SET( data, WindowData ); + + return DFB_OK; +} + +static DFBResult +wm_remove_window( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + CoreWindow *window, + void *window_data ) +{ + WindowData *data = window_data; + + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + D_ASSERT( window != NULL ); + D_ASSERT( window_data != NULL ); + + D_MAGIC_ASSERT( data, WindowData ); + +// D_ASSUME( data->window == NULL ); + + if (data->window) + unique_window_detach_global( data->window, &data->window_reaction ); + + D_MAGIC_CLEAR( data ); + + return DFB_OK; +} + +static DFBResult +wm_set_window_config( CoreWindow *window, + void *wm_data, + void *window_data, + const CoreWindowConfig *config, + CoreWindowConfigFlags flags ) +{ + DFBResult ret; + WindowData *data = window_data; + + D_ASSERT( window != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( window_data != NULL ); + D_ASSERT( config != NULL ); + + D_MAGIC_ASSERT( data, WindowData ); + + if (!data->window) + return DFB_DESTROYED; + + ret = unique_window_set_config( data->window, config, flags ); + + unique_window_get_config( data->window, &window->config ); + + return ret; +} + +static DFBResult +wm_restack_window( CoreWindow *window, + void *wm_data, + void *window_data, + CoreWindow *relative, + void *relative_data, + int relation ) +{ + WindowData *data = window_data; + WindowData *rel_data = relative_data; + + D_ASSERT( window != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( window_data != NULL ); + + D_MAGIC_ASSERT( data, WindowData ); + + D_ASSERT( relative == NULL || relative_data != NULL ); + + D_ASSERT( relative == NULL || relative == window || relation != 0); + + if (!data->window) + return DFB_DESTROYED; + + return unique_window_restack( data->window, rel_data ? rel_data->window : NULL, relation ); +} + +static DFBResult +wm_grab( CoreWindow *window, + void *wm_data, + void *window_data, + CoreWMGrab *grab ) +{ + WindowData *data = window_data; + + D_ASSERT( window != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( window_data != NULL ); + D_ASSERT( grab != NULL ); + + D_MAGIC_ASSERT( data, WindowData ); + + if (!data->window) + return DFB_DESTROYED; + + return unique_window_grab( data->window, grab ); +} + +static DFBResult +wm_ungrab( CoreWindow *window, + void *wm_data, + void *window_data, + CoreWMGrab *grab ) +{ + WindowData *data = window_data; + + D_ASSERT( window != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( window_data != NULL ); + D_ASSERT( grab != NULL ); + + D_MAGIC_ASSERT( data, WindowData ); + + if (!data->window) + return DFB_DESTROYED; + + return unique_window_ungrab( data->window, grab ); +} + +static DFBResult +wm_request_focus( CoreWindow *window, + void *wm_data, + void *window_data ) +{ + WindowData *data = window_data; + + D_ASSERT( window != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( window_data != NULL ); + + D_MAGIC_ASSERT( data, WindowData ); + + if (!data->window) + return DFB_DESTROYED; + + return unique_window_request_focus( data->window ); +} + +/**************************************************************************************************/ + +static DFBResult +wm_update_stack( CoreWindowStack *stack, + void *wm_data, + void *stack_data, + const DFBRegion *region, + DFBSurfaceFlipFlags flags ) +{ + StackData *data = stack_data; + + D_ASSERT( stack != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( stack_data != NULL ); + + DFB_REGION_ASSERT( region ); + + D_MAGIC_ASSERT( data, StackData ); + + if (!data->context) + return DFB_DESTROYED; + + return unique_context_update( data->context, region, 1, flags ); +} + +static DFBResult +wm_update_window( CoreWindow *window, + void *wm_data, + void *window_data, + const DFBRegion *region, + DFBSurfaceFlipFlags flags ) +{ + WindowData *data = window_data; + + D_ASSERT( window != NULL ); + D_ASSERT( wm_data != NULL ); + D_ASSERT( window_data != NULL ); + + DFB_REGION_ASSERT_IF( region ); + + D_MAGIC_ASSERT( data, WindowData ); + + if (!data->window) + return DFB_DESTROYED; + + return unique_window_update( data->window, region, flags ); +} + +/**************************************************************************************************/ + +/* 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, 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; +} + -- cgit