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