1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gtkinst.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include <osl/module.h>
35 #include <plugins/gtk/gtkdata.hxx>
36 #include <plugins/gtk/gtkinst.hxx>
39 #include <plugins/gtk/gtkframe.hxx>
40 #include <plugins/gtk/gtkobject.hxx>
41 #include <plugins/gtk/atkbridge.hxx>
43 #include <rtl/strbuf.hxx>
45 #if OSL_DEBUG_LEVEL > 1
53 GtkHookedYieldMutex::GtkHookedYieldMutex()
58 * These methods always occur in pairs
59 * A ThreadsEnter is followed by a ThreadsLeave
60 * We need to queue up the recursive lock count
61 * for each pair, so we can accurately restore
64 void GtkHookedYieldMutex::ThreadsEnter()
67 if( !aYieldStack
.empty() )
68 { /* Previously called ThreadsLeave() */
69 ULONG nCount
= aYieldStack
.front();
70 aYieldStack
.pop_front();
76 void GtkHookedYieldMutex::ThreadsLeave()
78 aYieldStack
.push_front( mnCount
);
80 #if OSL_DEBUG_LEVEL > 1
82 mnThreadId
!= NAMESPACE_VOS(OThread
)::getCurrentIdentifier())
83 fprintf( stderr
, "\n\n--- A different thread owns the mutex ...---\n\n\n");
91 void GtkHookedYieldMutex::acquire()
93 SalYieldMutex::acquire();
96 void GtkHookedYieldMutex::release()
98 SalYieldMutex::release();
103 #define GET_YIELD_MUTEX() static_cast<GtkHookedYieldMutex*>(GetSalData()->m_pInstance->GetYieldMutex())
104 static void GdkThreadsEnter( void )
106 GtkHookedYieldMutex
*pYieldMutex
= GET_YIELD_MUTEX();
107 pYieldMutex
->ThreadsEnter();
109 static void GdkThreadsLeave( void )
111 GtkHookedYieldMutex
*pYieldMutex
= GET_YIELD_MUTEX();
112 pYieldMutex
->ThreadsLeave();
114 static bool hookLocks( oslModule pModule
)
116 typedef void (*GdkLockFn
) (GCallback enter_fn
, GCallback leave_fn
);
118 GdkLockFn gdk_threads_set_lock_functions
=
119 (GdkLockFn
) osl_getAsciiFunctionSymbol( pModule
, "gdk_threads_set_lock_functions" );
120 if ( !gdk_threads_set_lock_functions
)
122 #if OSL_DEBUG_LEVEL > 1
123 fprintf( stderr
, "Failed to hook gdk threads locks\n" );
128 gdk_threads_set_lock_functions (GdkThreadsEnter
, GdkThreadsLeave
);
129 #if OSL_DEBUG_LEVEL > 1
130 fprintf( stderr
, "Hooked gdk threads locks\n" );
135 VCL_DLLPUBLIC SalInstance
* create_SalInstance( oslModule pModule
)
137 #if OSL_DEBUG_LEVEL > 1
138 int nFd
= open( "/home/pl93762/log.txt", O_CREAT
| O_TRUNC
| O_WRONLY
, 0755 );
139 dup2( nFd
, STDERR_FILENO
);
142 const gchar
* pVersion
= gtk_check_version( 2, 2, 0 );
145 #if OSL_DEBUG_LEVEL > 1
146 fprintf( stderr
, "gtk version conflict: %s\n", pVersion
);
151 GtkYieldMutex
*pYieldMutex
;
153 // init gdk thread protection
154 if ( !g_thread_supported() )
155 g_thread_init( NULL
);
157 if ( hookLocks( pModule
) )
158 pYieldMutex
= new GtkHookedYieldMutex();
160 pYieldMutex
= new GtkYieldMutex();
164 GtkInstance
* pInstance
= new GtkInstance( pYieldMutex
);
165 #if OSL_DEBUG_LEVEL > 1
166 fprintf( stderr
, "creating GtkSalInstance 0x%p\n", pInstance
);
169 // initialize SalData
170 GtkData
*pSalData
= new GtkData();
171 SetSalData( pSalData
);
172 pSalData
->m_pInstance
= pInstance
;
182 GtkInstance::~GtkInstance()
187 SalFrame
* GtkInstance::CreateFrame( SalFrame
* pParent
, ULONG nStyle
)
189 return new GtkSalFrame( pParent
, nStyle
);
192 SalFrame
* GtkInstance::CreateChildFrame( SystemParentData
* pParentData
, ULONG
)
194 SalFrame
* pFrame
= new GtkSalFrame( pParentData
);
199 SalObject
* GtkInstance::CreateObject( SalFrame
* pParent
, SystemWindowData
* pWindowData
, BOOL bShow
)
201 // there is no method to set a visual for a GtkWidget
202 // so we need the X11SalObject in that case
204 return X11SalObject::CreateObject( pParent
, pWindowData
, bShow
);
206 return new GtkSalObject( static_cast<GtkSalFrame
*>(pParent
), bShow
);
209 GtkYieldMutex::GtkYieldMutex()
213 void GtkYieldMutex::acquire()
215 vos::OThread::TThreadIdentifier aCurrentThread
= vos::OThread::getCurrentIdentifier();
216 // protect member manipulation
218 if( mnCount
> 0 && mnThreadId
== aCurrentThread
)
229 // obtained gdk mutex, now lock count is one by definition
232 mnThreadId
= aCurrentThread
;
236 void GtkYieldMutex::release()
238 vos::OThread::TThreadIdentifier aCurrentThread
= vos::OThread::getCurrentIdentifier();
239 // protect member manipulation
241 // strange things happen, do nothing if we don't own the mutex
242 if( mnThreadId
== aCurrentThread
)
254 sal_Bool
GtkYieldMutex::tryToAcquire()
256 vos::OThread::TThreadIdentifier aCurrentThread
= vos::OThread::getCurrentIdentifier();
257 // protect member manipulation
261 if( mnThreadId
== aCurrentThread
)
275 // HACK: gdk_threads_mutex is private, we shouldn't use it.
276 // how to we do a try_lock without having a gdk_threads_try_enter ?
277 if( ! g_mutex_trylock( gdk_threads_mutex
) )
280 // obtained gdk mutex, now lock count is one by definition
283 mnThreadId
= aCurrentThread
;
289 int GtkYieldMutex::Grab()
291 // this MUST only be called by gdk/gtk callbacks:
292 // they are entered with gdk mutex locked; the mutex
293 // was unlocked by GtkYieldMutex befor yielding which
294 // is now locked again by gtk implicitly
296 // obtained gdk mutex, now lock count is one by definition
299 if( mnCount
== 0 ) // recursive else
300 mnThreadId
= vos::OThread::getCurrentIdentifier();
301 #if OSL_DEBUG_LEVEL > 1
302 else if( mnThreadId
!= vos::OThread::getCurrentIdentifier() )
304 fprintf( stderr
, "Yield mutex grabbed in different thread !\n" );
313 void GtkYieldMutex::Ungrab( int nGrabs
)
315 // this MUST only be called when leaving the callback
316 // that locked the mutex with Grab()