bump product version to 5.0.4.1
[LibreOffice.git] / vcl / unx / generic / app / salinst.cxx
blob9c00f6d5a468353a0b9ea00769c0af2e9e6b6781
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
21 #include <stdio.h>
22 #include <stdlib.h>
24 #include "osl/module.hxx"
26 #include "unx/salunx.h"
27 #include "unx/saldata.hxx"
28 #include "unx/saldisp.hxx"
29 #include "generic/geninst.h"
30 #include "generic/genpspgraphics.h"
31 #include "unx/salframe.h"
32 #include "generic/genprn.h"
33 #include "unx/sm.hxx"
35 #include "vcl/apptypes.hxx"
36 #include "vcl/helper.hxx"
38 #include "salwtype.hxx"
39 #include <sal/macros.h>
41 // plugin factory function
42 extern "C"
44 VCLPLUG_GEN_PUBLIC SalInstance* create_SalInstance()
46 /* #i92121# workaround deadlocks in the X11 implementation
48 static const char* pNoXInitThreads = getenv( "SAL_NO_XINITTHREADS" );
49 /* #i90094#
50 from now on we know that an X connection will be
51 established, so protect X against itself
53 if( ! ( pNoXInitThreads && *pNoXInitThreads ) )
54 XInitThreads();
56 X11SalInstance* pInstance = new X11SalInstance( new SalYieldMutex() );
58 // initialize SalData
59 X11SalData *pSalData = new X11SalData( SAL_DATA_UNX, pInstance );
61 pSalData->Init();
62 pInstance->SetLib( pSalData->GetLib() );
64 return pInstance;
68 X11SalInstance::~X11SalInstance()
70 // close session management
71 SessionManagerClient::close();
73 // dispose SalDisplay list from SalData
74 // would be done in a static destructor else which is
75 // a little late
76 GetGenericData()->Dispose();
79 // AnyInput from sv/mow/source/app/svapp.cxx
81 struct PredicateReturn
83 VclInputFlags nType;
84 bool bRet;
87 extern "C" {
88 Bool ImplPredicateEvent( Display *, XEvent *pEvent, char *pData )
90 PredicateReturn *pPre = reinterpret_cast<PredicateReturn *>(pData);
92 if ( pPre->bRet )
93 return False;
95 VclInputFlags nType;
97 switch( pEvent->type )
99 case ButtonPress:
100 case ButtonRelease:
101 case MotionNotify:
102 case EnterNotify:
103 case LeaveNotify:
104 nType = VclInputFlags::MOUSE;
105 break;
107 case KeyPress:
108 //case KeyRelease:
109 nType = VclInputFlags::KEYBOARD;
110 break;
111 case Expose:
112 case GraphicsExpose:
113 case NoExpose:
114 nType = VclInputFlags::PAINT;
115 break;
116 default:
117 nType = VclInputFlags::NONE;
120 if ( (nType & pPre->nType) || ( nType == VclInputFlags::NONE && (pPre->nType & VclInputFlags::OTHER) ) )
121 pPre->bRet = true;
123 return False;
127 bool X11SalInstance::AnyInput(VclInputFlags nType)
129 SalGenericData *pData = GetGenericData();
130 Display *pDisplay = vcl_sal::getSalDisplay(pData)->GetDisplay();
131 bool bRet = false;
133 if( (nType & VclInputFlags::TIMER) && (mpXLib && mpXLib->CheckTimeout(false)) )
134 bRet = true;
135 else if (XPending(pDisplay) )
137 PredicateReturn aInput;
138 XEvent aEvent;
140 aInput.bRet = false;
141 aInput.nType = nType;
143 XCheckIfEvent(pDisplay, &aEvent, ImplPredicateEvent,
144 reinterpret_cast<char *>(&aInput) );
146 bRet = aInput.bRet;
148 #if OSL_DEBUG_LEVEL > 1
149 fprintf( stderr, "AnyInput 0x%x = %s\n", static_cast<unsigned int>(nType), bRet ? "true" : "false" );
150 #endif
151 return bRet;
154 void X11SalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
156 mpXLib->Yield( bWait, bHandleAllCurrentEvents );
159 void* X11SalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType,
160 int& rReturnedBytes )
162 static const char* pDisplay = getenv( "DISPLAY" );
163 rReturnedType = AsciiCString;
164 rReturnedBytes = pDisplay ? strlen( pDisplay )+1 : 1;
165 return pDisplay ? (void*)pDisplay : (void*)"";
168 SalFrame *X11SalInstance::CreateFrame( SalFrame *pParent, sal_uLong nSalFrameStyle )
170 SalFrame *pFrame = new X11SalFrame( pParent, nSalFrameStyle );
172 return pFrame;
175 SalFrame* X11SalInstance::CreateChildFrame( SystemParentData* pParentData, sal_uLong nStyle )
177 SalFrame* pFrame = new X11SalFrame( NULL, nStyle, pParentData );
179 return pFrame;
182 void X11SalInstance::DestroyFrame( SalFrame* pFrame )
184 delete pFrame;
187 static void getServerDirectories( std::list< OString >& o_rFontPaths )
189 #ifdef LINUX
191 * chkfontpath exists on some (RH derived) Linux distributions
193 static const char* pCommands[] = {
194 "/usr/sbin/chkfontpath 2>/dev/null", "chkfontpath 2>/dev/null"
196 ::std::list< OString > aLines;
198 for( unsigned int i = 0; i < SAL_N_ELEMENTS(pCommands); i++ )
200 FILE* pPipe = popen( pCommands[i], "r" );
201 aLines.clear();
202 if( pPipe )
204 char line[1024];
205 while( fgets( line, sizeof(line), pPipe ) )
207 int nLen = strlen( line );
208 if( line[nLen-1] == '\n' )
209 line[nLen-1] = 0;
210 char* pSearch = strstr( line, ": " );
211 if( pSearch )
212 aLines.push_back( pSearch+2 );
214 if( ! pclose( pPipe ) )
215 break;
219 for( ::std::list< OString >::iterator it = aLines.begin(); it != aLines.end(); ++it )
221 if( ! access( it->getStr(), F_OK ) )
223 o_rFontPaths.push_back( *it );
224 #if OSL_DEBUG_LEVEL > 1
225 fprintf( stderr, "adding fs dir %s\n", it->getStr() );
226 #endif
229 #else
230 (void)o_rFontPaths;
231 #endif
234 void X11SalInstance::FillFontPathList( std::list< OString >& o_rFontPaths )
236 Display *pDisplay = vcl_sal::getSalDisplay(GetGenericData())->GetDisplay();
238 DBG_ASSERT( pDisplay, "No Display !" );
239 if( pDisplay )
241 // get font paths to look for fonts
242 int nPaths = 0, i;
243 char** pPaths = XGetFontPath( pDisplay, &nPaths );
245 bool bServerDirs = false;
246 for( i = 0; i < nPaths; i++ )
248 OString aPath( pPaths[i] );
249 sal_Int32 nPos = 0;
250 if( ! bServerDirs
251 && ( nPos = aPath.indexOf( ':' ) ) > 0
252 && ( !aPath.copy(nPos).equals( ":unscaled" ) ) )
254 bServerDirs = true;
255 getServerDirectories( o_rFontPaths );
257 else
259 psp::normPath( aPath );
260 o_rFontPaths.push_back( aPath );
264 if( nPaths )
265 XFreeFontPath( pPaths );
268 // insert some standard directories
269 o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/TrueType" );
270 o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/Type1" );
271 o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/Type1/sun" );
272 o_rFontPaths.push_back( "/usr/X11R6/lib/X11/fonts/truetype" );
273 o_rFontPaths.push_back( "/usr/X11R6/lib/X11/fonts/Type1" );
275 #ifdef SOLARIS
276 /* cde specials, from /usr/dt/bin/Xsession: here are the good fonts,
277 the OWfontpath file may contain as well multiple lines as a comma
278 separated list of fonts in each line. to make it even more weird
279 environment variables are allowed as well */
281 const char* lang = getenv("LANG");
282 if ( lang != NULL )
284 OUString aOpenWinDir( "/usr/openwin/lib/locale/" );
285 aOpenWinDir += OUString::createFromAscii( lang );
286 aOpenWinDir += "/OWfontpath";
288 SvFileStream aStream( aOpenWinDir, StreamMode::READ );
290 // TODO: replace environment variables
291 while( aStream.IsOpen() && ! aStream.IsEof() )
293 OString aLine;
294 aStream.ReadLine( aLine );
295 psp::normPath( aLine );
296 // try to avoid bad fonts in some cases
297 static bool bAvoid = (strncasecmp( lang, "ar", 2 ) == 0) || (strncasecmp( lang, "he", 2 ) == 0) || strncasecmp( lang, "iw", 2 ) == 0 || (strncasecmp( lang, "hi", 2 ) == 0);
298 if( bAvoid && aLine.indexOf("iso_8859") != -1 )
299 continue;
300 o_rFontPaths.push_back( aLine );
303 #endif /* SOLARIS */
306 extern "C" { static void SAL_CALL thisModule() {} }
308 void X11SalInstance::AddToRecentDocumentList(const OUString& rFileUrl, const OUString& rMimeType, const OUString& rDocumentService)
310 const OUString SYM_ADD_TO_RECENTLY_USED_FILE_LIST("add_to_recently_used_file_list");
311 const OUString LIB_RECENT_FILE("librecentfile.so");
312 typedef void (*PFUNC_ADD_TO_RECENTLY_USED_LIST)(const OUString&, const OUString&, const OUString&);
314 PFUNC_ADD_TO_RECENTLY_USED_LIST add_to_recently_used_file_list = 0;
316 osl::Module module;
317 module.loadRelative( &thisModule, LIB_RECENT_FILE );
318 if (module.is())
319 add_to_recently_used_file_list = reinterpret_cast<PFUNC_ADD_TO_RECENTLY_USED_LIST>(module.getFunctionSymbol(SYM_ADD_TO_RECENTLY_USED_FILE_LIST));
320 if (add_to_recently_used_file_list)
321 add_to_recently_used_file_list(rFileUrl, rMimeType, rDocumentService);
324 void X11SalInstance::PostPrintersChanged()
326 SalDisplay* pDisp = vcl_sal::getSalDisplay(GetGenericData());
327 const std::list< SalFrame* >& rList = pDisp->getFrames();
328 for( std::list< SalFrame* >::const_iterator it = rList.begin();
329 it != rList.end(); ++it )
330 pDisp->SendInternalEvent( *it, NULL, SALEVENT_PRINTERCHANGED );
333 GenPspGraphics *X11SalInstance::CreatePrintGraphics()
335 return new GenPspGraphics();
338 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */