Diffstat (limited to 'microkde/kdecore/klibloader.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | microkde/kdecore/klibloader.cpp | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/microkde/kdecore/klibloader.cpp b/microkde/kdecore/klibloader.cpp index 6d0475a..0b54eb6 100644 --- a/microkde/kdecore/klibloader.cpp +++ b/microkde/kdecore/klibloader.cpp | |||
@@ -1,219 +1,222 @@ | |||
1 | /* This file is part of the KDE libraries | 1 | /* This file is part of the KDE libraries |
2 | Copyright (C) 1999 Torben Weis <weis@kde.org> | 2 | Copyright (C) 1999 Torben Weis <weis@kde.org> |
3 | Copyright (C) 2000 Michael Matz <matz@kde.org> | 3 | Copyright (C) 2000 Michael Matz <matz@kde.org> |
4 | 4 | ||
5 | This library is free software; you can redistribute it and/or | 5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public | 6 | modify it under the terms of the GNU Library General Public |
7 | License version 2 as published by the Free Software Foundation. | 7 | License version 2 as published by the Free Software Foundation. |
8 | 8 | ||
9 | This library is distributed in the hope that it will be useful, | 9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. | 12 | Library General Public License for more details. |
13 | 13 | ||
14 | You should have received a copy of the GNU Library General Public License | 14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to | 15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 16 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
17 | Boston, MA 02111-1307, USA. | 17 | Boston, MA 02111-1307, USA. |
18 | */ | 18 | */ |
19 | //US #include <config.h> | 19 | //US #include <config.h> |
20 | #include <qclipboard.h> | 20 | #include <qclipboard.h> |
21 | #include <qfile.h> | 21 | #include <qfile.h> |
22 | #include <qtimer.h> | 22 | #include <qtimer.h> |
23 | #include <qobjectdict.h> | 23 | #include <q3objectdict.h> |
24 | #include <qwidgetlist.h> | ||
25 | #include <qwidget.h> | 24 | #include <qwidget.h> |
25 | #include <qwidget.h> | ||
26 | //Added by qt3to4: | ||
27 | #include <Q3CString> | ||
28 | #include <Q3PtrList> | ||
26 | 29 | ||
27 | #include "kapplication.h" | 30 | #include "kapplication.h" |
28 | #include "klibloader.h" | 31 | #include "klibloader.h" |
29 | #include "kstandarddirs.h" | 32 | #include "kstandarddirs.h" |
30 | #include "kdebug.h" | 33 | #include "kdebug.h" |
31 | #include "klocale.h" | 34 | #include "klocale.h" |
32 | 35 | ||
33 | /*US | 36 | /*US |
34 | #ifndef NDEBUG | 37 | #ifndef NDEBUG |
35 | #include "ltdl.h" | 38 | #include "ltdl.h" |
36 | #endif | 39 | #endif |
37 | */ | 40 | */ |
38 | 41 | ||
39 | //US do everything through qlibrary | 42 | //US do everything through qlibrary |
40 | #ifndef DESKTOP_VERSION | 43 | #ifndef DESKTOP_VERSION |
41 | #include <qpe/qpeapplication.h> | 44 | #include <qpe/qpeapplication.h> |
42 | #include <qtopia/qlibrary.h> | 45 | #include <qtopia/qlibrary.h> |
43 | #else | 46 | #else |
44 | #include <qlibrary.h> | 47 | #include <qlibrary.h> |
45 | #endif | 48 | #endif |
46 | 49 | ||
47 | 50 | ||
48 | template class QAsciiDict<KLibrary>; | 51 | template class Q3AsciiDict<KLibrary>; |
49 | 52 | ||
50 | #include <stdlib.h> //getenv | 53 | #include <stdlib.h> //getenv |
51 | 54 | ||
52 | /*US | 55 | /*US |
53 | #if HAVE_DLFCN_H | 56 | #if HAVE_DLFCN_H |
54 | # include <dlfcn.h> | 57 | # include <dlfcn.h> |
55 | #endif | 58 | #endif |
56 | 59 | ||
57 | #ifdef RTLD_GLOBAL | 60 | #ifdef RTLD_GLOBAL |
58 | # define LT_GLOBAL RTLD_GLOBAL | 61 | # define LT_GLOBAL RTLD_GLOBAL |
59 | #else | 62 | #else |
60 | # ifdef DL_GLOBAL | 63 | # ifdef DL_GLOBAL |
61 | # define LT_GLOBAL DL_GLOBAL | 64 | # define LT_GLOBAL DL_GLOBAL |
62 | # endif | 65 | # endif |
63 | #endif | 66 | #endif |
64 | #ifndef LT_GLOBAL | 67 | #ifndef LT_GLOBAL |
65 | # define LT_GLOBAL 0 | 68 | # define LT_GLOBAL 0 |
66 | #endif | 69 | #endif |
67 | */ | 70 | */ |
68 | 71 | ||
69 | /*US | 72 | /*US |
70 | extern "C" { | 73 | extern "C" { |
71 | extern int lt_dlopen_flag; | 74 | extern int lt_dlopen_flag; |
72 | } | 75 | } |
73 | */ | 76 | */ |
74 | 77 | ||
75 | KLibFactory::KLibFactory( QObject* parent, const char* name ) | 78 | KLibFactory::KLibFactory( QObject* parent, const char* name ) |
76 | : QObject( parent, name ) | 79 | : QObject( parent, name ) |
77 | { | 80 | { |
78 | } | 81 | } |
79 | 82 | ||
80 | KLibFactory::~KLibFactory() | 83 | KLibFactory::~KLibFactory() |
81 | { | 84 | { |
82 | // kdDebug(150) << "Deleting KLibFactory " << this << endl; | 85 | // kdDebug(150) << "Deleting KLibFactory " << this << endl; |
83 | } | 86 | } |
84 | 87 | ||
85 | QObject* KLibFactory::create( QObject* parent, const char* name, const char* classname, const QStringList &args ) | 88 | QObject* KLibFactory::create( QObject* parent, const char* name, const char* classname, const QStringList &args ) |
86 | { | 89 | { |
87 | QObject* obj = createObject( parent, name, classname, args ); | 90 | QObject* obj = createObject( parent, name, classname, args ); |
88 | if ( obj ) | 91 | if ( obj ) |
89 | emit objectCreated( obj ); | 92 | emit objectCreated( obj ); |
90 | return obj; | 93 | return obj; |
91 | } | 94 | } |
92 | 95 | ||
93 | 96 | ||
94 | QObject* KLibFactory::createObject( QObject*, const char*, const char*, const QStringList &) | 97 | QObject* KLibFactory::createObject( QObject*, const char*, const char*, const QStringList &) |
95 | { | 98 | { |
96 | return 0; | 99 | return 0; |
97 | } | 100 | } |
98 | 101 | ||
99 | 102 | ||
100 | // ----------------------------------------------- | 103 | // ----------------------------------------------- |
101 | 104 | ||
102 | //US KLibrary::KLibrary( const QString& libname, const QString& filename, void * handle ) | 105 | //US KLibrary::KLibrary( const QString& libname, const QString& filename, void * handle ) |
103 | KLibrary::KLibrary( const QString& libname, const QString& filename, QLibrary* handle ) | 106 | KLibrary::KLibrary( const QString& libname, const QString& filename, QLibrary* handle ) |
104 | { | 107 | { |
105 | /* Make sure, we have a KLibLoader */ | 108 | /* Make sure, we have a KLibLoader */ |
106 | (void) KLibLoader::self(); | 109 | (void) KLibLoader::self(); |
107 | m_libname = libname; | 110 | m_libname = libname; |
108 | m_filename = filename; | 111 | m_filename = filename; |
109 | m_handle = handle; | 112 | m_handle = handle; |
110 | m_factory = 0; | 113 | m_factory = 0; |
111 | m_timer = 0; | 114 | m_timer = 0; |
112 | } | 115 | } |
113 | 116 | ||
114 | KLibrary::~KLibrary() | 117 | KLibrary::~KLibrary() |
115 | { | 118 | { |
116 | // kdDebug(150) << "Deleting KLibrary " << this << " " << m_libname << endl; | 119 | // kdDebug(150) << "Deleting KLibrary " << this << " " << m_libname << endl; |
117 | if ( m_timer && m_timer->isActive() ) | 120 | if ( m_timer && m_timer->isActive() ) |
118 | m_timer->stop(); | 121 | m_timer->stop(); |
119 | 122 | ||
120 | // If any object is remaining, delete | 123 | // If any object is remaining, delete |
121 | if ( m_objs.count() > 0 ) | 124 | if ( m_objs.count() > 0 ) |
122 | { | 125 | { |
123 | QPtrListIterator<QObject> it( m_objs ); | 126 | Q3PtrListIterator<QObject> it( m_objs ); |
124 | for ( ; it.current() ; ++it ) | 127 | for ( ; it.current() ; ++it ) |
125 | { | 128 | { |
126 | kdDebug(150) << "Factory still has object " << it.current() << " " << it.current()->name () << " Library = " << m_libname << endl; | 129 | kdDebug(150) << "Factory still has object " << it.current() << " " << it.current()->name () << " Library = " << m_libname << endl; |
127 | disconnect( it.current(), SIGNAL( destroyed() ), | 130 | disconnect( it.current(), SIGNAL( destroyed() ), |
128 | this, SLOT( slotObjectDestroyed() ) ); | 131 | this, SLOT( slotObjectDestroyed() ) ); |
129 | } | 132 | } |
130 | m_objs.setAutoDelete(true); | 133 | m_objs.setAutoDelete(true); |
131 | m_objs.clear(); | 134 | m_objs.clear(); |
132 | } | 135 | } |
133 | 136 | ||
134 | if ( m_factory ) { | 137 | if ( m_factory ) { |
135 | //kdDebug(150) << " ... deleting the factory " << m_factory << endl; | 138 | //kdDebug(150) << " ... deleting the factory " << m_factory << endl; |
136 | delete m_factory; | 139 | delete m_factory; |
137 | } | 140 | } |
138 | } | 141 | } |
139 | 142 | ||
140 | QString KLibrary::name() const | 143 | QString KLibrary::name() const |
141 | { | 144 | { |
142 | return m_libname; | 145 | return m_libname; |
143 | } | 146 | } |
144 | 147 | ||
145 | QString KLibrary::fileName() const | 148 | QString KLibrary::fileName() const |
146 | { | 149 | { |
147 | return m_filename; | 150 | return m_filename; |
148 | } | 151 | } |
149 | 152 | ||
150 | KLibFactory* KLibrary::factory() | 153 | KLibFactory* KLibrary::factory() |
151 | { | 154 | { |
152 | if ( m_factory ) | 155 | if ( m_factory ) |
153 | return m_factory; | 156 | return m_factory; |
154 | 157 | ||
155 | QCString symname; | 158 | Q3CString symname; |
156 | symname.sprintf("init_%s", name().latin1() ); | 159 | symname.sprintf("init_%s", name().latin1() ); |
157 | 160 | ||
158 | void* sym = symbol( symname ); | 161 | void* sym = symbol( symname ); |
159 | if ( !sym ) | 162 | if ( !sym ) |
160 | { | 163 | { |
161 | qDebug("KLibrary: The library %s does not offer an %s function", name().latin1(), symname.data()); | 164 | qDebug("KLibrary: The library %s does not offer an %s function", name().latin1(), symname.data()); |
162 | #ifndef NDEBUG | 165 | #ifndef NDEBUG |
163 | //US qDebug("KLibrary: errorcode: %s", lt_dlerror()); | 166 | //US qDebug("KLibrary: errorcode: %s", lt_dlerror()); |
164 | #endif | 167 | #endif |
165 | kdWarning(150) << "KLibrary: The library " << name().latin1() << " does not offer an init_" << name().latin1() << " function" << endl; | 168 | kdWarning(150) << "KLibrary: The library " << name().latin1() << " does not offer an init_" << name().latin1() << " function" << endl; |
166 | return 0; | 169 | return 0; |
167 | } | 170 | } |
168 | 171 | ||
169 | typedef KLibFactory* (*t_func)(); | 172 | typedef KLibFactory* (*t_func)(); |
170 | t_func func = (t_func)sym; | 173 | t_func func = (t_func)sym; |
171 | m_factory = func(); | 174 | m_factory = func(); |
172 | 175 | ||
173 | if( !m_factory ) | 176 | if( !m_factory ) |
174 | { | 177 | { |
175 | kdWarning(150) << "KLibrary: The library " << name() << " does not offer a KDE compatible factory" << endl; | 178 | kdWarning(150) << "KLibrary: The library " << name() << " does not offer a KDE compatible factory" << endl; |
176 | return 0; | 179 | return 0; |
177 | } | 180 | } |
178 | 181 | ||
179 | connect( m_factory, SIGNAL( objectCreated( QObject * ) ), | 182 | connect( m_factory, SIGNAL( objectCreated( QObject * ) ), |
180 | this, SLOT( slotObjectCreated( QObject * ) ) ); | 183 | this, SLOT( slotObjectCreated( QObject * ) ) ); |
181 | 184 | ||
182 | return m_factory; | 185 | return m_factory; |
183 | } | 186 | } |
184 | 187 | ||
185 | void* KLibrary::symbol( const char* symname ) const | 188 | void* KLibrary::symbol( const char* symname ) const |
186 | { | 189 | { |
187 | //US void* sym = lt_dlsym( (lt_dlhandle) m_handle, symname ); | 190 | //US void* sym = lt_dlsym( (lt_dlhandle) m_handle, symname ); |
188 | void* sym = m_handle->resolve( symname ); | 191 | void* sym = m_handle->resolve( symname ); |
189 | if ( !sym ) | 192 | if ( !sym ) |
190 | { | 193 | { |
191 | //US kdWarning(150) << "KLibrary: " << lt_dlerror() << endl; | 194 | //US kdWarning(150) << "KLibrary: " << lt_dlerror() << endl; |
192 | return 0; | 195 | return 0; |
193 | } | 196 | } |
194 | 197 | ||
195 | return sym; | 198 | return sym; |
196 | } | 199 | } |
197 | 200 | ||
198 | bool KLibrary::hasSymbol( const char* symname ) const | 201 | bool KLibrary::hasSymbol( const char* symname ) const |
199 | { | 202 | { |
200 | //US void* sym = lt_dlsym( (lt_dlhandle) m_handle, symname ); | 203 | //US void* sym = lt_dlsym( (lt_dlhandle) m_handle, symname ); |
201 | void* sym = m_handle->resolve( symname ); | 204 | void* sym = m_handle->resolve( symname ); |
202 | return (sym != 0L ); | 205 | return (sym != 0L ); |
203 | } | 206 | } |
204 | 207 | ||
205 | void KLibrary::unload() const | 208 | void KLibrary::unload() const |
206 | { | 209 | { |
207 | if (KLibLoader::s_self) | 210 | if (KLibLoader::s_self) |
208 | KLibLoader::s_self->unloadLibrary(QFile::encodeName(name())); | 211 | KLibLoader::s_self->unloadLibrary(QFile::encodeName(name())); |
209 | } | 212 | } |
210 | 213 | ||
211 | void KLibrary::slotObjectCreated( QObject *obj ) | 214 | void KLibrary::slotObjectCreated( QObject *obj ) |
212 | { | 215 | { |
213 | if ( !obj ) | 216 | if ( !obj ) |
214 | return; | 217 | return; |
215 | 218 | ||
216 | if ( m_timer && m_timer->isActive() ) | 219 | if ( m_timer && m_timer->isActive() ) |
217 | m_timer->stop(); | 220 | m_timer->stop(); |
218 | 221 | ||
219 | if ( m_objs.containsRef( obj ) ) | 222 | if ( m_objs.containsRef( obj ) ) |
@@ -244,393 +247,393 @@ void KLibrary::slotObjectDestroyed() | |||
244 | // as long as it's not stable make the timeout short, for debugging | 247 | // as long as it's not stable make the timeout short, for debugging |
245 | // pleasure (matz) | 248 | // pleasure (matz) |
246 | //m_timer->start( 1000*60, true ); | 249 | //m_timer->start( 1000*60, true ); |
247 | m_timer->start( 1000*10, true ); | 250 | m_timer->start( 1000*10, true ); |
248 | } | 251 | } |
249 | } | 252 | } |
250 | 253 | ||
251 | void KLibrary::slotTimeout() | 254 | void KLibrary::slotTimeout() |
252 | { | 255 | { |
253 | if ( m_objs.count() != 0 ) | 256 | if ( m_objs.count() != 0 ) |
254 | return; | 257 | return; |
255 | 258 | ||
256 | /* Don't go through KLibLoader::unloadLibrary(), because that uses the | 259 | /* Don't go through KLibLoader::unloadLibrary(), because that uses the |
257 | ref counter, but this timeout means to unconditionally close this library | 260 | ref counter, but this timeout means to unconditionally close this library |
258 | The destroyed() signal will take care to remove us from all lists. | 261 | The destroyed() signal will take care to remove us from all lists. |
259 | */ | 262 | */ |
260 | delete this; | 263 | delete this; |
261 | } | 264 | } |
262 | 265 | ||
263 | // ------------------------------------------------- | 266 | // ------------------------------------------------- |
264 | 267 | ||
265 | /* This helper class is needed, because KLibraries can go away without | 268 | /* This helper class is needed, because KLibraries can go away without |
266 | being unloaded. So we need some info about KLibraries even after its | 269 | being unloaded. So we need some info about KLibraries even after its |
267 | death. */ | 270 | death. */ |
268 | class KLibWrapPrivate | 271 | class KLibWrapPrivate |
269 | { | 272 | { |
270 | public: | 273 | public: |
271 | //US KLibWrapPrivate(KLibrary *l, lt_dlhandle h); | 274 | //US KLibWrapPrivate(KLibrary *l, lt_dlhandle h); |
272 | KLibWrapPrivate(KLibrary *l, QLibrary* h); | 275 | KLibWrapPrivate(KLibrary *l, QLibrary* h); |
273 | 276 | ||
274 | KLibrary *lib; | 277 | KLibrary *lib; |
275 | enum {UNKNOWN, UNLOAD, DONT_UNLOAD} unload_mode; | 278 | enum {UNKNOWN, UNLOAD, DONT_UNLOAD} unload_mode; |
276 | int ref_count; | 279 | int ref_count; |
277 | //US lt_dlhandle handle; | 280 | //US lt_dlhandle handle; |
278 | QLibrary *handle; | 281 | QLibrary *handle; |
279 | QString name; | 282 | QString name; |
280 | QString filename; | 283 | QString filename; |
281 | }; | 284 | }; |
282 | 285 | ||
283 | //US KLibWrapPrivate::KLibWrapPrivate(KLibrary *l, lt_dlhandle h) | 286 | //US KLibWrapPrivate::KLibWrapPrivate(KLibrary *l, lt_dlhandle h) |
284 | KLibWrapPrivate::KLibWrapPrivate(KLibrary *l, QLibrary* h) | 287 | KLibWrapPrivate::KLibWrapPrivate(KLibrary *l, QLibrary* h) |
285 | : lib(l), ref_count(1), handle(h), name(l->name()), filename(l->fileName()) | 288 | : lib(l), ref_count(1), handle(h), name(l->name()), filename(l->fileName()) |
286 | { | 289 | { |
287 | unload_mode = UNKNOWN; | 290 | unload_mode = UNKNOWN; |
288 | /*US | 291 | /*US |
289 | if (lt_dlsym(handle, "__kde_do_not_unload") != 0) { | 292 | if (lt_dlsym(handle, "__kde_do_not_unload") != 0) { |
290 | // kdDebug(150) << "Will not unload " << name << endl; | 293 | // kdDebug(150) << "Will not unload " << name << endl; |
291 | unload_mode = DONT_UNLOAD; | 294 | unload_mode = DONT_UNLOAD; |
292 | } else if (lt_dlsym(handle, "__kde_do_unload") != 0) { | 295 | } else if (lt_dlsym(handle, "__kde_do_unload") != 0) { |
293 | unload_mode = UNLOAD; | 296 | unload_mode = UNLOAD; |
294 | } | 297 | } |
295 | */ | 298 | */ |
296 | //US use instead: | 299 | //US use instead: |
297 | if (h->resolve("__kde_do_not_unload") != 0) { | 300 | if (h->resolve("__kde_do_not_unload") != 0) { |
298 | // kdDebug(150) << "Will not unload " << name << endl; | 301 | // kdDebug(150) << "Will not unload " << name << endl; |
299 | unload_mode = DONT_UNLOAD; | 302 | unload_mode = DONT_UNLOAD; |
300 | } else if (h->resolve("__kde_do_unload") != 0) { | 303 | } else if (h->resolve("__kde_do_unload") != 0) { |
301 | unload_mode = UNLOAD; | 304 | unload_mode = UNLOAD; |
302 | } | 305 | } |
303 | } | 306 | } |
304 | 307 | ||
305 | class KLibLoaderPrivate | 308 | class KLibLoaderPrivate |
306 | { | 309 | { |
307 | public: | 310 | public: |
308 | QPtrList<KLibWrapPrivate> loaded_stack; | 311 | Q3PtrList<KLibWrapPrivate> loaded_stack; |
309 | QPtrList<KLibWrapPrivate> pending_close; | 312 | Q3PtrList<KLibWrapPrivate> pending_close; |
310 | enum {UNKNOWN, UNLOAD, DONT_UNLOAD} unload_mode; | 313 | enum {UNKNOWN, UNLOAD, DONT_UNLOAD} unload_mode; |
311 | 314 | ||
312 | QString errorMessage; | 315 | QString errorMessage; |
313 | }; | 316 | }; |
314 | 317 | ||
315 | KLibLoader* KLibLoader::s_self = 0; | 318 | KLibLoader* KLibLoader::s_self = 0; |
316 | 319 | ||
317 | KLibLoader* KLibLoader::self() | 320 | KLibLoader* KLibLoader::self() |
318 | { | 321 | { |
319 | if ( !s_self ) | 322 | if ( !s_self ) |
320 | s_self = new KLibLoader; | 323 | s_self = new KLibLoader; |
321 | return s_self; | 324 | return s_self; |
322 | } | 325 | } |
323 | 326 | ||
324 | void KLibLoader::cleanUp() | 327 | void KLibLoader::cleanUp() |
325 | { | 328 | { |
326 | if ( !s_self ) | 329 | if ( !s_self ) |
327 | return; | 330 | return; |
328 | 331 | ||
329 | delete s_self; | 332 | delete s_self; |
330 | s_self = 0; | 333 | s_self = 0; |
331 | } | 334 | } |
332 | 335 | ||
333 | KLibLoader::KLibLoader( QObject* parent, const char* name ) | 336 | KLibLoader::KLibLoader( QObject* parent, const char* name ) |
334 | : QObject( parent, name ) | 337 | : QObject( parent, name ) |
335 | { | 338 | { |
336 | s_self = this; | 339 | s_self = this; |
337 | d = new KLibLoaderPrivate; | 340 | d = new KLibLoaderPrivate; |
338 | //US lt_dlinit(); | 341 | //US lt_dlinit(); |
339 | d->unload_mode = KLibLoaderPrivate::UNKNOWN; | 342 | d->unload_mode = KLibLoaderPrivate::UNKNOWN; |
340 | if (getenv("KDE_NOUNLOAD") != 0) | 343 | if (getenv("KDE_NOUNLOAD") != 0) |
341 | d->unload_mode = KLibLoaderPrivate::DONT_UNLOAD; | 344 | d->unload_mode = KLibLoaderPrivate::DONT_UNLOAD; |
342 | else if (getenv("KDE_DOUNLOAD") != 0) | 345 | else if (getenv("KDE_DOUNLOAD") != 0) |
343 | d->unload_mode = KLibLoaderPrivate::UNLOAD; | 346 | d->unload_mode = KLibLoaderPrivate::UNLOAD; |
344 | d->loaded_stack.setAutoDelete( true ); | 347 | d->loaded_stack.setAutoDelete( true ); |
345 | } | 348 | } |
346 | 349 | ||
347 | KLibLoader::~KLibLoader() | 350 | KLibLoader::~KLibLoader() |
348 | { | 351 | { |
349 | // kdDebug(150) << "Deleting KLibLoader " << this << " " << name() << endl; | 352 | // kdDebug(150) << "Deleting KLibLoader " << this << " " << name() << endl; |
350 | 353 | ||
351 | QAsciiDictIterator<KLibWrapPrivate> it( m_libs ); | 354 | Q3AsciiDictIterator<KLibWrapPrivate> it( m_libs ); |
352 | for (; it.current(); ++it ) | 355 | for (; it.current(); ++it ) |
353 | { | 356 | { |
354 | kdDebug(150) << "The KLibLoader contains the library " << it.current()->name | 357 | kdDebug(150) << "The KLibLoader contains the library " << it.current()->name |
355 | << " (" << it.current()->lib << ")" << endl; | 358 | << " (" << it.current()->lib << ")" << endl; |
356 | d->pending_close.append(it.current()); | 359 | d->pending_close.append(it.current()); |
357 | } | 360 | } |
358 | 361 | ||
359 | close_pending(0); | 362 | close_pending(0); |
360 | 363 | ||
361 | delete d; | 364 | delete d; |
362 | } | 365 | } |
363 | 366 | ||
364 | //static | 367 | //static |
365 | QString KLibLoader::findLibrary( const char * name/*US , const KInstance * instance*/ ) | 368 | QString KLibLoader::findLibrary( const char * name/*US , const KInstance * instance*/ ) |
366 | { | 369 | { |
367 | QCString libname( name ); | 370 | Q3CString libname( name ); |
368 | 371 | ||
369 | // only append ".la" if there is no extension | 372 | // only append ".la" if there is no extension |
370 | // this allows to load non-libtool libraries as well | 373 | // this allows to load non-libtool libraries as well |
371 | // (mhk, 20000228) | 374 | // (mhk, 20000228) |
372 | int pos = libname.findRev('/'); | 375 | int pos = libname.findRev('/'); |
373 | if (pos < 0) | 376 | if (pos < 0) |
374 | pos = 0; | 377 | pos = 0; |
375 | /*US | 378 | /*US |
376 | if (libname.find('.', pos) < 0) { | 379 | if (libname.find('.', pos) < 0) { |
377 | libname += ".la"; | 380 | libname += ".la"; |
378 | } | 381 | } |
379 | */ | 382 | */ |
380 | //US in the microedition we work only with shared libraries. | 383 | //US in the microedition we work only with shared libraries. |
381 | 384 | ||
382 | if (libname.find('.', pos) < 0) { | 385 | if (libname.find('.', pos) < 0) { |
383 | #ifdef _WIN32_ | 386 | #ifdef _WIN32_ |
384 | libname += ".dll"; | 387 | libname += ".dll"; |
385 | #else | 388 | #else |
386 | libname += ".so"; | 389 | libname += ".so"; |
387 | #endif | 390 | #endif |
388 | } | 391 | } |
389 | 392 | ||
390 | // only look up the file if it is not an absolute filename | 393 | // only look up the file if it is not an absolute filename |
391 | // (mhk, 20000228) | 394 | // (mhk, 20000228) |
392 | QString libfile; | 395 | QString libfile; |
393 | if (libname[0] == '/') | 396 | if (libname[0] == '/') |
394 | libfile = libname; | 397 | libfile = libname; |
395 | else | 398 | else |
396 | { | 399 | { |
397 | //US at this point the libname must exist as real filesname. No expansions will be made later | 400 | //US at this point the libname must exist as real filesname. No expansions will be made later |
398 | // in findResources. Because of that we prepend the lib prefix here to the name | 401 | // in findResources. Because of that we prepend the lib prefix here to the name |
399 | //US I add also the "lib" prefix. I do not how could this could have worked before without it? | 402 | //US I add also the "lib" prefix. I do not how could this could have worked before without it? |
400 | #ifndef _WIN32_ | 403 | #ifndef _WIN32_ |
401 | libname.insert(pos, "lib"); | 404 | libname.insert(pos, "lib"); |
402 | #endif | 405 | #endif |
403 | 406 | ||
404 | 407 | ||
405 | //US libfile = instance->dirs()->findResource( "module", libname ); | 408 | //US libfile = instance->dirs()->findResource( "module", libname ); |
406 | //qDebug("libname = %s ",libname.data() ); | 409 | //qDebug("libname = %s ",libname.data() ); |
407 | libfile = KGlobal::dirs()->findResource( "module", libname ); | 410 | libfile = KGlobal::dirs()->findResource( "module", libname ); |
408 | //qDebug("libfile = %s ",libfile.latin1() ); | 411 | //qDebug("libfile = %s ",libfile.latin1() ); |
409 | 412 | ||
410 | if ( libfile.isEmpty() ) | 413 | if ( libfile.isEmpty() ) |
411 | { | 414 | { |
412 | //US libfile = instance->dirs()->findResource( "lib", libname ); | 415 | //US libfile = instance->dirs()->findResource( "lib", libname ); |
413 | libfile = KGlobal::dirs()->findResource( "lib", libname ); | 416 | libfile = KGlobal::dirs()->findResource( "lib", libname ); |
414 | //qDebug("libfile2 = %s ",libfile.latin1() ); | 417 | //qDebug("libfile2 = %s ",libfile.latin1() ); |
415 | #ifndef NDEBUG | 418 | #ifndef NDEBUG |
416 | if ( !libfile.isEmpty() && libname.left(3) == "lib" ) // don't warn for kdeinit modules | 419 | if ( !libfile.isEmpty() && libname.left(3) == "lib" ) // don't warn for kdeinit modules |
417 | kdDebug(150) << "library " << libname << " not found under 'module' but under 'lib'" << endl; | 420 | kdDebug(150) << "library " << libname << " not found under 'module' but under 'lib'" << endl; |
418 | #endif | 421 | #endif |
419 | } | 422 | } |
420 | if ( libfile.isEmpty() ) | 423 | if ( libfile.isEmpty() ) |
421 | { | 424 | { |
422 | #ifndef NDEBUG | 425 | #ifndef NDEBUG |
423 | kdDebug(150) << "library=" << libname << ": No file names " << libname.data() << " found in paths." << endl; | 426 | kdDebug(150) << "library=" << libname << ": No file names " << libname.data() << " found in paths." << endl; |
424 | self()->d->errorMessage = i18n("Library files for \"%1\" not found in paths").arg(libname); | 427 | self()->d->errorMessage = i18n("Library files for \"%1\" not found in paths").arg(QString(libname)); |
425 | 428 | ||
426 | qDebug("KLibLoader::library could not find library: %s", libname.data()); | 429 | qDebug("KLibLoader::library could not find library: %s", libname.data()); |
427 | #endif | 430 | #endif |
428 | 431 | ||
429 | } | 432 | } |
430 | else | 433 | else |
431 | self()->d->errorMessage = QString::null; | 434 | self()->d->errorMessage = QString::null; |
432 | } | 435 | } |
433 | 436 | ||
434 | //qDebug("return libfile = %s ",libfile.latin1() ); | 437 | //qDebug("return libfile = %s ",libfile.latin1() ); |
435 | return libfile; | 438 | return libfile; |
436 | } | 439 | } |
437 | 440 | ||
438 | 441 | ||
439 | KLibrary* KLibLoader::globalLibrary( const char *name ) | 442 | KLibrary* KLibLoader::globalLibrary( const char *name ) |
440 | { | 443 | { |
441 | KLibrary *tmp; | 444 | KLibrary *tmp; |
442 | /*US | 445 | /*US |
443 | int olt_dlopen_flag = lt_dlopen_flag; | 446 | int olt_dlopen_flag = lt_dlopen_flag; |
444 | 447 | ||
445 | lt_dlopen_flag |= LT_GLOBAL; | 448 | lt_dlopen_flag |= LT_GLOBAL; |
446 | kdDebug(150) << "Loading the next library global with flag " | 449 | kdDebug(150) << "Loading the next library global with flag " |
447 | << lt_dlopen_flag | 450 | << lt_dlopen_flag |
448 | << "." << endl; | 451 | << "." << endl; |
449 | */ | 452 | */ |
450 | tmp = library(name); | 453 | tmp = library(name); |
451 | /*US | 454 | /*US |
452 | lt_dlopen_flag = olt_dlopen_flag; | 455 | lt_dlopen_flag = olt_dlopen_flag; |
453 | */ | 456 | */ |
454 | return tmp; | 457 | return tmp; |
455 | } | 458 | } |
456 | 459 | ||
457 | 460 | ||
458 | KLibrary* KLibLoader::library( const char *name ) | 461 | KLibrary* KLibLoader::library( const char *name ) |
459 | { | 462 | { |
460 | if (!name) | 463 | if (!name) |
461 | return 0; | 464 | return 0; |
462 | 465 | ||
463 | KLibWrapPrivate* wrap = m_libs[name]; | 466 | KLibWrapPrivate* wrap = m_libs[name]; |
464 | if (wrap) { | 467 | if (wrap) { |
465 | /* Nothing to do to load the library. */ | 468 | /* Nothing to do to load the library. */ |
466 | wrap->ref_count++; | 469 | wrap->ref_count++; |
467 | return wrap->lib; | 470 | return wrap->lib; |
468 | } | 471 | } |
469 | 472 | ||
470 | /* Test if this library was loaded at some time, but got | 473 | /* Test if this library was loaded at some time, but got |
471 | unloaded meanwhile, whithout being dlclose()'ed. */ | 474 | unloaded meanwhile, whithout being dlclose()'ed. */ |
472 | QPtrListIterator<KLibWrapPrivate> it(d->loaded_stack); | 475 | Q3PtrListIterator<KLibWrapPrivate> it(d->loaded_stack); |
473 | for (; it.current(); ++it) { | 476 | for (; it.current(); ++it) { |
474 | if (it.current()->name == name) | 477 | if (it.current()->name == name) |
475 | wrap = it.current(); | 478 | wrap = it.current(); |
476 | } | 479 | } |
477 | 480 | ||
478 | if (wrap) { | 481 | if (wrap) { |
479 | d->pending_close.removeRef(wrap); | 482 | d->pending_close.removeRef(wrap); |
480 | if (!wrap->lib) { | 483 | if (!wrap->lib) { |
481 | /* This lib only was in loaded_stack, but not in m_libs. */ | 484 | /* This lib only was in loaded_stack, but not in m_libs. */ |
482 | wrap->lib = new KLibrary( name, wrap->filename, wrap->handle ); | 485 | wrap->lib = new KLibrary( name, wrap->filename, wrap->handle ); |
483 | } | 486 | } |
484 | wrap->ref_count++; | 487 | wrap->ref_count++; |
485 | } else { | 488 | } else { |
486 | QString libfile = findLibrary( name ); | 489 | QString libfile = findLibrary( name ); |
487 | if ( libfile.isEmpty() ) | 490 | if ( libfile.isEmpty() ) |
488 | return 0; | 491 | return 0; |
489 | #ifdef DESKTOP_VERSION | 492 | #ifdef DESKTOP_VERSION |
490 | QLibrary *qlib = new QLibrary( libfile.latin1() ); | 493 | QLibrary *qlib = new QLibrary( libfile.latin1() ); |
491 | #else | 494 | #else |
492 | QLibrary *qlib = new QLibrary( libfile.latin1(), QLibrary::Immediately ); | 495 | QLibrary *qlib = new QLibrary( libfile.latin1(), QLibrary::Immediately ); |
493 | #endif | 496 | #endif |
494 | 497 | ||
495 | //US lt_dlhandle handle = lt_dlopen( libfile.latin1() ); | 498 | //US lt_dlhandle handle = lt_dlopen( libfile.latin1() ); |
496 | //US if ( !handle ) | 499 | //US if ( !handle ) |
497 | if ( !qlib ) | 500 | if ( !qlib ) |
498 | { | 501 | { |
499 | qDebug( "KLibLoader::library could not load library: %s", libfile.latin1()); | 502 | qDebug( "KLibLoader::library could not load library: %s", libfile.latin1()); |
500 | d->errorMessage = QString::null; | 503 | d->errorMessage = QString::null; |
501 | return 0; | 504 | return 0; |
502 | } | 505 | } |
503 | else | 506 | else |
504 | d->errorMessage = QString::null; | 507 | d->errorMessage = QString::null; |
505 | 508 | ||
506 | KLibrary *lib = new KLibrary( name, libfile, qlib ); | 509 | KLibrary *lib = new KLibrary( name, libfile, qlib ); |
507 | wrap = new KLibWrapPrivate(lib, qlib); | 510 | wrap = new KLibWrapPrivate(lib, qlib); |
508 | d->loaded_stack.prepend(wrap); | 511 | d->loaded_stack.prepend(wrap); |
509 | } | 512 | } |
510 | m_libs.insert( name, wrap ); | 513 | m_libs.insert( name, wrap ); |
511 | 514 | ||
512 | connect( wrap->lib, SIGNAL( destroyed() ), | 515 | connect( wrap->lib, SIGNAL( destroyed() ), |
513 | this, SLOT( slotLibraryDestroyed() ) ); | 516 | this, SLOT( slotLibraryDestroyed() ) ); |
514 | 517 | ||
515 | return wrap->lib; | 518 | return wrap->lib; |
516 | } | 519 | } |
517 | 520 | ||
518 | QString KLibLoader::lastErrorMessage() const | 521 | QString KLibLoader::lastErrorMessage() const |
519 | { | 522 | { |
520 | return d->errorMessage; | 523 | return d->errorMessage; |
521 | } | 524 | } |
522 | 525 | ||
523 | void KLibLoader::unloadLibrary( const char *libname ) | 526 | void KLibLoader::unloadLibrary( const char *libname ) |
524 | { | 527 | { |
525 | KLibWrapPrivate *wrap = m_libs[ libname ]; | 528 | KLibWrapPrivate *wrap = m_libs[ libname ]; |
526 | if (!wrap) | 529 | if (!wrap) |
527 | return; | 530 | return; |
528 | if (--wrap->ref_count) | 531 | if (--wrap->ref_count) |
529 | return; | 532 | return; |
530 | 533 | ||
531 | // kdDebug(150) << "closing library " << libname << endl; | 534 | // kdDebug(150) << "closing library " << libname << endl; |
532 | 535 | ||
533 | m_libs.remove( libname ); | 536 | m_libs.remove( libname ); |
534 | 537 | ||
535 | disconnect( wrap->lib, SIGNAL( destroyed() ), | 538 | disconnect( wrap->lib, SIGNAL( destroyed() ), |
536 | this, SLOT( slotLibraryDestroyed() ) ); | 539 | this, SLOT( slotLibraryDestroyed() ) ); |
537 | close_pending( wrap ); | 540 | close_pending( wrap ); |
538 | } | 541 | } |
539 | 542 | ||
540 | KLibFactory* KLibLoader::factory( const char* name ) | 543 | KLibFactory* KLibLoader::factory( const char* name ) |
541 | { | 544 | { |
542 | KLibrary* lib = library( name ); | 545 | KLibrary* lib = library( name ); |
543 | if ( !lib ) | 546 | if ( !lib ) |
544 | return 0; | 547 | return 0; |
545 | 548 | ||
546 | return lib->factory(); | 549 | return lib->factory(); |
547 | } | 550 | } |
548 | 551 | ||
549 | void KLibLoader::slotLibraryDestroyed() | 552 | void KLibLoader::slotLibraryDestroyed() |
550 | { | 553 | { |
551 | const KLibrary *lib = static_cast<const KLibrary *>( sender() ); | 554 | const KLibrary *lib = static_cast<const KLibrary *>( sender() ); |
552 | 555 | ||
553 | QAsciiDictIterator<KLibWrapPrivate> it( m_libs ); | 556 | Q3AsciiDictIterator<KLibWrapPrivate> it( m_libs ); |
554 | for (; it.current(); ++it ) | 557 | for (; it.current(); ++it ) |
555 | if ( it.current()->lib == lib ) | 558 | if ( it.current()->lib == lib ) |
556 | { | 559 | { |
557 | KLibWrapPrivate *wrap = it.current(); | 560 | KLibWrapPrivate *wrap = it.current(); |
558 | wrap->lib = 0; /* the KLibrary object is already away */ | 561 | wrap->lib = 0; /* the KLibrary object is already away */ |
559 | m_libs.remove( it.currentKey() ); | 562 | m_libs.remove( it.currentKey() ); |
560 | close_pending( wrap ); | 563 | close_pending( wrap ); |
561 | return; | 564 | return; |
562 | } | 565 | } |
563 | } | 566 | } |
564 | 567 | ||
565 | void KLibLoader::close_pending(KLibWrapPrivate *wrap) | 568 | void KLibLoader::close_pending(KLibWrapPrivate *wrap) |
566 | { | 569 | { |
567 | if (wrap && !d->pending_close.containsRef( wrap )) | 570 | if (wrap && !d->pending_close.containsRef( wrap )) |
568 | d->pending_close.append( wrap ); | 571 | d->pending_close.append( wrap ); |
569 | 572 | ||
570 | /* First delete all KLibrary objects in pending_close, but _don't_ unload | 573 | /* First delete all KLibrary objects in pending_close, but _don't_ unload |
571 | the DSO behind it. */ | 574 | the DSO behind it. */ |
572 | QPtrListIterator<KLibWrapPrivate> it(d->pending_close); | 575 | Q3PtrListIterator<KLibWrapPrivate> it(d->pending_close); |
573 | for (; it.current(); ++it) { | 576 | for (; it.current(); ++it) { |
574 | wrap = it.current(); | 577 | wrap = it.current(); |
575 | if (wrap->lib) { | 578 | if (wrap->lib) { |
576 | disconnect( wrap->lib, SIGNAL( destroyed() ), | 579 | disconnect( wrap->lib, SIGNAL( destroyed() ), |
577 | this, SLOT( slotLibraryDestroyed() ) ); | 580 | this, SLOT( slotLibraryDestroyed() ) ); |
578 | delete wrap->lib; | 581 | delete wrap->lib; |
579 | wrap->lib = 0; | 582 | wrap->lib = 0; |
580 | } | 583 | } |
581 | } | 584 | } |
582 | 585 | ||
583 | if (d->unload_mode == KLibLoaderPrivate::DONT_UNLOAD) return; | 586 | if (d->unload_mode == KLibLoaderPrivate::DONT_UNLOAD) return; |
584 | 587 | ||
585 | bool deleted_one = false; | 588 | bool deleted_one = false; |
586 | while ((wrap = d->loaded_stack.first())) { | 589 | while ((wrap = d->loaded_stack.first())) { |
587 | /* Let's first see, if we want to try to unload this lib. | 590 | /* Let's first see, if we want to try to unload this lib. |
588 | If the env. var KDE_DOUNLOAD is set, we try to unload every lib. | 591 | If the env. var KDE_DOUNLOAD is set, we try to unload every lib. |
589 | If not, we look at the lib itself, and unload it only, if it exports | 592 | If not, we look at the lib itself, and unload it only, if it exports |
590 | the symbol __kde_do_unload. */ | 593 | the symbol __kde_do_unload. */ |
591 | if (d->unload_mode != KLibLoaderPrivate::UNLOAD | 594 | if (d->unload_mode != KLibLoaderPrivate::UNLOAD |
592 | && wrap->unload_mode != KLibWrapPrivate::UNLOAD) | 595 | && wrap->unload_mode != KLibWrapPrivate::UNLOAD) |
593 | break; | 596 | break; |
594 | 597 | ||
595 | /* Now ensure, that the libs are only unloaded in the reverse direction | 598 | /* Now ensure, that the libs are only unloaded in the reverse direction |
596 | they were loaded. */ | 599 | they were loaded. */ |
597 | if (!d->pending_close.containsRef( wrap )) { | 600 | if (!d->pending_close.containsRef( wrap )) { |
598 | if (!deleted_one) | 601 | if (!deleted_one) |
599 | /* Only diagnose, if we really haven't deleted anything. */ | 602 | /* Only diagnose, if we really haven't deleted anything. */ |
600 | // kdDebug(150) << "try to dlclose " << wrap->name << ": not yet" << endl; | 603 | // kdDebug(150) << "try to dlclose " << wrap->name << ": not yet" << endl; |
601 | break; | 604 | break; |
602 | } | 605 | } |
603 | 606 | ||
604 | // kdDebug(150) << "try to dlclose " << wrap->name << ": yes, done." << endl; | 607 | // kdDebug(150) << "try to dlclose " << wrap->name << ": yes, done." << endl; |
605 | 608 | ||
606 | #if 0 | 609 | #if 0 |
607 | #ifndef Q_WS_QWS | 610 | #ifndef Q_WS_QWS |
608 | if ( !deleted_one ) { | 611 | if ( !deleted_one ) { |
609 | /* Only do the hack once in this loop. | 612 | /* Only do the hack once in this loop. |
610 | WABA: *HACK* | 613 | WABA: *HACK* |
611 | We need to make sure to clear the clipboard before unloading a DSO | 614 | We need to make sure to clear the clipboard before unloading a DSO |
612 | because the DSO could have defined an object derived from QMimeSource | 615 | because the DSO could have defined an object derived from QMimeSource |
613 | and placed that on the clipboard. */ | 616 | and placed that on the clipboard. */ |
614 | /*kapp->clipboard()->clear();*/ | 617 | /*kapp->clipboard()->clear();*/ |
615 | 618 | ||
616 | /* Well.. let's do something more subtle... convert the clipboard context | 619 | /* Well.. let's do something more subtle... convert the clipboard context |
617 | to text. That should be safe as it only uses objects defined by Qt. */ | 620 | to text. That should be safe as it only uses objects defined by Qt. */ |
618 | 621 | ||
619 | QWidgetList *widgetlist = QApplication::topLevelWidgets(); | 622 | QWidgetList *widgetlist = QApplication::topLevelWidgets(); |
620 | QWidget *co = widgetlist->first(); | 623 | QWidget *co = widgetlist->first(); |
621 | while (co) { | 624 | while (co) { |
622 | if (qstrcmp(co->name(), "internal clipboard owner") == 0) { | 625 | if (qstrcmp(co->name(), "internal clipboard owner") == 0) { |
623 | if (XGetSelectionOwner(co->x11Display(), XA_PRIMARY) == co->winId()) | 626 | if (XGetSelectionOwner(co->x11Display(), XA_PRIMARY) == co->winId()) |
624 | kapp->clipboard()->setText(kapp->clipboard()->text()); | 627 | kapp->clipboard()->setText(kapp->clipboard()->text()); |
625 | 628 | ||
626 | break; | 629 | break; |
627 | } | 630 | } |
628 | co = widgetlist->next(); | 631 | co = widgetlist->next(); |
629 | } | 632 | } |
630 | delete widgetlist; | 633 | delete widgetlist; |
631 | } | 634 | } |
632 | #else | 635 | #else |
633 | // FIXME(E): Implement in Qt Embedded | 636 | // FIXME(E): Implement in Qt Embedded |
634 | #endif | 637 | #endif |
635 | 638 | ||
636 | #endif // 0 | 639 | #endif // 0 |