/* (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 D_DEBUG_DOMAIN( Core_Clipboard, "Core/Clipboard", "DirectFB Clipboard Core" ); /**********************************************************************************************************************/ typedef struct { int magic; FusionSkirmish lock; char *mime_type; void *data; unsigned int size; struct timeval timestamp; FusionSHMPoolShared *shmpool; } DFBClipboardCoreShared; struct __DFB_DFBClipboardCore { int magic; CoreDFB *core; DFBClipboardCoreShared *shared; }; DFB_CORE_PART( clipboard_core, ClipboardCore ); /**********************************************************************************************************************/ static DFBResult dfb_clipboard_core_initialize( CoreDFB *core, DFBClipboardCore *data, DFBClipboardCoreShared *shared ) { D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_initialize( %p, %p, %p )\n", core, data, shared ); D_ASSERT( data != NULL ); D_ASSERT( shared != NULL ); data->core = core; data->shared = shared; shared->shmpool = dfb_core_shmpool( core ); fusion_skirmish_init( &shared->lock, "Clipboard Core", dfb_core_world(core) ); D_MAGIC_SET( data, DFBClipboardCore ); D_MAGIC_SET( shared, DFBClipboardCoreShared ); return DFB_OK; } static DFBResult dfb_clipboard_core_join( CoreDFB *core, DFBClipboardCore *data, DFBClipboardCoreShared *shared ) { D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_join( %p, %p, %p )\n", core, data, shared ); D_ASSERT( data != NULL ); D_MAGIC_ASSERT( shared, DFBClipboardCoreShared ); data->core = core; data->shared = shared; D_MAGIC_SET( data, DFBClipboardCore ); return DFB_OK; } static DFBResult dfb_clipboard_core_shutdown( DFBClipboardCore *data, bool emergency ) { DFBClipboardCoreShared *shared; D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_shutdown( %p, %semergency )\n", data, emergency ? "" : "no " ); D_MAGIC_ASSERT( data, DFBClipboardCore ); shared = data->shared; D_MAGIC_ASSERT( shared, DFBClipboardCoreShared ); fusion_skirmish_destroy( &shared->lock ); if (shared->data) SHFREE( shared->shmpool, shared->data ); if (shared->mime_type) SHFREE( shared->shmpool, shared->mime_type ); D_MAGIC_CLEAR( data ); D_MAGIC_CLEAR( shared ); return DFB_OK; } static DFBResult dfb_clipboard_core_leave( DFBClipboardCore *data, bool emergency ) { D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_leave( %p, %semergency )\n", data, emergency ? "" : "no " ); D_MAGIC_ASSERT( data, DFBClipboardCore ); D_MAGIC_ASSERT( data->shared, DFBClipboardCoreShared ); D_MAGIC_CLEAR( data ); return DFB_OK; } static DFBResult dfb_clipboard_core_suspend( DFBClipboardCore *data ) { D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_suspend( %p )\n", data ); D_MAGIC_ASSERT( data, DFBClipboardCore ); D_MAGIC_ASSERT( data->shared, DFBClipboardCoreShared ); return DFB_OK; } static DFBResult dfb_clipboard_core_resume( DFBClipboardCore *data ) { D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_resume( %p )\n", data ); D_MAGIC_ASSERT( data, DFBClipboardCore ); D_MAGIC_ASSERT( data->shared, DFBClipboardCoreShared ); return DFB_OK; } /**********************************************************************************************************************/ DFBResult dfb_clipboard_set( DFBClipboardCore *core, const char *mime_type, const void *data, unsigned int size, struct timeval *timestamp ) { DFBClipboardCoreShared *shared; char *new_mime; void *new_data; D_MAGIC_ASSERT( core, DFBClipboardCore ); D_ASSERT( mime_type != NULL ); D_ASSERT( data != NULL ); D_ASSERT( size > 0 ); shared = core->shared; D_MAGIC_ASSERT( shared, DFBClipboardCoreShared ); new_mime = SHSTRDUP( shared->shmpool, mime_type ); if (!new_mime) return D_OOSHM(); new_data = SHMALLOC( shared->shmpool, size ); if (!new_data) { SHFREE( shared->shmpool, new_mime ); return D_OOSHM(); } direct_memcpy( new_data, data, size ); if (fusion_skirmish_prevail( &shared->lock )) { SHFREE( shared->shmpool, new_data ); SHFREE( shared->shmpool, new_mime ); return DFB_FUSION; } if (shared->data) SHFREE( shared->shmpool, shared->data ); if (shared->mime_type) SHFREE( shared->shmpool, shared->mime_type ); shared->mime_type = new_mime; shared->data = new_data; shared->size = size; gettimeofday( &shared->timestamp, NULL ); if (timestamp) *timestamp = shared->timestamp; fusion_skirmish_dismiss( &shared->lock ); return DFB_OK; } DFBResult dfb_clipboard_get( DFBClipboardCore *core, char **mime_type, void **data, unsigned int *size ) { DFBClipboardCoreShared *shared; D_MAGIC_ASSERT( core, DFBClipboardCore ); shared = core->shared; D_MAGIC_ASSERT( shared, DFBClipboardCoreShared ); if (fusion_skirmish_prevail( &shared->lock )) return DFB_FUSION; if (!shared->mime_type || !shared->data) { fusion_skirmish_dismiss( &shared->lock ); return DFB_BUFFEREMPTY; } if (mime_type) *mime_type = strdup( shared->mime_type ); if (data) { *data = malloc( shared->size ); direct_memcpy( *data, shared->data, shared->size ); } if (size) *size = shared->size; fusion_skirmish_dismiss( &shared->lock ); return DFB_OK; } DFBResult dfb_clipboard_get_timestamp( DFBClipboardCore *core, struct timeval *timestamp ) { DFBClipboardCoreShared *shared; D_MAGIC_ASSERT( core, DFBClipboardCore ); D_ASSERT( timestamp != NULL ); shared = core->shared; D_MAGIC_ASSERT( shared, DFBClipboardCoreShared ); if (fusion_skirmish_prevail( &shared->lock )) return DFB_FUSION; *timestamp = shared->timestamp; fusion_skirmish_dismiss( &shared->lock ); return DFB_OK; }