xref: /aoo41x/main/vcl/unx/kde/kdedata.cxx (revision 9f62ea84)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26 
27 #define _SV_SALDATA_CXX
28 #include <shell/kde_headers.h>
29 
30 #include <unistd.h>
31 #include <fcntl.h>
32 
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <limits.h>
37 #include <errno.h>
38 #include <poll.h>
39 #ifdef FREEBSD
40 #include <sys/types.h>
41 #include <sys/time.h>
42 #include <unistd.h>
43 #endif
44 
45 #include <osl/thread.h>
46 #include <osl/process.h>
47 #include <osl/module.h>
48 
49 #include <tools/debug.hxx>
50 
51 #include <vos/process.hxx>
52 #include <vos/mutex.hxx>
53 
54 #include "unx/kde/kdedata.hxx"
55 #include "unx/i18n_im.hxx"
56 #include "unx/i18n_xkb.hxx"
57 
58 #include "vclpluginapi.h"
59 
60 /* #i59042# override KApplications method for session management
61  * since it will interfere badly with our own.
62  */
63 class VCLKDEApplication : public KApplication
64 {
65     public:
66     VCLKDEApplication() : KApplication() {}
67 
68     virtual void commitData(QSessionManager &sm);
69 };
70 
71 void VCLKDEApplication::commitData(QSessionManager&)
72 {
73 }
74 
75 /***************************************************************************
76  * class SalKDEDisplay                                                     *
77  ***************************************************************************/
78 
79 SalKDEDisplay::SalKDEDisplay( Display* pDisp )
80     : SalX11Display( pDisp )
81 {
82 }
83 
84 SalKDEDisplay::~SalKDEDisplay()
85 {
86     // in case never a frame opened
87     static_cast<KDEXLib*>(GetXLib())->doStartup();
88     // clean up own members
89     doDestruct();
90     // prevent SalDisplay from closing KApplication's display
91     pDisp_ = NULL;
92 }
93 
94 /***************************************************************************
95  * class KDEXLib                                                           *
96  ***************************************************************************/
97 
98 KDEXLib::~KDEXLib()
99 {
100     // #158056# on 64 bit linux using libXRandr.so.2 will crash in
101     // XCloseDisplay when freeing extension data
102     // no known work around, therefor currently leak. Hopefully
103     // this does not make problems since we're shutting down anyway
104     // should we ever get a real kde plugin that uses the KDE event loop
105     // we should use kde's method to signal screen changes similar
106     // to the gtk plugin
107     #if ! defined USE_RANDR || ! (defined LINUX && defined X86_64)
108     // properly deinitialize KApplication
109     delete (VCLKDEApplication*)m_pApplication;
110     #endif
111     // free the faked cmdline arguments no longer needed by KApplication
112     for( int i = 0; i < m_nFakeCmdLineArgs; i++ )
113         free( m_pFreeCmdLineArgs[i] );
114     delete [] m_pFreeCmdLineArgs;
115     delete [] m_pAppCmdLineArgs;
116 }
117 
118 void KDEXLib::Init()
119 {
120 	SalI18N_InputMethod* pInputMethod = new SalI18N_InputMethod;
121 	pInputMethod->SetLocale();
122 	XrmInitialize();
123 
124 	KAboutData *kAboutData = new KAboutData( "OpenOffice.org",
125 			I18N_NOOP( "OpenOffice.org" ),
126 			"1.1.0",
127 			I18N_NOOP( "OpenOffice.org with KDE Native Widget Support." ),
128 			KAboutData::License_LGPL,
129 			"(c) 2003, 2004 Novell, Inc",
130 			I18N_NOOP( "OpenOffice.org is an office suite.\n" ),
131 			"http://kde.openoffice.org/index.html",
132 			"dev@kde.openoffice.org");
133 	kAboutData->addAuthor( "Jan Holesovsky",
134 			I18N_NOOP( "Original author and maintainer of the KDE NWF." ),
135 			"kendy@artax.karlin.mff.cuni.cz",
136 			"http://artax.karlin.mff.cuni.cz/~kendy" );
137 
138     m_nFakeCmdLineArgs = 1;
139 	sal_uInt16 nIdx;
140 	vos::OExtCommandLine aCommandLine;
141 	int nParams = aCommandLine.getCommandArgCount();
142 	rtl::OString aDisplay;
143 	rtl::OUString aParam, aBin;
144 
145 	for ( nIdx = 0; nIdx < nParams; ++nIdx )
146 	{
147 		aCommandLine.getCommandArg( nIdx, aParam );
148 		if ( !m_pFreeCmdLineArgs && aParam.equalsAscii( "-display" ) && nIdx + 1 < nParams )
149 		{
150 			aCommandLine.getCommandArg( nIdx + 1, aParam );
151 			aDisplay = rtl::OUStringToOString( aParam, osl_getThreadTextEncoding() );
152 
153 			m_nFakeCmdLineArgs = 3;
154 			m_pFreeCmdLineArgs = new char*[ m_nFakeCmdLineArgs ];
155 			m_pFreeCmdLineArgs[ 1 ] = strdup( "-display" );
156 			m_pFreeCmdLineArgs[ 2 ] = strdup( aDisplay.getStr() );
157 		}
158 	}
159 	if ( !m_pFreeCmdLineArgs )
160 		m_pFreeCmdLineArgs = new char*[ m_nFakeCmdLineArgs ];
161 
162     osl_getExecutableFile( &aParam.pData );
163     osl_getSystemPathFromFileURL( aParam.pData, &aBin.pData );
164     rtl::OString aExec = rtl::OUStringToOString( aBin, osl_getThreadTextEncoding() );
165 	m_pFreeCmdLineArgs[0] = strdup( aExec.getStr() );
166 
167     // make a copy of the string list for freeing it since
168     // KApplication manipulates the pointers inside the argument vector
169     // note: KApplication bad !
170     m_pAppCmdLineArgs = new char*[ m_nFakeCmdLineArgs ];
171     for( int i = 0; i < m_nFakeCmdLineArgs; i++ )
172         m_pAppCmdLineArgs[i] = m_pFreeCmdLineArgs[i];
173 
174 	KCmdLineArgs::init( m_nFakeCmdLineArgs, m_pAppCmdLineArgs, kAboutData );
175 
176 	KApplication::disableAutoDcopRegistration();
177 	m_pApplication = new VCLKDEApplication();
178     kapp->disableSessionManagement();
179 
180 	Display* pDisp = QPaintDevice::x11AppDisplay();
181 
182 	SalDisplay *pSalDisplay = new SalKDEDisplay( pDisp );
183 
184 	pInputMethod->CreateMethod( pDisp );
185 	pInputMethod->AddConnectionWatch( pDisp, (void*)this );
186 	pSalDisplay->SetInputMethod( pInputMethod );
187 
188     PushXErrorLevel( true );
189 	SalI18N_KeyboardExtension *pKbdExtension = new SalI18N_KeyboardExtension( pDisp );
190 	XSync( pDisp, False );
191 
192 	pKbdExtension->UseExtension( ! HasXErrorOccured() );
193 	PopXErrorLevel();
194 
195 	pSalDisplay->SetKbdExtension( pKbdExtension );
196 }
197 
198 void KDEXLib::doStartup()
199 {
200     if( ! m_bStartupDone )
201     {
202         KStartupInfo::appStarted();
203         m_bStartupDone = true;
204         #if OSL_DEBUG_LEVEL > 1
205         fprintf( stderr, "called KStartupInfo::appStarted()\n" );
206         #endif
207     }
208 }
209 
210 /**********************************************************************
211  * class KDEData                                                      *
212  **********************************************************************/
213 
214 KDEData::~KDEData()
215 {
216 }
217 
218 void KDEData::Init()
219 {
220     pXLib_ = new KDEXLib();
221     pXLib_->Init();
222 }
223 
224 /**********************************************************************
225  * plugin entry point                                                 *
226  **********************************************************************/
227 
228 extern "C" {
229     VCLPLUG_KDE_PUBLIC SalInstance* create_SalInstance( oslModule )
230     {
231         /* #i92121# workaround deadlocks in the X11 implementation
232         */
233         static const char* pNoXInitThreads = getenv( "SAL_NO_XINITTHREADS" );
234         /* #i90094#
235            from now on we know that an X connection will be
236            established, so protect X against itself
237         */
238         if( ! ( pNoXInitThreads && *pNoXInitThreads ) )
239             XInitThreads();
240 
241         rtl::OString aVersion( qVersion() );
242 #if OSL_DEBUG_LEVEL > 1
243         fprintf( stderr, "qt version string is \"%s\"\n", aVersion.getStr() );
244 #endif
245         sal_Int32 nIndex = 0, nMajor = 0, nMinor = 0, nMicro = 0;
246         nMajor = aVersion.getToken( 0, '.', nIndex ).toInt32();
247         if( nIndex > 0 )
248             nMinor = aVersion.getToken( 0, '.', nIndex ).toInt32();
249         if( nIndex > 0 )
250             nMicro = aVersion.getToken( 0, '.', nIndex ).toInt32();
251         if( nMajor != 3 || nMinor < 2 || (nMinor == 2 && nMicro < 2) )
252         {
253 #if OSL_DEBUG_LEVEL > 1
254             fprintf( stderr, "unsuitable qt version %d.%d.%d\n", (int)nMajor, (int)nMinor, (int)nMicro );
255 #endif
256             return NULL;
257         }
258 
259         KDESalInstance* pInstance = new KDESalInstance( new SalYieldMutex() );
260 #if OSL_DEBUG_LEVEL > 1
261         fprintf( stderr, "created KDESalInstance 0x%p\n", pInstance );
262 #endif
263 
264         // initialize SalData
265         KDEData *pSalData = new KDEData();
266         SetSalData( pSalData );
267         pSalData->m_pInstance = pInstance;
268         pSalData->Init();
269         pSalData->initNWF();
270 
271         return pInstance;
272     }
273 }
274