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