merge the formfield patch from ooo-build
[ooovba.git] / vcl / unx / source / app / salinst.cxx
blob6c1549d2e0938de20f414660a75e69d147ed3fab
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salinst.cxx,v $
10 * $Revision: 1.34.154.1 $
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 <string.h>
35 #include <stdio.h>
36 #include <stdlib.h>
38 #include <osl/module.hxx>
40 #include "salunx.h"
42 #include "saldata.hxx"
43 #include "saldisp.hxx"
44 #include "salinst.h"
45 #include "salframe.h"
46 #include "dtint.hxx"
47 #include "salprn.h"
48 #include "sm.hxx"
50 #include "vcl/salwtype.hxx"
51 #include "vcl/salatype.hxx"
52 #include "vcl/helper.hxx"
54 #include "vos/mutex.hxx"
56 // -------------------------------------------------------------------------
58 // SalYieldMutex
60 // -------------------------------------------------------------------------
62 SalYieldMutex::SalYieldMutex()
64 mnCount = 0;
65 mnThreadId = 0;
68 void SalYieldMutex::acquire()
70 OMutex::acquire();
71 mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier();
72 mnCount++;
75 void SalYieldMutex::release()
77 if ( mnThreadId == NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
79 if ( mnCount == 1 )
80 mnThreadId = 0;
81 mnCount--;
83 OMutex::release();
86 sal_Bool SalYieldMutex::tryToAcquire()
88 if ( OMutex::tryToAcquire() )
90 mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier();
91 mnCount++;
92 return True;
94 else
95 return False;
98 //----------------------------------------------------------------------------
100 // -=-= SalInstance =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
101 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
103 // plugin factory function
104 extern "C"
106 VCL_DLLPUBLIC SalInstance* create_SalInstance()
108 /* #i92121# workaround deadlocks in the X11 implementation
110 static const char* pNoXInitThreads = getenv( "SAL_NO_XINITTHREADS" );
111 /* #i90094#
112 from now on we know that an X connection will be
113 established, so protect X against itself
115 if( ! ( pNoXInitThreads && *pNoXInitThreads ) )
116 XInitThreads();
118 X11SalInstance* pInstance = new X11SalInstance( new SalYieldMutex() );
120 // initialize SalData
121 X11SalData *pSalData = new X11SalData;
122 SetSalData( pSalData );
123 pSalData->m_pInstance = pInstance;
124 pSalData->Init();
126 return pInstance;
130 X11SalInstance::~X11SalInstance()
132 // close session management
133 SessionManagerClient::close();
135 // dispose SalDisplay list from SalData
136 // would be done in a static destructor else which is
137 // a little late
139 X11SalData *pSalData = GetX11SalData();
140 pSalData->deInitNWF();
141 delete pSalData;
142 SetSalData( NULL );
144 delete mpSalYieldMutex;
148 // --------------------------------------------------------
149 // AnyInput from sv/mow/source/app/svapp.cxx
151 struct PredicateReturn
153 USHORT nType;
154 BOOL bRet;
157 extern "C" {
158 Bool ImplPredicateEvent( Display *, XEvent *pEvent, char *pData )
160 PredicateReturn *pPre = (PredicateReturn *)pData;
162 if ( pPre->bRet )
163 return False;
165 USHORT nType;
167 switch( pEvent->type )
169 case ButtonPress:
170 case ButtonRelease:
171 case MotionNotify:
172 case EnterNotify:
173 case LeaveNotify:
174 nType = INPUT_MOUSE;
175 break;
177 case XLIB_KeyPress:
178 //case KeyRelease:
179 nType = INPUT_KEYBOARD;
180 break;
181 case Expose:
182 case GraphicsExpose:
183 case NoExpose:
184 nType = INPUT_PAINT;
185 break;
186 default:
187 nType = 0;
190 if ( (nType & pPre->nType) || ( ! nType && (pPre->nType & INPUT_OTHER) ) )
191 pPre->bRet = TRUE;
193 return False;
197 bool X11SalInstance::AnyInput(USHORT nType)
199 X11SalData *pSalData = GetX11SalData();
200 Display *pDisplay = pSalData->GetDisplay()->GetDisplay();
201 BOOL bRet = FALSE;
203 if( (nType & INPUT_TIMER) &&
204 pSalData->GetDisplay()->GetXLib()->CheckTimeout( false ) )
206 bRet = TRUE;
208 else if (XPending(pDisplay) )
210 PredicateReturn aInput;
211 XEvent aEvent;
213 aInput.bRet = FALSE;
214 aInput.nType = nType;
216 XCheckIfEvent(pDisplay, &aEvent, ImplPredicateEvent,
217 (char *)&aInput );
219 bRet = aInput.bRet;
221 return bRet;
224 vos::IMutex* X11SalInstance::GetYieldMutex()
226 return mpSalYieldMutex;
229 // -----------------------------------------------------------------------
231 ULONG X11SalInstance::ReleaseYieldMutex()
233 SalYieldMutex* pYieldMutex = mpSalYieldMutex;
234 if ( pYieldMutex->GetThreadId() ==
235 NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
237 ULONG nCount = pYieldMutex->GetAcquireCount();
238 ULONG n = nCount;
239 while ( n )
241 pYieldMutex->release();
242 n--;
245 return nCount;
247 else
248 return 0;
251 // -----------------------------------------------------------------------
253 void X11SalInstance::AcquireYieldMutex( ULONG nCount )
255 SalYieldMutex* pYieldMutex = mpSalYieldMutex;
256 while ( nCount )
258 pYieldMutex->acquire();
259 nCount--;
263 void X11SalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
264 { GetX11SalData()->GetLib()->Yield( bWait, bHandleAllCurrentEvents ); }
266 void* X11SalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
268 static const char* pDisplay = getenv( "DISPLAY" );
269 rReturnedType = AsciiCString;
270 rReturnedBytes = pDisplay ? strlen( pDisplay )+1 : 1;
271 return pDisplay ? (void*)pDisplay : (void*)"";
274 SalFrame *X11SalInstance::CreateFrame( SalFrame *pParent, ULONG nSalFrameStyle )
276 SalFrame *pFrame = new X11SalFrame( pParent, nSalFrameStyle );
278 return pFrame;
281 SalFrame* X11SalInstance::CreateChildFrame( SystemParentData* pParentData, ULONG nStyle )
283 SalFrame* pFrame = new X11SalFrame( NULL, nStyle, pParentData );
285 return pFrame;
288 void X11SalInstance::DestroyFrame( SalFrame* pFrame )
290 delete pFrame;
293 static void getServerDirectories( std::list< rtl::OString >& o_rFontPaths )
295 #ifdef LINUX
297 * chkfontpath exists on some (RH derived) Linux distributions
299 static const char* pCommands[] = {
300 "/usr/sbin/chkfontpath 2>/dev/null", "chkfontpath 2>/dev/null"
302 ::std::list< ByteString > aLines;
304 for( unsigned int i = 0; i < sizeof(pCommands)/sizeof(pCommands[0]); i++ )
306 FILE* pPipe = popen( pCommands[i], "r" );
307 aLines.clear();
308 if( pPipe )
310 char line[1024];
311 char* pSearch;
312 while( fgets( line, sizeof(line), pPipe ) )
314 int nLen = strlen( line );
315 if( line[nLen-1] == '\n' )
316 line[nLen-1] = 0;
317 pSearch = strstr( line, ": " );
318 if( pSearch )
319 aLines.push_back( pSearch+2 );
321 if( ! pclose( pPipe ) )
322 break;
326 for( ::std::list< ByteString >::iterator it = aLines.begin(); it != aLines.end(); ++it )
328 if( ! access( it->GetBuffer(), F_OK ) )
330 o_rFontPaths.push_back( *it );
331 #if OSL_DEBUG_LEVEL > 1
332 fprintf( stderr, "adding fs dir %s\n", it->GetBuffer() );
333 #endif
336 #else
337 (void)o_rFontPaths;
338 #endif
343 void X11SalInstance::FillFontPathList( std::list< rtl::OString >& o_rFontPaths )
345 Display *pDisplay = GetX11SalData()->GetDisplay()->GetDisplay();
347 DBG_ASSERT( pDisplay, "No Display !" );
348 if( pDisplay )
350 // get font paths to look for fonts
351 int nPaths = 0, i;
352 char** pPaths = XGetFontPath( pDisplay, &nPaths );
354 bool bServerDirs = false;
355 for( i = 0; i < nPaths; i++ )
357 OString aPath( pPaths[i] );
358 sal_Int32 nPos = 0;
359 if( ! bServerDirs
360 && ( nPos = aPath.indexOf( ':' ) ) > 0
361 && ( !aPath.copy(nPos).equals( ":unscaled" ) ) )
363 bServerDirs = true;
364 getServerDirectories( o_rFontPaths );
366 else
368 psp::normPath( aPath );
369 o_rFontPaths.push_back( aPath );
373 if( nPaths )
374 XFreeFontPath( pPaths );
377 // insert some standard directories
378 o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/TrueType" );
379 o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/Type1" );
380 o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/Type1/sun" );
381 o_rFontPaths.push_back( "/usr/X11R6/lib/X11/fonts/truetype" );
382 o_rFontPaths.push_back( "/usr/X11R6/lib/X11/fonts/Type1" );
384 #ifdef SOLARIS
385 /* cde specials, from /usr/dt/bin/Xsession: here are the good fonts,
386 the OWfontpath file may contain as well multiple lines as a comma
387 separated list of fonts in each line. to make it even more weird
388 environment variables are allowed as well */
390 const char* lang = getenv("LANG");
391 if ( lang != NULL )
393 String aOpenWinDir( String::CreateFromAscii( "/usr/openwin/lib/locale/" ) );
394 aOpenWinDir.AppendAscii( lang );
395 aOpenWinDir.AppendAscii( "/OWfontpath" );
397 SvFileStream aStream( aOpenWinDir, STREAM_READ );
399 // TODO: replace environment variables
400 while( aStream.IsOpen() && ! aStream.IsEof() )
402 ByteString aLine;
403 aStream.ReadLine( aLine );
404 // need an OString for normpath
405 OString aNLine( aLine );
406 psp::normPath( aNLine );
407 aLine = aNLine;
408 // try to avoid bad fonts in some cases
409 static bool bAvoid = (strncasecmp( lang, "ar", 2 ) == 0) || (strncasecmp( lang, "he", 2 ) == 0) || strncasecmp( lang, "iw", 2 ) == 0 || (strncasecmp( lang, "hi", 2 ) == 0);
410 if( bAvoid && aLine.Search( "iso_8859" ) != STRING_NOTFOUND )
411 continue;
412 o_rFontPaths.push_back( aLine );
415 #endif /* SOLARIS */
418 extern "C" { static void SAL_CALL thisModule() {} }
420 void X11SalInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType)
422 const rtl::OUString SYM_ADD_TO_RECENTLY_USED_FILE_LIST(RTL_CONSTASCII_USTRINGPARAM("add_to_recently_used_file_list"));
423 const rtl::OUString LIB_RECENT_FILE(RTL_CONSTASCII_USTRINGPARAM("librecentfile.so"));
424 typedef void (*PFUNC_ADD_TO_RECENTLY_USED_LIST)(const rtl::OUString&, const rtl::OUString&);
426 PFUNC_ADD_TO_RECENTLY_USED_LIST add_to_recently_used_file_list = 0;
428 osl::Module module;
429 module.loadRelative( &thisModule, LIB_RECENT_FILE );
430 if (module.is())
431 add_to_recently_used_file_list = (PFUNC_ADD_TO_RECENTLY_USED_LIST)module.getFunctionSymbol(SYM_ADD_TO_RECENTLY_USED_FILE_LIST);
432 if (add_to_recently_used_file_list)
433 add_to_recently_used_file_list(rFileUrl, rMimeType);