Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <string.h>
31 : : #include <stdio.h>
32 : : #include <stdlib.h>
33 : :
34 : : #include "osl/module.hxx"
35 : :
36 : : #include "unx/salunx.h"
37 : : #include "unx/saldata.hxx"
38 : : #include "unx/saldisp.hxx"
39 : : #include "generic/geninst.h"
40 : : #include "generic/genpspgraphics.h"
41 : : #include "unx/salframe.h"
42 : : #include "generic/genprn.h"
43 : : #include "unx/sm.hxx"
44 : :
45 : : #include "vcl/apptypes.hxx"
46 : : #include "vcl/helper.hxx"
47 : :
48 : : #include "salwtype.hxx"
49 : : #include <sal/macros.h>
50 : :
51 : : //----------------------------------------------------------------------------
52 : :
53 : : // -=-= SalInstance =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
54 : : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
55 : :
56 : : // plugin factory function
57 : : extern "C"
58 : : {
59 : 0 : VCLPLUG_GEN_PUBLIC SalInstance* create_SalInstance()
60 : : {
61 : : /* #i92121# workaround deadlocks in the X11 implementation
62 : : */
63 : 0 : static const char* pNoXInitThreads = getenv( "SAL_NO_XINITTHREADS" );
64 : : /* #i90094#
65 : : from now on we know that an X connection will be
66 : : established, so protect X against itself
67 : : */
68 : 0 : if( ! ( pNoXInitThreads && *pNoXInitThreads ) )
69 : 0 : XInitThreads();
70 : :
71 : 0 : X11SalInstance* pInstance = new X11SalInstance( new SalYieldMutex() );
72 : :
73 : : // initialize SalData
74 : 0 : X11SalData *pSalData = new X11SalData( SAL_DATA_UNX, pInstance );
75 : :
76 : 0 : pSalData->Init();
77 : 0 : pInstance->SetLib( pSalData->GetLib() );
78 : :
79 : 0 : return pInstance;
80 : : }
81 : : }
82 : :
83 : 0 : X11SalInstance::~X11SalInstance()
84 : : {
85 : : // close session management
86 : 0 : SessionManagerClient::close();
87 : :
88 : : // dispose SalDisplay list from SalData
89 : : // would be done in a static destructor else which is
90 : : // a little late
91 : 0 : GetGenericData()->Dispose();
92 : 0 : }
93 : :
94 : :
95 : : // --------------------------------------------------------
96 : : // AnyInput from sv/mow/source/app/svapp.cxx
97 : :
98 : : struct PredicateReturn
99 : : {
100 : : sal_uInt16 nType;
101 : : sal_Bool bRet;
102 : : };
103 : :
104 : : extern "C" {
105 : 0 : Bool ImplPredicateEvent( Display *, XEvent *pEvent, char *pData )
106 : : {
107 : 0 : PredicateReturn *pPre = (PredicateReturn *)pData;
108 : :
109 : 0 : if ( pPre->bRet )
110 : 0 : return False;
111 : :
112 : : sal_uInt16 nType;
113 : :
114 : 0 : switch( pEvent->type )
115 : : {
116 : : case ButtonPress:
117 : : case ButtonRelease:
118 : : case MotionNotify:
119 : : case EnterNotify:
120 : : case LeaveNotify:
121 : 0 : nType = VCL_INPUT_MOUSE;
122 : 0 : break;
123 : :
124 : : case XLIB_KeyPress:
125 : : //case KeyRelease:
126 : 0 : nType = VCL_INPUT_KEYBOARD;
127 : 0 : break;
128 : : case Expose:
129 : : case GraphicsExpose:
130 : : case NoExpose:
131 : 0 : nType = VCL_INPUT_PAINT;
132 : 0 : break;
133 : : default:
134 : 0 : nType = 0;
135 : : }
136 : :
137 : 0 : if ( (nType & pPre->nType) || ( ! nType && (pPre->nType & VCL_INPUT_OTHER) ) )
138 : 0 : pPre->bRet = sal_True;
139 : :
140 : 0 : return False;
141 : : }
142 : : }
143 : :
144 : 0 : bool X11SalInstance::AnyInput(sal_uInt16 nType)
145 : : {
146 : 0 : SalGenericData *pData = GetGenericData();
147 : 0 : Display *pDisplay = pData->GetSalDisplay()->GetDisplay();
148 : 0 : sal_Bool bRet = sal_False;
149 : :
150 : 0 : if( (nType & VCL_INPUT_TIMER) && (mpXLib && mpXLib->CheckTimeout(false)) )
151 : 0 : bRet = sal_True;
152 : 0 : else if (XPending(pDisplay) )
153 : : {
154 : : PredicateReturn aInput;
155 : : XEvent aEvent;
156 : :
157 : 0 : aInput.bRet = sal_False;
158 : 0 : aInput.nType = nType;
159 : :
160 : : XCheckIfEvent(pDisplay, &aEvent, ImplPredicateEvent,
161 : 0 : (char *)&aInput );
162 : :
163 : 0 : bRet = aInput.bRet;
164 : : }
165 : : #if OSL_DEBUG_LEVEL > 1
166 : : fprintf( stderr, "AnyInput 0x%x = %s\n", nType, bRet ? "true" : "false" );
167 : : #endif
168 : 0 : return bRet;
169 : : }
170 : :
171 : 0 : void X11SalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
172 : : {
173 : 0 : mpXLib->Yield( bWait, bHandleAllCurrentEvents );
174 : 0 : }
175 : :
176 : 0 : void* X11SalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType,
177 : : int& rReturnedBytes )
178 : : {
179 : 0 : static const char* pDisplay = getenv( "DISPLAY" );
180 : 0 : rReturnedType = AsciiCString;
181 : 0 : rReturnedBytes = pDisplay ? strlen( pDisplay )+1 : 1;
182 : 0 : return pDisplay ? (void*)pDisplay : (void*)"";
183 : : }
184 : :
185 : 0 : SalFrame *X11SalInstance::CreateFrame( SalFrame *pParent, sal_uLong nSalFrameStyle )
186 : : {
187 : 0 : SalFrame *pFrame = new X11SalFrame( pParent, nSalFrameStyle );
188 : :
189 : 0 : return pFrame;
190 : : }
191 : :
192 : 0 : SalFrame* X11SalInstance::CreateChildFrame( SystemParentData* pParentData, sal_uLong nStyle )
193 : : {
194 : 0 : SalFrame* pFrame = new X11SalFrame( NULL, nStyle, pParentData );
195 : :
196 : 0 : return pFrame;
197 : : }
198 : :
199 : 0 : void X11SalInstance::DestroyFrame( SalFrame* pFrame )
200 : : {
201 : 0 : delete pFrame;
202 : 0 : }
203 : :
204 : 0 : static void getServerDirectories( std::list< rtl::OString >& o_rFontPaths )
205 : : {
206 : : #ifdef LINUX
207 : : /*
208 : : * chkfontpath exists on some (RH derived) Linux distributions
209 : : */
210 : : static const char* pCommands[] = {
211 : : "/usr/sbin/chkfontpath 2>/dev/null", "chkfontpath 2>/dev/null"
212 : : };
213 : 0 : ::std::list< rtl::OString > aLines;
214 : :
215 : 0 : for( unsigned int i = 0; i < SAL_N_ELEMENTS(pCommands); i++ )
216 : : {
217 : 0 : FILE* pPipe = popen( pCommands[i], "r" );
218 : 0 : aLines.clear();
219 : 0 : if( pPipe )
220 : : {
221 : : char line[1024];
222 : : char* pSearch;
223 : 0 : while( fgets( line, sizeof(line), pPipe ) )
224 : : {
225 : 0 : int nLen = strlen( line );
226 : 0 : if( line[nLen-1] == '\n' )
227 : 0 : line[nLen-1] = 0;
228 : 0 : pSearch = strstr( line, ": " );
229 : 0 : if( pSearch )
230 : 0 : aLines.push_back( pSearch+2 );
231 : : }
232 : 0 : if( ! pclose( pPipe ) )
233 : : break;
234 : : }
235 : : }
236 : :
237 : 0 : for( ::std::list< rtl::OString >::iterator it = aLines.begin(); it != aLines.end(); ++it )
238 : : {
239 : 0 : if( ! access( it->getStr(), F_OK ) )
240 : : {
241 : 0 : o_rFontPaths.push_back( *it );
242 : : #if OSL_DEBUG_LEVEL > 1
243 : : fprintf( stderr, "adding fs dir %s\n", it->getStr() );
244 : : #endif
245 : : }
246 : 0 : }
247 : : #else
248 : : (void)o_rFontPaths;
249 : : #endif
250 : 0 : }
251 : :
252 : :
253 : :
254 : 0 : void X11SalInstance::FillFontPathList( std::list< rtl::OString >& o_rFontPaths )
255 : : {
256 : 0 : Display *pDisplay = GetGenericData()->GetSalDisplay()->GetDisplay();
257 : :
258 : : DBG_ASSERT( pDisplay, "No Display !" );
259 : 0 : if( pDisplay )
260 : : {
261 : : // get font paths to look for fonts
262 : 0 : int nPaths = 0, i;
263 : 0 : char** pPaths = XGetFontPath( pDisplay, &nPaths );
264 : :
265 : 0 : bool bServerDirs = false;
266 : 0 : for( i = 0; i < nPaths; i++ )
267 : : {
268 : 0 : OString aPath( pPaths[i] );
269 : 0 : sal_Int32 nPos = 0;
270 : 0 : if( ! bServerDirs
271 : : && ( nPos = aPath.indexOf( ':' ) ) > 0
272 : 0 : && ( !aPath.copy(nPos).equals( ":unscaled" ) ) )
273 : : {
274 : 0 : bServerDirs = true;
275 : 0 : getServerDirectories( o_rFontPaths );
276 : : }
277 : : else
278 : : {
279 : 0 : psp::normPath( aPath );
280 : 0 : o_rFontPaths.push_back( aPath );
281 : : }
282 : 0 : }
283 : :
284 : 0 : if( nPaths )
285 : 0 : XFreeFontPath( pPaths );
286 : : }
287 : :
288 : : // insert some standard directories
289 : 0 : o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/TrueType" );
290 : 0 : o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/Type1" );
291 : 0 : o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/Type1/sun" );
292 : 0 : o_rFontPaths.push_back( "/usr/X11R6/lib/X11/fonts/truetype" );
293 : 0 : o_rFontPaths.push_back( "/usr/X11R6/lib/X11/fonts/Type1" );
294 : :
295 : : #ifdef SOLARIS
296 : : /* cde specials, from /usr/dt/bin/Xsession: here are the good fonts,
297 : : the OWfontpath file may contain as well multiple lines as a comma
298 : : separated list of fonts in each line. to make it even more weird
299 : : environment variables are allowed as well */
300 : :
301 : : const char* lang = getenv("LANG");
302 : : if ( lang != NULL )
303 : : {
304 : : String aOpenWinDir( String::CreateFromAscii( "/usr/openwin/lib/locale/" ) );
305 : : aOpenWinDir.AppendAscii( lang );
306 : : aOpenWinDir.AppendAscii( "/OWfontpath" );
307 : :
308 : : SvFileStream aStream( aOpenWinDir, STREAM_READ );
309 : :
310 : : // TODO: replace environment variables
311 : : while( aStream.IsOpen() && ! aStream.IsEof() )
312 : : {
313 : : rtl::OString aLine;
314 : : aStream.ReadLine( aLine );
315 : : psp::normPath( aLine );
316 : : // try to avoid bad fonts in some cases
317 : : static bool bAvoid = (strncasecmp( lang, "ar", 2 ) == 0) || (strncasecmp( lang, "he", 2 ) == 0) || strncasecmp( lang, "iw", 2 ) == 0 || (strncasecmp( lang, "hi", 2 ) == 0);
318 : : if( bAvoid && aLine.indexOfL(RTL_CONSTASCII_STRINGPARAM("iso_8859")) != -1 )
319 : : continue;
320 : : o_rFontPaths.push_back( aLine );
321 : : }
322 : : }
323 : : #endif /* SOLARIS */
324 : 0 : }
325 : :
326 : 0 : extern "C" { static void SAL_CALL thisModule() {} }
327 : :
328 : 0 : void X11SalInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType)
329 : : {
330 : 0 : const rtl::OUString SYM_ADD_TO_RECENTLY_USED_FILE_LIST(RTL_CONSTASCII_USTRINGPARAM("add_to_recently_used_file_list"));
331 : 0 : const rtl::OUString LIB_RECENT_FILE(RTL_CONSTASCII_USTRINGPARAM("librecentfile.so"));
332 : : typedef void (*PFUNC_ADD_TO_RECENTLY_USED_LIST)(const rtl::OUString&, const rtl::OUString&);
333 : :
334 : 0 : PFUNC_ADD_TO_RECENTLY_USED_LIST add_to_recently_used_file_list = 0;
335 : :
336 : 0 : osl::Module module;
337 : 0 : module.loadRelative( &thisModule, LIB_RECENT_FILE );
338 : 0 : if (module.is())
339 : 0 : add_to_recently_used_file_list = (PFUNC_ADD_TO_RECENTLY_USED_LIST)module.getFunctionSymbol(SYM_ADD_TO_RECENTLY_USED_FILE_LIST);
340 : 0 : if (add_to_recently_used_file_list)
341 : 0 : add_to_recently_used_file_list(rFileUrl, rMimeType);
342 : 0 : }
343 : :
344 : 0 : void X11SalInstance::PostPrintersChanged()
345 : : {
346 : 0 : SalDisplay* pDisp = GetGenericData()->GetSalDisplay();
347 : 0 : const std::list< SalFrame* >& rList = pDisp->getFrames();
348 : 0 : for( std::list< SalFrame* >::const_iterator it = rList.begin();
349 : 0 : it != rList.end(); ++it )
350 : 0 : pDisp->SendInternalEvent( *it, NULL, SALEVENT_PRINTERCHANGED );
351 : 0 : }
352 : :
353 : 0 : GenPspGraphics *X11SalInstance::CreatePrintGraphics()
354 : : {
355 : 0 : return new GenPspGraphics();
356 : : }
357 : :
358 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|