/* (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 D_DEBUG_DOMAIN( UniQuE_WM, "UniQuE/WM", "UniQuE - Universal Quark Emitter" ); /**************************************************************************************************/ static CoreDFB *dfb_core; static WMData *wm_data; static WMShared *wm_shared; /**************************************************************************************************/ static const StretRegionClass *region_classes[_URCI_NUM] = { &unique_root_region_class, &unique_frame_region_class, &unique_window_region_class, &unique_foo_region_class }; static DFBResult register_region_classes ( WMShared *shared, bool master ); static DFBResult unregister_region_classes( WMShared *shared ); /**************************************************************************************************/ static const UniqueDeviceClass *device_classes[_UDCI_NUM] = { &unique_pointer_device_class, &unique_wheel_device_class, &unique_keyboard_device_class }; static DFBResult register_device_classes ( WMShared *shared, bool master ); static DFBResult unregister_device_classes( WMShared *shared ); /**************************************************************************************************/ static DFBResult load_foo( CoreDFB *core, WMShared *shared ) { DFBResult ret; D_ASSERT( core != NULL ); D_MAGIC_ASSERT( shared, WMShared ); ret = dfb_surface_create_simple( core, foo_desc.width, foo_desc.height, foo_desc.pixelformat, DSCAPS_NONE, CSTF_SHARED, 0, NULL, &shared->foo_surface ); if (ret) { D_DERROR( ret, "UniQuE/WM: Could not create %dx%d surface for border tiles!\n", foo_desc.width, foo_desc.height ); return ret; } ret = dfb_surface_write_buffer( shared->foo_surface, CSBR_BACK, foo_desc.preallocated[0].data, foo_desc.preallocated[0].pitch, NULL ); if (ret) D_DERROR( ret, "UniQuE/WM: Could not write to %dx%d surface for border tiles!\n", foo_desc.width, foo_desc.height ); dfb_surface_globalize( shared->foo_surface ); return DFB_OK; } static void unload_foo( WMShared *shared ) { D_MAGIC_ASSERT( shared, WMShared ); dfb_surface_unlink( &shared->foo_surface ); } /**************************************************************************************************/ DFBResult unique_wm_module_init( CoreDFB *core, WMData *data, WMShared *shared, bool master ) { DFBResult ret; D_DEBUG_AT( UniQuE_WM, "unique_wm_init( core %p, data %p, shared %p, %s )\n", core, data, shared, master ? "master" : "slave" ); D_ASSERT( core != NULL ); D_ASSERT( data != NULL ); D_ASSERT( data->context_notify != NULL ); D_ASSERT( data->window_notify != NULL ); D_MAGIC_ASSERT( shared, WMShared ); D_ASSERT( dfb_core == NULL ); D_ASSERT( wm_data == NULL ); D_ASSERT( wm_shared == NULL ); if (data->module_abi != UNIQUE_WM_ABI_VERSION) { D_ERROR( "UniQuE/WM: Module ABI version (%d) does not match %d!\n", data->module_abi, UNIQUE_WM_ABI_VERSION ); return DFB_VERSIONMISMATCH; } ret = register_region_classes( shared, master ); if (ret) return ret; ret = register_device_classes( shared, master ); if (ret) goto error_device; if (master) { int i; ret = load_foo( core, shared ); if (ret) goto error_foo; ret = dfb_input_add_global( _unique_device_listener, &shared->device_listener ); if (ret) goto error_global; shared->context_pool = unique_context_pool_create( data->world ); shared->decoration_pool = unique_decoration_pool_create( data->world ); shared->window_pool = unique_window_pool_create( data->world ); shared->insets.l = foo[UFI_W].rect.w; shared->insets.t = foo[UFI_N].rect.h; shared->insets.r = foo[UFI_E].rect.w; shared->insets.b = foo[UFI_S].rect.h; for (i=0; i<8; i++) shared->foo_rects[i] = foo[i].rect; } else dfb_input_set_global( _unique_device_listener, shared->device_listener ); dfb_core = core; wm_data = data; wm_shared = shared; return DFB_OK; error_global: unload_foo( shared ); error_foo: unregister_device_classes( shared ); error_device: unregister_region_classes( shared ); return ret; } void unique_wm_module_deinit( WMData *data, WMShared *shared, bool master, bool emergency ) { D_DEBUG_AT( UniQuE_WM, "unique_wm_deinit( %s%s ) <- core %p, data %p, shared %p\n", master ? "master" : "slave", emergency ? ", emergency" : "", dfb_core, wm_data, wm_shared ); D_ASSERT( dfb_core != NULL ); D_ASSERT( wm_data != NULL ); D_ASSERT( wm_data == data ); D_MAGIC_ASSERT( shared, WMShared ); D_ASSERT( wm_shared == shared ); if (master) { fusion_object_pool_destroy( shared->window_pool, data->world ); fusion_object_pool_destroy( shared->decoration_pool, data->world ); fusion_object_pool_destroy( shared->context_pool, data->world ); } unregister_device_classes( shared ); unregister_region_classes( shared ); if (master) unload_foo( wm_shared ); dfb_core = NULL; wm_data = NULL; wm_shared = NULL; } ReactionResult _unique_wm_module_context_listener( const void *msg_data, void *ctx ) { const UniqueContextNotification *notification = msg_data; D_ASSERT( wm_data != NULL ); D_ASSERT( wm_data->context_notify != NULL ); D_ASSERT( notification != NULL ); D_ASSERT( ! D_FLAGS_IS_SET( notification->flags, ~UCNF_ALL ) ); D_DEBUG_AT( UniQuE_WM, "%s( context %p, flags 0x%08x )\n", __FUNCTION__, notification->context, notification->flags ); return wm_data->context_notify( wm_data, notification, ctx ); } ReactionResult _unique_wm_module_window_listener ( const void *msg_data, void *ctx ) { const UniqueWindowNotification *notification = msg_data; D_ASSERT( wm_data != NULL ); D_ASSERT( wm_data->window_notify != NULL ); D_ASSERT( notification != NULL ); D_ASSERT( ! D_FLAGS_IS_SET( notification->flags, ~UWNF_ALL ) ); D_DEBUG_AT( UniQuE_WM, "%s( window %p, flags 0x%08x )\n", __FUNCTION__, notification->window, notification->flags ); return wm_data->window_notify( wm_data, notification, ctx ); } UniqueContext * unique_wm_create_context( void ) { D_ASSERT( dfb_core != NULL ); D_ASSERT( wm_data != NULL ); D_MAGIC_ASSERT( wm_shared, WMShared ); D_ASSERT( wm_shared->context_pool != NULL ); return (UniqueContext*) fusion_object_create( wm_shared->context_pool, wm_data->world ); } UniqueDecoration * unique_wm_create_decoration( void ) { D_ASSERT( dfb_core != NULL ); D_ASSERT( wm_data != NULL ); D_MAGIC_ASSERT( wm_shared, WMShared ); D_ASSERT( wm_shared->decoration_pool != NULL ); return (UniqueDecoration*) fusion_object_create( wm_shared->decoration_pool, wm_data->world ); } UniqueWindow * unique_wm_create_window( void ) { D_ASSERT( dfb_core != NULL ); D_ASSERT( wm_data != NULL ); D_MAGIC_ASSERT( wm_shared, WMShared ); D_ASSERT( wm_shared->window_pool != NULL ); return (UniqueWindow*) fusion_object_create( wm_shared->window_pool, wm_data->world ); } /**************************************************************************************************/ bool unique_wm_running( void ) { if (dfb_core) { if (!wm_data || !wm_shared) { D_BUG( "partly initialized module (%p,%p,%p)", dfb_core, wm_data, wm_shared ); return false; } return true; } return false; } DirectResult unique_wm_enum_contexts( FusionObjectCallback callback, void *ctx ) { D_ASSERT( dfb_core != NULL ); D_ASSERT( wm_data != NULL ); D_MAGIC_ASSERT( wm_shared, WMShared ); D_ASSERT( wm_shared->context_pool != NULL ); return fusion_object_pool_enum( wm_shared->context_pool, callback, ctx ); } DirectResult unique_wm_enum_windows( FusionObjectCallback callback, void *ctx ) { D_ASSERT( dfb_core != NULL ); D_ASSERT( wm_data != NULL ); D_MAGIC_ASSERT( wm_shared, WMShared ); D_ASSERT( wm_shared->context_pool != NULL ); return fusion_object_pool_enum( wm_shared->window_pool, callback, ctx ); } /**************************************************************************************************/ static DFBResult register_region_classes( WMShared *shared, bool master ) { int i; DFBResult ret; StretRegionClassID class_id; D_MAGIC_ASSERT( shared, WMShared ); for (i=0; i<_URCI_NUM; i++) { ret = stret_class_register( region_classes[i], &class_id ); if (ret) { D_DERROR( ret, "UniQuE/WM: Failed to register region class %d!\n", i ); goto error; } if (master) shared->region_classes[i] = class_id; else if (shared->region_classes[i] != class_id) { D_ERROR( "UniQuE/WM: Class IDs mismatch (%d/%d)!\n", class_id, shared->region_classes[i] ); stret_class_unregister( class_id ); ret = DFB_VERSIONMISMATCH; goto error; } } return DFB_OK; error: while (--i >= 0) stret_class_unregister( shared->region_classes[i] ); return ret; } static DFBResult unregister_region_classes( WMShared *shared ) { int i; D_MAGIC_ASSERT( shared, WMShared ); for (i=_URCI_NUM-1; i>=0; i--) stret_class_unregister( shared->region_classes[i] ); return DFB_OK; } static DFBResult register_device_classes( WMShared *shared, bool master ) { int i; DFBResult ret; UniqueDeviceClassID class_id; D_MAGIC_ASSERT( shared, WMShared ); for (i=0; i<_UDCI_NUM; i++) { ret = unique_device_class_register( device_classes[i], &class_id ); if (ret) { D_DERROR( ret, "UniQuE/WM: Failed to register device class %d!\n", i ); goto error; } if (master) shared->device_classes[i] = class_id; else if (shared->device_classes[i] != class_id) { D_ERROR( "UniQuE/WM: Class IDs mismatch (%d/%d)!\n", class_id, shared->device_classes[i] ); unique_device_class_unregister( class_id ); ret = DFB_VERSIONMISMATCH; goto error; } } return DFB_OK; error: while (--i >= 0) unique_device_class_unregister( shared->device_classes[i] ); return ret; } static DFBResult unregister_device_classes( WMShared *shared ) { int i; D_MAGIC_ASSERT( shared, WMShared ); for (i=_UDCI_NUM-1; i>=0; i--) unique_device_class_unregister( shared->device_classes[i] ); return DFB_OK; }