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 : #include <string.h>
21 : #include <stdio.h>
22 : #include <stdlib.h>
23 :
24 : #include "osl/module.hxx"
25 :
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"
34 :
35 : #include "vcl/apptypes.hxx"
36 : #include "vcl/helper.hxx"
37 :
38 : #include "salwtype.hxx"
39 : #include <sal/macros.h>
40 :
41 : // plugin factory function
42 : extern "C"
43 : {
44 0 : VCLPLUG_GEN_PUBLIC SalInstance* create_SalInstance()
45 : {
46 : /* #i92121# workaround deadlocks in the X11 implementation
47 : */
48 0 : 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
52 : */
53 0 : if( ! ( pNoXInitThreads && *pNoXInitThreads ) )
54 0 : XInitThreads();
55 :
56 0 : X11SalInstance* pInstance = new X11SalInstance( new SalYieldMutex() );
57 :
58 : // initialize SalData
59 0 : X11SalData *pSalData = new X11SalData( SAL_DATA_UNX, pInstance );
60 :
61 0 : pSalData->Init();
62 0 : pInstance->SetLib( pSalData->GetLib() );
63 :
64 0 : return pInstance;
65 : }
66 : }
67 :
68 2 : X11SalInstance::~X11SalInstance()
69 : {
70 : // close session management
71 1 : SessionManagerClient::close();
72 :
73 : // dispose SalDisplay list from SalData
74 : // would be done in a static destructor else which is
75 : // a little late
76 1 : GetGenericData()->Dispose();
77 1 : }
78 :
79 : // AnyInput from sv/mow/source/app/svapp.cxx
80 :
81 : struct PredicateReturn
82 : {
83 : VclInputFlags nType;
84 : bool bRet;
85 : };
86 :
87 : extern "C" {
88 22159 : Bool ImplPredicateEvent( Display *, XEvent *pEvent, char *pData )
89 : {
90 22159 : PredicateReturn *pPre = reinterpret_cast<PredicateReturn *>(pData);
91 :
92 22159 : if ( pPre->bRet )
93 0 : return False;
94 :
95 : VclInputFlags nType;
96 :
97 22159 : switch( pEvent->type )
98 : {
99 : case ButtonPress:
100 : case ButtonRelease:
101 : case MotionNotify:
102 : case EnterNotify:
103 : case LeaveNotify:
104 0 : nType = VclInputFlags::MOUSE;
105 0 : break;
106 :
107 : case KeyPress:
108 : //case KeyRelease:
109 0 : nType = VclInputFlags::KEYBOARD;
110 0 : break;
111 : case Expose:
112 : case GraphicsExpose:
113 : case NoExpose:
114 0 : nType = VclInputFlags::PAINT;
115 0 : break;
116 : default:
117 22159 : nType = VclInputFlags::NONE;
118 : }
119 :
120 22159 : if ( (nType & pPre->nType) || ( nType == VclInputFlags::NONE && (pPre->nType & VclInputFlags::OTHER) ) )
121 0 : pPre->bRet = true;
122 :
123 22159 : return False;
124 : }
125 : }
126 :
127 56 : bool X11SalInstance::AnyInput(VclInputFlags nType)
128 : {
129 56 : SalGenericData *pData = GetGenericData();
130 56 : Display *pDisplay = vcl_sal::getSalDisplay(pData)->GetDisplay();
131 56 : bool bRet = false;
132 :
133 56 : if( (nType & VclInputFlags::TIMER) && (mpXLib && mpXLib->CheckTimeout(false)) )
134 0 : bRet = true;
135 56 : else if (XPending(pDisplay) )
136 : {
137 : PredicateReturn aInput;
138 : XEvent aEvent;
139 :
140 56 : aInput.bRet = false;
141 56 : aInput.nType = nType;
142 :
143 : XCheckIfEvent(pDisplay, &aEvent, ImplPredicateEvent,
144 56 : reinterpret_cast<char *>(&aInput) );
145 :
146 56 : bRet = aInput.bRet;
147 : }
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 56 : return bRet;
152 : }
153 :
154 0 : void X11SalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
155 : {
156 0 : mpXLib->Yield( bWait, bHandleAllCurrentEvents );
157 0 : }
158 :
159 3 : void* X11SalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType,
160 : int& rReturnedBytes )
161 : {
162 3 : static const char* pDisplay = getenv( "DISPLAY" );
163 3 : rReturnedType = AsciiCString;
164 3 : rReturnedBytes = pDisplay ? strlen( pDisplay )+1 : 1;
165 3 : return pDisplay ? const_cast<char *>(pDisplay) : const_cast<char *>("");
166 : }
167 :
168 0 : SalFrame *X11SalInstance::CreateFrame( SalFrame *pParent, sal_uLong nSalFrameStyle )
169 : {
170 0 : SalFrame *pFrame = new X11SalFrame( pParent, nSalFrameStyle );
171 :
172 0 : return pFrame;
173 : }
174 :
175 0 : SalFrame* X11SalInstance::CreateChildFrame( SystemParentData* pParentData, sal_uLong nStyle )
176 : {
177 0 : SalFrame* pFrame = new X11SalFrame( NULL, nStyle, pParentData );
178 :
179 0 : return pFrame;
180 : }
181 :
182 13 : void X11SalInstance::DestroyFrame( SalFrame* pFrame )
183 : {
184 13 : delete pFrame;
185 13 : }
186 :
187 0 : static void getServerDirectories( std::list< OString >& o_rFontPaths )
188 : {
189 : #ifdef LINUX
190 : /*
191 : * chkfontpath exists on some (RH derived) Linux distributions
192 : */
193 : static const char* pCommands[] = {
194 : "/usr/sbin/chkfontpath 2>/dev/null", "chkfontpath 2>/dev/null"
195 : };
196 0 : ::std::list< OString > aLines;
197 :
198 0 : for( unsigned int i = 0; i < SAL_N_ELEMENTS(pCommands); i++ )
199 : {
200 0 : FILE* pPipe = popen( pCommands[i], "r" );
201 0 : aLines.clear();
202 0 : if( pPipe )
203 : {
204 : char line[1024];
205 0 : while( fgets( line, sizeof(line), pPipe ) )
206 : {
207 0 : int nLen = strlen( line );
208 0 : if( line[nLen-1] == '\n' )
209 0 : line[nLen-1] = 0;
210 0 : char* pSearch = strstr( line, ": " );
211 0 : if( pSearch )
212 0 : aLines.push_back( pSearch+2 );
213 : }
214 0 : if( ! pclose( pPipe ) )
215 0 : break;
216 : }
217 : }
218 :
219 0 : for( ::std::list< OString >::iterator it = aLines.begin(); it != aLines.end(); ++it )
220 : {
221 0 : if( ! access( it->getStr(), F_OK ) )
222 : {
223 0 : o_rFontPaths.push_back( *it );
224 : #if OSL_DEBUG_LEVEL > 1
225 : fprintf( stderr, "adding fs dir %s\n", it->getStr() );
226 : #endif
227 : }
228 0 : }
229 : #else
230 : (void)o_rFontPaths;
231 : #endif
232 0 : }
233 :
234 0 : void X11SalInstance::FillFontPathList( std::list< OString >& o_rFontPaths )
235 : {
236 0 : Display *pDisplay = vcl_sal::getSalDisplay(GetGenericData())->GetDisplay();
237 :
238 : DBG_ASSERT( pDisplay, "No Display !" );
239 0 : if( pDisplay )
240 : {
241 : // get font paths to look for fonts
242 0 : int nPaths = 0, i;
243 0 : char** pPaths = XGetFontPath( pDisplay, &nPaths );
244 :
245 0 : bool bServerDirs = false;
246 0 : for( i = 0; i < nPaths; i++ )
247 : {
248 0 : OString aPath( pPaths[i] );
249 0 : sal_Int32 nPos = 0;
250 0 : if( ! bServerDirs
251 0 : && ( nPos = aPath.indexOf( ':' ) ) > 0
252 0 : && ( !aPath.copy(nPos).equals( ":unscaled" ) ) )
253 : {
254 0 : bServerDirs = true;
255 0 : getServerDirectories( o_rFontPaths );
256 : }
257 : else
258 : {
259 0 : psp::normPath( aPath );
260 0 : o_rFontPaths.push_back( aPath );
261 : }
262 0 : }
263 :
264 0 : if( nPaths )
265 0 : XFreeFontPath( pPaths );
266 : }
267 :
268 : // insert some standard directories
269 0 : o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/TrueType" );
270 0 : o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/Type1" );
271 0 : o_rFontPaths.push_back( "/usr/openwin/lib/X11/fonts/Type1/sun" );
272 0 : o_rFontPaths.push_back( "/usr/X11R6/lib/X11/fonts/truetype" );
273 0 : o_rFontPaths.push_back( "/usr/X11R6/lib/X11/fonts/Type1" );
274 :
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 */
280 :
281 : const char* lang = getenv("LANG");
282 : if ( lang != NULL )
283 : {
284 : OUString aOpenWinDir( "/usr/openwin/lib/locale/" );
285 : aOpenWinDir += OUString::createFromAscii( lang );
286 : aOpenWinDir += "/OWfontpath";
287 :
288 : SvFileStream aStream( aOpenWinDir, StreamMode::READ );
289 :
290 : // TODO: replace environment variables
291 : while( aStream.IsOpen() && ! aStream.IsEof() )
292 : {
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 );
301 : }
302 : }
303 : #endif /* SOLARIS */
304 0 : }
305 :
306 0 : extern "C" { static void SAL_CALL thisModule() {} }
307 :
308 0 : void X11SalInstance::AddToRecentDocumentList(const OUString& rFileUrl, const OUString& rMimeType, const OUString& rDocumentService)
309 : {
310 0 : const OUString SYM_ADD_TO_RECENTLY_USED_FILE_LIST("add_to_recently_used_file_list");
311 0 : const OUString LIB_RECENT_FILE("librecentfile.so");
312 : typedef void (*PFUNC_ADD_TO_RECENTLY_USED_LIST)(const OUString&, const OUString&, const OUString&);
313 :
314 0 : PFUNC_ADD_TO_RECENTLY_USED_LIST add_to_recently_used_file_list = 0;
315 :
316 0 : osl::Module module;
317 0 : module.loadRelative( &thisModule, LIB_RECENT_FILE );
318 0 : if (module.is())
319 0 : add_to_recently_used_file_list = reinterpret_cast<PFUNC_ADD_TO_RECENTLY_USED_LIST>(module.getFunctionSymbol(SYM_ADD_TO_RECENTLY_USED_FILE_LIST));
320 0 : if (add_to_recently_used_file_list)
321 0 : add_to_recently_used_file_list(rFileUrl, rMimeType, rDocumentService);
322 0 : }
323 :
324 0 : void X11SalInstance::PostPrintersChanged()
325 : {
326 0 : SalDisplay* pDisp = vcl_sal::getSalDisplay(GetGenericData());
327 0 : const std::list< SalFrame* >& rList = pDisp->getFrames();
328 0 : for( std::list< SalFrame* >::const_iterator it = rList.begin();
329 0 : it != rList.end(); ++it )
330 0 : pDisp->SendInternalEvent( *it, NULL, SALEVENT_PRINTERCHANGED );
331 0 : }
332 :
333 0 : GenPspGraphics *X11SalInstance::CreatePrintGraphics()
334 : {
335 0 : return new GenPspGraphics();
336 9 : }
337 :
338 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|