• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kdecore
 

kdecore

kapplication.cpp
00001 /* This file is part of the KDE libraries
00002     Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org)
00003     Copyright (C) 1998, 1999, 2000 KDE Team
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019         */
00020 
00021 #include "config.h"
00022 
00023 #ifdef HAVE_XCOMPOSITE
00024 #define COMPOSITE
00025 #endif
00026 
00027 // #ifdef QTRANSLATOR_H
00028 // #error qtranslator.h was already included
00029 // #endif // QTRANSLATOR_H
00030 // 
00031 // #ifdef TQTRANSLATOR_H
00032 // #error tqtranslator.h was already included
00033 // #endif // TQTRANSLATOR_H
00034 
00035 #undef QT_NO_TRANSLATION
00036 #undef TQT_NO_TRANSLATION
00037 #include <tqtranslator.h>
00038 
00039 // FIXME
00040 // FOR BINARY COMPATIBILITY ONLY
00041 // REMOVE WHEN PRACTICAL!
00042 #define TDEAPPLICATION_BINARY_COMPAT_HACK 1
00043 #include "kapplication.h"
00044 #undef TDEAPPLICATION_BINARY_COMPAT_HACK
00045 
00046 #define QT_NO_TRANSLATION
00047 #define TQT_NO_TRANSLATION
00048 #include <tqdir.h>
00049 #include <tqptrcollection.h>
00050 #include <tqwidgetlist.h>
00051 #include <tqstrlist.h>
00052 #include <tqfile.h>
00053 #include <tqmessagebox.h>
00054 #include <tqtextstream.h>
00055 #include <tqregexp.h>
00056 #include <tqlineedit.h>
00057 #include <tqtextedit.h>
00058 #include <tqsessionmanager.h>
00059 #include <tqptrlist.h>
00060 #include <tqtimer.h>
00061 #include <tqstylesheet.h>
00062 #include <tqpixmapcache.h>
00063 #include <tqtooltip.h>
00064 #include <tqstylefactory.h>
00065 #include <tqmetaobject.h>
00066 #include <tqimage.h>
00067 #ifndef QT_NO_SQL
00068 #include <tqsqlpropertymap.h>
00069 #endif
00070 
00071 #include <kglobal.h>
00072 #include <kstandarddirs.h>
00073 #include <kdebug.h>
00074 #include <klocale.h>
00075 #include <kstyle.h>
00076 #include <kiconloader.h>
00077 #include <kclipboard.h>
00078 #include <kconfig.h>
00079 #include <ksimpleconfig.h>
00080 #include <kcmdlineargs.h>
00081 #include <kaboutdata.h>
00082 #include <kglobalsettings.h>
00083 #include <kcrash.h>
00084 #include <kdatastream.h>
00085 #include <klibloader.h>
00086 #include <kmimesourcefactory.h>
00087 #include <kstdaccel.h>
00088 #include <kaccel.h>
00089 #include "kcheckaccelerators.h"
00090 #include <tqptrdict.h>
00091 #include <kmacroexpander.h>
00092 #include <kshell.h>
00093 #include <kprotocolinfo.h>
00094 #include <kkeynative.h>
00095 #include <kmdcodec.h>
00096 #include <kglobalaccel.h>
00097 
00098 #if defined Q_WS_X11
00099 #include <kstartupinfo.h>
00100 #endif
00101 
00102 #include <dcopclient.h>
00103 #include <dcopref.h>
00104 
00105 #include <sys/types.h>
00106 #ifdef HAVE_SYS_STAT_H
00107 #include <sys/stat.h>
00108 #endif
00109 #include <sys/wait.h>
00110 #include <grp.h>
00111 #include <sys/types.h>
00112 
00113 #ifndef Q_WS_WIN
00114 #include "kwin.h"
00115 #endif
00116 
00117 #include <fcntl.h>
00118 #include <stdlib.h> // getenv(), srand(), rand()
00119 #include <signal.h>
00120 #include <unistd.h>
00121 #include <time.h>
00122 #include <sys/time.h>
00123 #include <errno.h>
00124 #include <string.h>
00125 #include <netdb.h>
00126 #if defined Q_WS_X11
00127 //#ifndef Q_WS_QWS //FIXME(E): NetWM should talk to QWS...
00128 #include <netwm.h>
00129 #endif
00130 
00131 #include "kprocctrl.h"
00132 
00133 #ifdef HAVE_PATHS_H
00134 #include <paths.h>
00135 #endif
00136 
00137 #ifdef Q_WS_X11
00138 #include <X11/Xlib.h>
00139 #ifdef COMPOSITE
00140 #include <X11/extensions/Xrender.h>
00141 #include <X11/extensions/Xcomposite.h>
00142 #include <dlfcn.h>
00143 #endif
00144 #include <X11/Xutil.h>
00145 #include <X11/Xatom.h>
00146 #include <X11/SM/SMlib.h>
00147 #include <fixx11h.h>
00148 #endif
00149 
00150 #include <pwd.h>
00151 
00152 #ifndef Q_WS_WIN
00153 #include <KDE-ICE/ICElib.h>
00154 #else
00155 typedef void* IceIOErrorHandler;
00156 #include <windows.h>
00157 //KDE4: remove
00158 #define Button1Mask (1<<8)
00159 #define Button2Mask (1<<9)
00160 #define Button3Mask (1<<10)
00161 #endif
00162 
00163 #ifdef Q_WS_X11
00164 #define DISPLAY "DISPLAY"
00165 #elif defined(Q_WS_QWS)
00166 #define DISPLAY "QWS_DISPLAY"
00167 #endif
00168 
00169 #if defined Q_WS_X11
00170 #include <kipc.h>
00171 #endif
00172 
00173 #ifdef Q_WS_MACX
00174 #include <Carbon/Carbon.h>
00175 #include <tqimage.h>
00176 #endif
00177 
00178 #include "kappdcopiface.h"
00179 
00180 // exported for kdm kfrontend
00181 KDE_EXPORT bool kde_have_kipc = true; // magic hook to disable kipc in kdm
00182 bool kde_kiosk_exception = false; // flag to disable kiosk restrictions
00183 bool kde_kiosk_admin = false;
00184 
00185 KApplication* KApplication::KApp = 0L;
00186 bool KApplication::loadedByKdeinit = false;
00187 DCOPClient *KApplication::s_DCOPClient = 0L;
00188 bool KApplication::s_dcopClientNeedsPostInit = false;
00189 
00190 #ifdef Q_WS_X11
00191 static Atom atom_DesktopWindow;
00192 static Atom atom_NetSupported;
00193 #endif
00194 
00195 #if defined(Q_WS_X11) && defined(COMPOSITE)
00196 static int composite_event, composite_error, composite_opcode;
00197 static bool x11_composite_error_generated;
00198 static int x11_error(Display *dpy, XErrorEvent *ev) {
00199     if (ev->request_code == composite_opcode && ev->minor_code == X_CompositeRedirectSubwindows)
00200     {
00201         x11_composite_error_generated = true;
00202         return 0;
00203     }
00204 }
00205 #endif
00206 
00207 // duplicated from patched Qt, so that there won't be unresolved symbols if Qt gets
00208 // replaced by unpatched one
00209 KDECORE_EXPORT bool qt_qclipboard_bailout_hack = false;
00210 
00211 template class TQPtrList<KSessionManaged>;
00212 
00213 #ifdef Q_WS_X11
00214 extern "C" {
00215 static int kde_xio_errhandler( Display * dpy )
00216 {
00217   return kapp->xioErrhandler( dpy );
00218 }
00219 
00220 static int kde_x_errhandler( Display *dpy, XErrorEvent *err )
00221 {
00222   return kapp->xErrhandler( dpy, err );
00223 }
00224 
00225 }
00226 
00227 extern "C" {
00228 static void kde_ice_ioerrorhandler( IceConn conn )
00229 {
00230     if(kapp)
00231         kapp->iceIOErrorHandler( conn );
00232     // else ignore the error for now
00233 }
00234 }
00235 #endif
00236 
00237 #ifdef Q_WS_WIN
00238 void KApplication_init_windows(bool GUIenabled);
00239 
00240 class QAssistantClient;
00241 #endif
00242 
00243 /*
00244   Private data to make keeping binary compatibility easier
00245  */
00246 class KApplicationPrivate
00247 {
00248 public:
00249   KApplicationPrivate()
00250     :   actionRestrictions( false ),
00251     refCount( 1 ),
00252     oldIceIOErrorHandler( 0 ),
00253     checkAccelerators( 0 ),
00254     overrideStyle( TQString::null ),
00255     startup_id( "0" ),
00256     app_started_timer( NULL ),
00257     m_KAppDCOPInterface( 0L ),
00258     session_save( false )
00259 #ifdef Q_WS_X11
00260     ,oldXErrorHandler( NULL )
00261     ,oldXIOErrorHandler( NULL )
00262 #elif defined Q_WS_WIN
00263     ,qassistantclient( 0 )
00264 #endif
00265   {
00266   }
00267 
00268   ~KApplicationPrivate()
00269   {
00270 #ifdef Q_WS_WIN
00271      delete qassistantclient;
00272 #endif
00273   }
00274 
00275 
00276   bool actionRestrictions : 1;
00277   bool guiEnabled : 1;
00284   int refCount;
00285   IceIOErrorHandler oldIceIOErrorHandler;
00286   KCheckAccelerators* checkAccelerators;
00287   TQString overrideStyle;
00288   TQString geometry_arg;
00289   TQCString startup_id;
00290   TQTimer* app_started_timer;
00291   KAppDCOPInterface *m_KAppDCOPInterface;
00292   bool session_save;
00293 #ifdef Q_WS_X11
00294   int (*oldXErrorHandler)(Display*,XErrorEvent*);
00295   int (*oldXIOErrorHandler)(Display*);
00296 #elif defined Q_WS_WIN
00297   QAssistantClient* qassistantclient;
00298 #endif
00299 
00300   class URLActionRule
00301   {
00302   public:
00303 #define checkExactMatch(s, b) \
00304         if (s.isEmpty()) b = true; \
00305         else if (s[s.length()-1] == '!') \
00306         { b = false; s.truncate(s.length()-1); } \
00307         else b = true;
00308 #define checkStartWildCard(s, b) \
00309         if (s.isEmpty()) b = true; \
00310         else if (s[0] == '*') \
00311         { b = true; s = s.mid(1); } \
00312         else b = false;
00313 #define checkEqual(s, b) \
00314         b = (s == "=");
00315 
00316      URLActionRule(const TQString &act,
00317                    const TQString &bProt, const TQString &bHost, const TQString &bPath,
00318                    const TQString &dProt, const TQString &dHost, const TQString &dPath,
00319                    bool perm)
00320                    : action(act),
00321                      baseProt(bProt), baseHost(bHost), basePath(bPath),
00322                      destProt(dProt), destHost(dHost), destPath(dPath),
00323                      permission(perm)
00324                    {
00325                       checkExactMatch(baseProt, baseProtWildCard);
00326                       checkStartWildCard(baseHost, baseHostWildCard);
00327                       checkExactMatch(basePath, basePathWildCard);
00328                       checkExactMatch(destProt, destProtWildCard);
00329                       checkStartWildCard(destHost, destHostWildCard);
00330                       checkExactMatch(destPath, destPathWildCard);
00331                       checkEqual(destProt, destProtEqual);
00332                       checkEqual(destHost, destHostEqual);
00333                    }
00334 
00335      bool baseMatch(const KURL &url, const TQString &protClass)
00336      {
00337         if (baseProtWildCard)
00338         {
00339            if ( !baseProt.isEmpty() && !url.protocol().startsWith(baseProt) &&
00340                 (protClass.isEmpty() || (protClass != baseProt)) )
00341               return false;
00342         }
00343         else
00344         {
00345            if ( (url.protocol() != baseProt) &&
00346                 (protClass.isEmpty() || (protClass != baseProt)) )
00347               return false;
00348         }
00349         if (baseHostWildCard)
00350         {
00351            if (!baseHost.isEmpty() && !url.host().endsWith(baseHost))
00352               return false;
00353         }
00354         else
00355         {
00356            if (url.host() != baseHost)
00357               return false;
00358         }
00359         if (basePathWildCard)
00360         {
00361            if (!basePath.isEmpty() && !url.path().startsWith(basePath))
00362               return false;
00363         }
00364         else
00365         {
00366            if (url.path() != basePath)
00367               return false;
00368         }
00369         return true;
00370      }
00371 
00372      bool destMatch(const KURL &url, const TQString &protClass, const KURL &base, const TQString &baseClass)
00373      {
00374         if (destProtEqual)
00375         {
00376            if ( (url.protocol() != base.protocol()) &&
00377                 (protClass.isEmpty() || baseClass.isEmpty() || protClass != baseClass) )
00378               return false;
00379         }
00380         else if (destProtWildCard)
00381         {
00382            if ( !destProt.isEmpty() && !url.protocol().startsWith(destProt) &&
00383                 (protClass.isEmpty() || (protClass != destProt)) )
00384               return false;
00385         }
00386         else
00387         {
00388            if ( (url.protocol() != destProt) &&
00389                 (protClass.isEmpty() || (protClass != destProt)) )
00390               return false;
00391         }
00392         if (destHostWildCard)
00393         {
00394            if (!destHost.isEmpty() && !url.host().endsWith(destHost))
00395               return false;
00396         }
00397         else if (destHostEqual)
00398         {
00399            if (url.host() != base.host())
00400               return false;
00401         }
00402         else
00403         {
00404            if (url.host() != destHost)
00405               return false;
00406         }
00407         if (destPathWildCard)
00408         {
00409            if (!destPath.isEmpty() && !url.path().startsWith(destPath))
00410               return false;
00411         }
00412         else
00413         {
00414            if (url.path() != destPath)
00415               return false;
00416         }
00417         return true;
00418      }
00419 
00420      TQString action;
00421      TQString baseProt;
00422      TQString baseHost;
00423      TQString basePath;
00424      TQString destProt;
00425      TQString destHost;
00426      TQString destPath;
00427      bool baseProtWildCard : 1;
00428      bool baseHostWildCard : 1;
00429      bool basePathWildCard : 1;
00430      bool destProtWildCard : 1;
00431      bool destHostWildCard : 1;
00432      bool destPathWildCard : 1;
00433      bool destProtEqual    : 1;
00434      bool destHostEqual    : 1;
00435      bool permission;
00436   };
00437   TQPtrList<URLActionRule> urlActionRestrictions;
00438 
00439     TQString sessionKey;
00440     TQString pSessionConfigFile;
00441 };
00442 
00443 
00444 static TQPtrList<TQWidget>*x11Filter = 0;
00445 static bool autoDcopRegistration = true;
00446 
00447 void KApplication::installX11EventFilter( TQWidget* filter )
00448 {
00449     if ( !filter )
00450         return;
00451     if (!x11Filter)
00452         x11Filter = new TQPtrList<TQWidget>;
00453     connect ( filter, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( x11FilterDestroyed() ) );
00454     x11Filter->append( filter );
00455 }
00456 
00457 void KApplication::x11FilterDestroyed()
00458 {
00459     removeX11EventFilter( static_cast< const TQWidget* >( sender()));
00460 }
00461 
00462 void KApplication::removeX11EventFilter( const TQWidget* filter )
00463 {
00464     if ( !x11Filter || !filter )
00465         return;
00466     x11Filter->removeRef( filter );
00467     if ( x11Filter->isEmpty() ) {
00468         delete x11Filter;
00469         x11Filter = 0;
00470     }
00471 }
00472 
00473 // FIXME: remove this when we've get a better method of
00474 // customizing accelerator handling -- hopefully in Qt.
00475 // For now, this is set whenever an accelerator is overridden
00476 // in KAccelEventHandler so that the AccelOverride isn't sent twice. -- ellis, 19/10/02
00477 extern bool kde_g_bKillAccelOverride;
00478 
00479 bool KApplication::notify(TQObject *receiver, TQEvent *event)
00480 {
00481     TQEvent::Type t = event->type();
00482     if (kde_g_bKillAccelOverride)
00483     {
00484        kde_g_bKillAccelOverride = false;
00485        // Indicate that the accelerator has been overridden.
00486        if (t == TQEvent::AccelOverride)
00487        {
00488           TQT_TQKEYEVENT(event)->accept();
00489           return true;
00490        }
00491        else
00492           kdWarning(125) << "kde_g_bKillAccelOverride set, but received an event other than AccelOverride." << endl;
00493     }
00494 
00495     if ((t == TQEvent::AccelOverride) || (t == TQEvent::KeyPress))
00496     {
00497        static const KShortcut& _selectAll = KStdAccel::selectAll();
00498        TQLineEdit *edit = ::tqqt_cast<TQLineEdit *>(receiver);
00499        if (edit)
00500        {
00501           // We have a keypress for a lineedit...
00502           TQKeyEvent *kevent = TQT_TQKEYEVENT(event);
00503           KKey key(kevent);
00504           if (_selectAll.contains(key))
00505           {
00506              if (t == TQEvent::KeyPress)
00507              {
00508                 edit->selectAll();
00509                 return true;
00510              }
00511              else
00512              {
00513                 kevent->accept();
00514              }
00515           }
00516           // Ctrl-U deletes from start of line.
00517           if (key == KKey(Qt::CTRL + Qt::Key_U))
00518           {
00519              if (t == TQEvent::KeyPress)
00520              {
00521                 if (!edit->isReadOnly())
00522                 {
00523                    TQString t(edit->text());
00524                    t = t.mid(edit->cursorPosition());
00525                    edit->validateAndSet(t, 0, 0, 0);
00526                 }
00527                 return true;
00528              }
00529              else
00530              {
00531                 kevent->accept();
00532              }
00533 
00534           }
00535        }
00536        TQTextEdit *medit = ::tqqt_cast<TQTextEdit *>(receiver);
00537        if (medit)
00538        {
00539           // We have a keypress for a multilineedit...
00540           TQKeyEvent *kevent = TQT_TQKEYEVENT(event);
00541           if (_selectAll.contains(KKey(kevent)))
00542           {
00543              if (t == TQEvent::KeyPress)
00544              {
00545                 medit->selectAll();
00546                 return true;
00547              }
00548              else
00549              {
00550                 kevent->accept();
00551              }
00552           }
00553        }
00554     }
00555     if( t == TQEvent::Show && receiver->isWidgetType())
00556     {
00557         TQWidget* w = TQT_TQWIDGET( receiver );
00558 #if defined Q_WS_X11
00559         if( w->isTopLevel() && !startupId().isEmpty() && !TQT_TQSHOWEVENT(event)->spontaneous()) // TODO better done using window group leader?
00560             KStartupInfo::setWindowStartupId( w->winId(), startupId());
00561 #endif
00562         if( w->isTopLevel() && !w->testWFlags( WX11BypassWM ) && !w->isPopup() && !event->spontaneous())
00563         {
00564             if( d->app_started_timer == NULL )
00565             {
00566                 d->app_started_timer = new TQTimer( this, "app_started_timer" );
00567                 connect( d->app_started_timer, TQT_SIGNAL( timeout()), TQT_SLOT( checkAppStartedSlot()));
00568             }
00569             if( !d->app_started_timer->isActive())
00570                 d->app_started_timer->start( 0, true );
00571         }
00572         if( w->isTopLevel() && ( w->icon() == NULL || w->icon()->isNull()))
00573         {
00574             // icon() cannot be null pixmap, it'll be the "unknown" icon - so check if there is this application icon
00575             static TQPixmap* ic = NULL;
00576             if( ic == NULL )
00577                 ic = new TQPixmap( KGlobal::iconLoader()->loadIcon( iconName(),
00578                     KIcon::NoGroup, 0, KIcon::DefaultState, NULL, true ));
00579             if( !ic->isNull())
00580             {
00581                 w->setIcon( *ic );
00582 #if defined Q_WS_X11
00583                 KWin::setIcons( w->winId(), *ic, miniIcon());
00584 #endif
00585             }
00586         }
00587     }
00588     return TQApplication::notify(receiver, event);
00589 }
00590 
00591 void KApplication::checkAppStartedSlot()
00592 {
00593 #if defined Q_WS_X11
00594     KStartupInfo::handleAutoAppStartedSending();
00595 #endif
00596 }
00597 
00598 // the help class for session management communication
00599 static TQPtrList<KSessionManaged>* sessionClients()
00600 {
00601     static TQPtrList<KSessionManaged>* session_clients = 0L;
00602     if ( !session_clients )
00603         session_clients = new TQPtrList<KSessionManaged>;
00604     return session_clients;
00605 }
00606 
00607 /*
00608   Auxiliary function to calculate a a session config name used for the
00609   instance specific config object.
00610   Syntax:  "session/<appname>_<sessionId>"
00611  */
00612 TQString KApplication::sessionConfigName() const
00613 {
00614     TQString sessKey = sessionKey();
00615     if ( sessKey.isEmpty() && !d->sessionKey.isEmpty() )
00616         sessKey = d->sessionKey;
00617     return TQString("session/%1_%2_%3").arg(name()).arg(sessionId()).arg(sessKey);
00618 }
00619 
00620 #ifdef Q_WS_X11
00621 static SmcConn mySmcConnection = 0;
00622 static SmcConn tmpSmcConnection = 0;
00623 #else
00624 // FIXME(E): Implement for Qt Embedded
00625 // Possibly "steal" XFree86's libSM?
00626 #endif
00627 static TQTime* smModificationTime = 0;
00628 
00629 KApplication::KApplication( int& argc, char** argv, const TQCString& rAppName,
00630                             bool allowStyles, bool GUIenabled, bool SMenabled ) :
00631   TQApplication( argc, argv, GUIenabled, SMenabled ), KInstance(rAppName),
00632 #ifdef Q_WS_X11
00633   display(0L),
00634   argb_visual(false),
00635 #endif
00636   d (new KApplicationPrivate())
00637 {
00638     aIconPixmap.pm.icon = 0L;
00639     aIconPixmap.pm.miniIcon = 0L;
00640     read_app_startup_id();
00641     if (!GUIenabled)
00642        allowStyles = false;
00643     useStyles = allowStyles;
00644     Q_ASSERT (!rAppName.isEmpty());
00645     setName(rAppName);
00646 
00647     installSigpipeHandler();
00648     KCmdLineArgs::initIgnore(argc, argv, rAppName.data());
00649     parseCommandLine( );
00650     init(GUIenabled);
00651     d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00652 }
00653 
00654 // FIXME
00655 // FOR BINARY COMPATIBILITY ONLY
00656 // REMOVE WHEN PRACTICAL!
00657 KApplication::KApplication( int& argc, char** argv, const TQCString& rAppName,
00658                             bool allowStyles, bool GUIenabled ) :
00659   TQApplication( argc, argv, GUIenabled ), KInstance(rAppName),
00660 #ifdef Q_WS_X11
00661   display(0L),
00662   argb_visual(false),
00663 #endif
00664   d (new KApplicationPrivate())
00665 {
00666     aIconPixmap.pm.icon = 0L;
00667     aIconPixmap.pm.miniIcon = 0L;
00668     read_app_startup_id();
00669     if (!GUIenabled)
00670        allowStyles = false;
00671     useStyles = allowStyles;
00672     Q_ASSERT (!rAppName.isEmpty());
00673     setName(rAppName);
00674 
00675     installSigpipeHandler();
00676     KCmdLineArgs::initIgnore(argc, argv, rAppName.data());
00677     parseCommandLine( );
00678     init(GUIenabled);
00679     d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00680 }
00681 
00682 KApplication::KApplication( bool allowStyles, bool GUIenabled, bool SMenabled ) :
00683 //  TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(), TRUE ),  // Qt4 requires that there always be a GUI
00684   TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(), GUIenabled, SMenabled ),   // We need to be able to run command line apps
00685   KInstance( KCmdLineArgs::about),
00686 #ifdef Q_WS_X11
00687   display(0L),
00688   argb_visual(false),
00689 #endif
00690   d (new KApplicationPrivate)
00691 {
00692     aIconPixmap.pm.icon = 0L;
00693     aIconPixmap.pm.miniIcon = 0L;
00694     read_app_startup_id();
00695     if (!GUIenabled)
00696        allowStyles = false;
00697     useStyles = allowStyles;
00698     setName( instanceName() );
00699 
00700     installSigpipeHandler();
00701     parseCommandLine( );
00702     init(GUIenabled);
00703     d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00704 }
00705 
00706 // FIXME
00707 // FOR BINARY COMPATIBILITY ONLY
00708 // REMOVE WHEN PRACTICAL!
00709 KApplication::KApplication( bool allowStyles, bool GUIenabled ) :
00710 //  TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(), TRUE ),  // Qt4 requires that there always be a GUI
00711   TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(), GUIenabled ),  // We need to be able to run command line apps
00712   KInstance( KCmdLineArgs::about),
00713 #ifdef Q_WS_X11
00714   display(0L),
00715   argb_visual(false),
00716 #endif
00717   d (new KApplicationPrivate)
00718 {
00719     aIconPixmap.pm.icon = 0L;
00720     aIconPixmap.pm.miniIcon = 0L;
00721     read_app_startup_id();
00722     if (!GUIenabled)
00723        allowStyles = false;
00724     useStyles = allowStyles;
00725     setName( instanceName() );
00726 
00727     installSigpipeHandler();
00728     parseCommandLine( );
00729     init(GUIenabled);
00730     d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00731 }
00732 
00733 #ifdef Q_WS_X11
00734 KApplication::KApplication( Display *dpy, bool allowStyles ) :
00735   TQApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
00736                 getX11RGBAVisual(dpy), getX11RGBAColormap(dpy) ),
00737   KInstance( KCmdLineArgs::about), display(0L), d (new KApplicationPrivate)
00738 {
00739     aIconPixmap.pm.icon = 0L;
00740     aIconPixmap.pm.miniIcon = 0L;
00741     read_app_startup_id();
00742     useStyles = allowStyles;
00743     setName( instanceName() );
00744     installSigpipeHandler();
00745     parseCommandLine( );
00746     init( true );
00747     d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00748 }
00749 
00750 KApplication::KApplication( Display *dpy, bool disable_argb, Qt::HANDLE visual, Qt::HANDLE colormap, bool allowStyles ) :
00751   TQApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
00752                 disable_argb?visual:getX11RGBAVisual(dpy), disable_argb?colormap:getX11RGBAColormap(dpy) ),
00753   KInstance( KCmdLineArgs::about), display(0L), d (new KApplicationPrivate)
00754 {
00755     aIconPixmap.pm.icon = 0L;
00756     aIconPixmap.pm.miniIcon = 0L;
00757     read_app_startup_id();
00758     useStyles = allowStyles;
00759     if (disable_argb) argb_visual = false;
00760     setName( instanceName() );
00761     installSigpipeHandler();
00762     parseCommandLine( );
00763     init( true );
00764     d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00765 }
00766 
00767 KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
00768                     bool allowStyles ) :
00769   TQApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
00770                 visual?visual:getX11RGBAVisual(dpy), colormap?colormap:getX11RGBAColormap(dpy) ),
00771   KInstance( KCmdLineArgs::about), display(0L), d (new KApplicationPrivate)
00772 {
00773     if ((visual) && (colormap))
00774         getX11RGBAInformation(dpy);
00775     aIconPixmap.pm.icon = 0L;
00776     aIconPixmap.pm.miniIcon = 0L;
00777     read_app_startup_id();
00778     useStyles = allowStyles;
00779     setName( instanceName() );
00780     installSigpipeHandler();
00781     parseCommandLine( );
00782     init( true );
00783     d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00784 }
00785 
00786 KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
00787                     bool allowStyles, KInstance * _instance ) :
00788   TQApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
00789                 visual?visual:getX11RGBAVisual(dpy), colormap?colormap:getX11RGBAColormap(dpy) ),
00790   KInstance( _instance ), display(0L), d (new KApplicationPrivate)
00791 {
00792     if ((visual) && (colormap))
00793         getX11RGBAInformation(dpy);
00794     aIconPixmap.pm.icon = 0L;
00795     aIconPixmap.pm.miniIcon = 0L;
00796     read_app_startup_id();
00797     useStyles = allowStyles;
00798     setName( instanceName() );
00799     installSigpipeHandler();
00800     parseCommandLine( );
00801     init( true );
00802     d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00803 }
00804 #endif
00805 
00806 KApplication::KApplication( bool allowStyles, bool GUIenabled, KInstance* _instance ) :
00807   TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
00808                 GUIenabled ),
00809   KInstance( _instance ),
00810 #ifdef Q_WS_X11
00811   display(0L),
00812 #endif
00813   argb_visual(false),
00814   d (new KApplicationPrivate)
00815 {
00816     aIconPixmap.pm.icon = 0L;
00817     aIconPixmap.pm.miniIcon = 0L;
00818     read_app_startup_id();
00819     if (!GUIenabled)
00820        allowStyles = false;
00821     useStyles = allowStyles;
00822     setName( instanceName() );
00823 
00824     installSigpipeHandler();
00825     parseCommandLine( );
00826     init(GUIenabled);
00827     d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00828 }
00829 
00830 #ifdef Q_WS_X11
00831 KApplication::KApplication(Display *display, int& argc, char** argv, const TQCString& rAppName,
00832                            bool allowStyles, bool GUIenabled ) :
00833   TQApplication( display ), KInstance(rAppName),
00834   display(0L),
00835   argb_visual(false),
00836   d (new KApplicationPrivate())
00837 {
00838     aIconPixmap.pm.icon = 0L;
00839     aIconPixmap.pm.miniIcon = 0L;
00840     read_app_startup_id();
00841     if (!GUIenabled)
00842        allowStyles = false;
00843     useStyles = allowStyles;
00844 
00845     Q_ASSERT (!rAppName.isEmpty());
00846     setName(rAppName);
00847 
00848     installSigpipeHandler();
00849     KCmdLineArgs::initIgnore(argc, argv, rAppName.data());
00850     parseCommandLine( );
00851     init(GUIenabled);
00852     d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00853 }
00854 #endif
00855 
00856 int KApplication::xioErrhandler( Display* dpy )
00857 {
00858     if(kapp)
00859     {
00860         emit shutDown();
00861 #ifdef Q_WS_X11
00862         d->oldXIOErrorHandler( dpy );
00863 #else
00864         Q_UNUSED(dpy);
00865 #endif
00866     }
00867     exit( 1 );
00868     return 0;
00869 }
00870 
00871 int KApplication::xErrhandler( Display* dpy, void* err_ )
00872 { // no idea how to make forward decl. for XErrorEvent
00873 #ifdef Q_WS_X11
00874     XErrorEvent* err = static_cast< XErrorEvent* >( err_ );
00875     if(kapp)
00876     {
00877         // add KDE specific stuff here
00878         d->oldXErrorHandler( dpy, err );
00879     }
00880 #endif
00881     return 0;
00882 }
00883 
00884 void KApplication::iceIOErrorHandler( _IceConn *conn )
00885 {
00886     emit shutDown();
00887 
00888 #ifdef Q_WS_X11
00889     if ( d->oldIceIOErrorHandler != NULL )
00890       (*d->oldIceIOErrorHandler)( conn );
00891 #endif
00892     exit( 1 );
00893 }
00894 
00895 class KDETranslator : public TQTranslator
00896 {
00897 public:
00898   KDETranslator(TQObject *parent) : TQTranslator(parent, "kdetranslator") {}
00899   virtual TQTranslatorMessage findMessage(const char* context,
00900                      const char *sourceText,
00901                      const char* message) const
00902   {
00903     TQTranslatorMessage res;
00904     res.setTranslation(KGlobal::locale()->translateQt(context, sourceText, message));
00905     return res;
00906   }
00907 };
00908 
00909 void KApplication::init(bool GUIenabled)
00910 {
00911   d->guiEnabled = GUIenabled;
00912   if ((getuid() != geteuid()) ||
00913       (getgid() != getegid()) )
00914   {
00915      // man permissions are not exploitable and better than 
00916      // world writable directories
00917      struct group *man = getgrnam("man");
00918      if ( !man || man->gr_gid != getegid() ){
00919        fprintf(stderr, "The KDE libraries are not designed to run with suid privileges.\n");
00920        ::exit(127);
00921      }
00922   }
00923 
00924   KProcessController::ref();
00925 
00926   (void) KClipboardSynchronizer::self();
00927 
00928   TQApplication::setDesktopSettingsAware( false );
00929 
00930   KApp = this;
00931 
00932 
00933 #ifdef Q_WS_X11 //FIXME(E)
00934   // create all required atoms in _one_ roundtrip to the X server
00935   if ( GUIenabled ) {
00936       const int max = 20;
00937       Atom* atoms[max];
00938       char* names[max];
00939       Atom atoms_return[max];
00940       int n = 0;
00941 
00942       atoms[n] = &kipcCommAtom;
00943       names[n++] = (char *) "KIPC_COMM_ATOM";
00944 
00945       atoms[n] = &atom_DesktopWindow;
00946       names[n++] = (char *) "KDE_DESKTOP_WINDOW";
00947 
00948       atoms[n] = &atom_NetSupported;
00949       names[n++] = (char *) "_NET_SUPPORTED";
00950 
00951       XInternAtoms( qt_xdisplay(), names, n, false, atoms_return );
00952 
00953       for (int i = 0; i < n; i++ )
00954       *atoms[i] = atoms_return[i];
00955   }
00956 #endif
00957 
00958   dcopAutoRegistration();
00959   dcopClientPostInit();
00960 
00961   smw = 0;
00962 
00963   // Initial KIPC event mask.
00964 #if defined Q_WS_X11
00965   kipcEventMask = (1 << KIPC::StyleChanged) | (1 << KIPC::PaletteChanged) |
00966                   (1 << KIPC::FontChanged) | (1 << KIPC::BackgroundChanged) |
00967                   (1 << KIPC::ToolbarStyleChanged) | (1 << KIPC::SettingsChanged) |
00968                   (1 << KIPC::ClipboardConfigChanged) | (1 << KIPC::BlockShortcuts);
00969 #endif
00970 
00971   // Trigger creation of locale.
00972   (void) KGlobal::locale();
00973 
00974   KConfig* config = KGlobal::config();
00975   d->actionRestrictions = config->hasGroup("KDE Action Restrictions" ) && !kde_kiosk_exception;
00976   // For brain-dead configurations where the user's local config file is not writable.
00977   // * We use kdialog to warn the user, so we better not generate warnings from
00978   //   kdialog itself.
00979   // * Don't warn if we run with a read-only $HOME
00980   TQCString readOnly = getenv("KDE_HOME_READONLY");
00981   if (readOnly.isEmpty() && (tqstrcmp(name(), "kdialog") != 0))
00982   {
00983     KConfigGroupSaver saver(config, "KDE Action Restrictions");
00984     if (config->readBoolEntry("warn_unwritable_config",true))
00985        config->checkConfigFilesWritable(true);
00986   }
00987 
00988   if (GUIenabled)
00989   {
00990 #ifdef Q_WS_X11
00991     // this is important since we fork() to launch the help (Matthias)
00992     fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, FD_CLOEXEC);
00993     // set up the fancy (=robust and error ignoring ) KDE xio error handlers (Matthias)
00994     d->oldXErrorHandler = XSetErrorHandler( kde_x_errhandler );
00995     d->oldXIOErrorHandler = XSetIOErrorHandler( kde_xio_errhandler );
00996 #endif
00997 
00998     connect( this, TQT_SIGNAL( aboutToQuit() ), this, TQT_SIGNAL( shutDown() ) );
00999 
01000 #ifdef Q_WS_X11 //FIXME(E)
01001     display = desktop()->x11Display();
01002 #endif
01003 
01004     {
01005         TQStringList plugins = KGlobal::dirs()->resourceDirs( "qtplugins" );
01006         TQStringList::Iterator it = plugins.begin();
01007         while (it != plugins.end()) {
01008             addLibraryPath( *it );
01009             ++it;
01010         }
01011 
01012     }
01013     kdisplaySetStyle();
01014     kdisplaySetFont();
01015 //    kdisplaySetPalette(); done by kdisplaySetStyle
01016     propagateSettings(SETTINGS_QT);
01017 
01018     // Set default mime-source factory
01019     // XXX: This is a hack. Make our factory the default factory, but add the
01020     // previous default factory to the list of factories. Why? When the default
01021     // factory can't resolve something, it iterates in the list of factories.
01022     // But it TQWhatsThis only uses the default factory. So if there was already
01023     // a default factory (which happens when using an image library using uic),
01024     // we prefer KDE's factory and so we put that old default factory in the
01025     // list and use KDE as the default. This may speed up things as well.
01026     TQMimeSourceFactory* oldDefaultFactory = TQMimeSourceFactory::takeDefaultFactory();
01027     TQMimeSourceFactory::setDefaultFactory( mimeSourceFactory() );
01028     if ( oldDefaultFactory ) {
01029         TQMimeSourceFactory::addFactory( oldDefaultFactory );
01030     }
01031 
01032     d->checkAccelerators = new KCheckAccelerators( TQT_TQOBJECT(this) );
01033   }
01034 
01035 #ifdef Q_WS_MACX
01036   if (GUIenabled) {
01037       TQPixmap pixmap = KGlobal::iconLoader()->loadIcon( KCmdLineArgs::appName(),
01038               KIcon::NoGroup, KIcon::SizeLarge, KIcon::DefaultState, 0L, false );
01039       if (!pixmap.isNull()) {
01040           TQImage i = pixmap.convertToImage().convertDepth(32).smoothScale(40, 40);
01041           for(int y = 0; y < i.height(); y++) {
01042               uchar *l = i.scanLine(y);
01043               for(int x = 0; x < i.width(); x+=4)
01044                   *(l+x) = 255;
01045           }
01046           CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
01047           CGDataProviderRef dp = CGDataProviderCreateWithData(NULL,
01048                   i.bits(), i.numBytes(), NULL);
01049           CGImageRef ir = CGImageCreate(i.width(), i.height(), 8, 32, i.bytesPerLine(),
01050                   cs, kCGImageAlphaNoneSkipFirst, dp,
01051                   0, 0, kCGRenderingIntentDefault);
01052           //cleanup
01053           SetApplicationDockTileImage(ir);
01054           CGImageRelease(ir);
01055           CGColorSpaceRelease(cs);
01056           CGDataProviderRelease(dp);
01057       }
01058   }
01059 #endif
01060 
01061 
01062   // save and restore the RTL setting, as installTranslator calls qt_detectRTLLanguage,
01063   // which makes it impossible to use the -reverse cmdline switch with KDE apps
01064   bool rtl = reverseLayout();
01065   installTranslator(new KDETranslator(TQT_TQOBJECT(this)));
01066   setReverseLayout( rtl );
01067   if (i18n( "_: Dear Translator! Translate this string to the string 'LTR' in "
01068      "left-to-right languages (as english) or to 'RTL' in right-to-left "
01069      "languages (such as Hebrew and Arabic) to get proper widget layout." ) == "RTL")
01070     setReverseLayout( !rtl );
01071 
01072   // install appdata resource type
01073   KGlobal::dirs()->addResourceType("appdata", KStandardDirs::kde_default("data")
01074                                    + TQString::fromLatin1(name()) + '/');
01075   pSessionConfig = 0L;
01076   bSessionManagement = true;
01077 
01078 #ifdef Q_WS_X11
01079   // register a communication window for desktop changes (Matthias)
01080   if (GUIenabled && kde_have_kipc )
01081   {
01082     smw = new TQWidget(0,0);
01083     long data = 1;
01084     XChangeProperty(qt_xdisplay(), smw->winId(),
01085             atom_DesktopWindow, atom_DesktopWindow,
01086             32, PropModeReplace, (unsigned char *)&data, 1);
01087   }
01088   d->oldIceIOErrorHandler = IceSetIOErrorHandler( kde_ice_ioerrorhandler );
01089 #elif defined(Q_WS_WIN)
01090   KApplication_init_windows(GUIenabled);
01091 #else
01092   // FIXME(E): Implement for Qt Embedded
01093 #endif
01094 }
01095 
01096 static int my_system (const char *command) {
01097    int pid, status;
01098 
01099    pid = fork();
01100    if (pid == -1)
01101       return -1;
01102    if (pid == 0) {
01103       const char* shell = "/bin/sh";
01104       execl(shell, shell, "-c", command, (void *)0);
01105       ::_exit(127);
01106    }
01107    do {
01108       if (waitpid(pid, &status, 0) == -1) {
01109          if (errno != EINTR)
01110             return -1;
01111        } else
01112             return status;
01113    } while(1);
01114 }
01115 
01116 
01117 DCOPClient *KApplication::dcopClient()
01118 {
01119   if (s_DCOPClient)
01120     return s_DCOPClient;
01121 
01122   s_DCOPClient = new DCOPClient();
01123   KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde");
01124   if (args && args->isSet("dcopserver"))
01125   {
01126     s_DCOPClient->setServerAddress( args->getOption("dcopserver"));
01127   }
01128   if( kapp ) {
01129     connect(s_DCOPClient, TQT_SIGNAL(attachFailed(const TQString &)),
01130             kapp, TQT_SLOT(dcopFailure(const TQString &)));
01131     connect(s_DCOPClient, TQT_SIGNAL(blockUserInput(bool) ),
01132             kapp, TQT_SLOT(dcopBlockUserInput(bool)) );
01133   }
01134   else
01135     s_dcopClientNeedsPostInit = true;
01136 
01137   DCOPClient::setMainClient( s_DCOPClient );
01138   return s_DCOPClient;
01139 }
01140 
01141 void KApplication::dcopClientPostInit()
01142 {
01143   if( s_dcopClientNeedsPostInit )
01144     {
01145     s_dcopClientNeedsPostInit = false;
01146     connect(s_DCOPClient, TQT_SIGNAL(blockUserInput(bool) ),
01147             TQT_SLOT(dcopBlockUserInput(bool)) );
01148     s_DCOPClient->bindToApp(); // Make sure we get events from the DCOPClient.
01149     }
01150 }
01151 
01152 void KApplication::dcopAutoRegistration()
01153 {
01154   if (autoDcopRegistration)
01155      {
01156      ( void ) dcopClient();
01157      if( dcopClient()->appId().isEmpty())
01158          dcopClient()->registerAs(name());
01159      }
01160 }
01161 
01162 void KApplication::disableAutoDcopRegistration()
01163 {
01164   autoDcopRegistration = false;
01165 }
01166 
01167 KConfig* KApplication::sessionConfig()
01168 {
01169     if (pSessionConfig)
01170         return pSessionConfig;
01171 
01172     // create an instance specific config object
01173     pSessionConfig = new KConfig( sessionConfigName(), false, false);
01174     return pSessionConfig;
01175 }
01176 
01177 void KApplication::ref()
01178 {
01179     d->refCount++;
01180     //kdDebug() << "[kdecore-kapplication] KApplication::ref() : refCount = " << d->refCount << endl;
01181 }
01182 
01183 void KApplication::deref()
01184 {
01185     d->refCount--;
01186     //kdDebug() << "[kdecore-kapplication] KApplication::deref() : refCount = " << d->refCount << endl;
01187     if ( d->refCount <= 0 )
01188         quit();
01189 }
01190 
01191 KSessionManaged::KSessionManaged()
01192 {
01193     sessionClients()->remove( this );
01194     sessionClients()->append( this );
01195 }
01196 
01197 KSessionManaged::~KSessionManaged()
01198 {
01199     sessionClients()->remove( this );
01200 }
01201 
01202 bool KSessionManaged::saveState(TQSessionManager&)
01203 {
01204     return true;
01205 }
01206 
01207 bool KSessionManaged::commitData(TQSessionManager&)
01208 {
01209     return true;
01210 }
01211 
01212 
01213 void KApplication::disableSessionManagement() {
01214   bSessionManagement = false;
01215 }
01216 
01217 void KApplication::enableSessionManagement() {
01218   bSessionManagement = true;
01219 #ifdef Q_WS_X11
01220   // Session management support in Qt/KDE is awfully broken.
01221   // If konqueror disables session management right after its startup,
01222   // and enables it later (preloading stuff), it won't be properly
01223   // saved on session shutdown.
01224   // I'm not actually sure why it doesn't work, but saveState()
01225   // doesn't seem to be called on session shutdown, possibly
01226   // because disabling session management after konqueror startup
01227   // disabled it somehow. Forcing saveState() here for this application
01228   // seems to fix it.
01229   if( mySmcConnection ) {
01230         SmcRequestSaveYourself( mySmcConnection, SmSaveLocal, False,
01231                 SmInteractStyleAny,
01232                 False, False );
01233 
01234     // flush the request
01235     IceFlush(SmcGetIceConnection(mySmcConnection));
01236   }
01237 #endif
01238 }
01239 
01240 
01241 bool KApplication::requestShutDown(
01242     ShutdownConfirm confirm, ShutdownType sdtype, ShutdownMode sdmode )
01243 {
01244 #ifdef Q_WS_X11
01245     TQApplication::syncX();
01246     /*  use ksmserver's dcop interface if necessary  */
01247     if ( confirm == ShutdownConfirmYes ||
01248          sdtype != ShutdownTypeDefault ||
01249          sdmode != ShutdownModeDefault )
01250     {
01251         TQByteArray data;
01252         TQDataStream arg(data, IO_WriteOnly);
01253         arg << (int)confirm << (int)sdtype << (int)sdmode;
01254     return dcopClient()->send( "ksmserver", "ksmserver",
01255                                    "logout(int,int,int)", data );
01256     }
01257 
01258     if ( mySmcConnection ) {
01259         // we already have a connection to the session manager, use it.
01260         SmcRequestSaveYourself( mySmcConnection, SmSaveBoth, True,
01261                 SmInteractStyleAny,
01262                 confirm == ShutdownConfirmNo, True );
01263 
01264     // flush the request
01265     IceFlush(SmcGetIceConnection(mySmcConnection));
01266         return true;
01267     }
01268 
01269     // open a temporary connection, if possible
01270 
01271     propagateSessionManager();
01272     TQCString smEnv = ::getenv("SESSION_MANAGER");
01273     if (smEnv.isEmpty())
01274         return false;
01275 
01276     if (! tmpSmcConnection) {
01277     char cerror[256];
01278     char* myId = 0;
01279     char* prevId = 0;
01280     SmcCallbacks cb;
01281     tmpSmcConnection = SmcOpenConnection( 0, 0, 1, 0,
01282                           0, &cb,
01283                           prevId,
01284                           &myId,
01285                           255,
01286                           cerror );
01287     ::free( myId ); // it was allocated by C
01288     if (!tmpSmcConnection )
01289         return false;
01290     }
01291 
01292     SmcRequestSaveYourself( tmpSmcConnection, SmSaveBoth, True,
01293                 SmInteractStyleAny, False, True );
01294 
01295     // flush the request
01296     IceFlush(SmcGetIceConnection(tmpSmcConnection));
01297     return true;
01298 #else
01299     // FIXME(E): Implement for Qt Embedded
01300     return false;
01301 #endif
01302 }
01303 
01304 void KApplication::propagateSessionManager()
01305 {
01306 #ifdef Q_WS_X11
01307     TQCString fName = TQFile::encodeName(locateLocal("socket", "KSMserver"));
01308     TQCString display = ::getenv(DISPLAY);
01309     // strip the screen number from the display
01310     display.replace(TQRegExp("\\.[0-9]+$"), "");
01311     int i;
01312     while( (i = display.find(':')) >= 0)
01313        display[i] = '_';
01314 
01315     fName += "_"+display;
01316     TQCString smEnv = ::getenv("SESSION_MANAGER");
01317     bool check = smEnv.isEmpty();
01318     if ( !check && smModificationTime ) {
01319          TQFileInfo info( fName );
01320          TQTime current = TQT_TQTIME_OBJECT(info.lastModified().time());
01321          check = current > *smModificationTime;
01322     }
01323     if ( check ) {
01324         delete smModificationTime;
01325         TQFile f( fName );
01326         if ( !f.open( IO_ReadOnly ) )
01327             return;
01328         TQFileInfo info ( f );
01329         smModificationTime = new TQTime( TQT_TQTIME_OBJECT(info.lastModified().time()) );
01330         TQTextStream t(&f);
01331         t.setEncoding( TQTextStream::Latin1 );
01332         TQString s = t.readLine();
01333         f.close();
01334         ::setenv( "SESSION_MANAGER", s.latin1(), true  );
01335     }
01336 #endif
01337 }
01338 
01339 void KApplication::commitData( TQSessionManager& sm )
01340 {
01341     d->session_save = true;
01342     bool canceled = false;
01343     for (KSessionManaged* it = sessionClients()->first();
01344          it && !canceled;
01345          it = sessionClients()->next() ) {
01346         canceled = !it->commitData( sm );
01347     }
01348     if ( canceled )
01349         sm.cancel();
01350 
01351     if ( sm.allowsInteraction() ) {
01352         TQWidgetList done;
01353         TQWidgetList *list = TQApplication::topLevelWidgets();
01354         bool canceled = false;
01355         TQWidget* w = list->first();
01356         while ( !canceled && w ) {
01357             if ( !w->testWState( WState_ForceHide ) && !w->inherits("KMainWindow") ) {
01358                 TQCloseEvent e;
01359                 sendEvent( w, &e );
01360                 canceled = !e.isAccepted();
01361                 if ( !canceled )
01362                     done.append( w );
01363                 delete list; // one never knows...
01364                 list = TQApplication::topLevelWidgets();
01365                 w = list->first();
01366             } else {
01367                 w = list->next();
01368             }
01369             while ( w && done.containsRef( w ) )
01370                 w = list->next();
01371         }
01372         delete list;
01373     }
01374 
01375 
01376     if ( !bSessionManagement )
01377         sm.setRestartHint( TQSessionManager::RestartNever );
01378     else
01379     sm.setRestartHint( TQSessionManager::RestartIfRunning );
01380     d->session_save = false;
01381 }
01382 
01383 static void checkRestartVersion( TQSessionManager& sm )
01384 {
01385     Display* dpy = qt_xdisplay();
01386     Atom type;
01387     int format;
01388     unsigned long nitems, after;
01389     unsigned char* data;
01390     if( XGetWindowProperty( dpy, RootWindow( dpy, 0 ), XInternAtom( dpy, "TDE_FULL_SESSION", False ),
01391         0, 1, False, AnyPropertyType, &type, &format, &nitems, &after, &data ) == Success ) {
01392         if( data != NULL )
01393             XFree( data );
01394         if( type == XA_STRING && format == 8 ) { // session set, check if KDE_SESSION_VERSION is not set (meaning KDE3)
01395             if( XGetWindowProperty( dpy, RootWindow( dpy, 0 ), XInternAtom( dpy, "KDE_SESSION_VERSION", False ),
01396                 0, 1, False, AnyPropertyType, &type, &format, &nitems, &after, &data ) == Success ) {
01397                 if( data != NULL )
01398                     XFree( data ); // KDE4 or newer
01399                 if( type == None )
01400                     return; // we run in our native session, no need to wrap
01401             } else {
01402                 return; // we run in our native session, no need to wrap
01403             }
01404         }
01405     }
01406     TQString wrapper = KStandardDirs::findExe( "trinity" );
01407     TQStringList restartCommand = sm.restartCommand();
01408     restartCommand.prepend( wrapper );
01409     sm.setRestartCommand( restartCommand );
01410 }
01411 
01412 void KApplication::saveState( TQSessionManager& sm )
01413 {
01414     d->session_save = true;
01415 #ifdef Q_WS_X11
01416     static bool firstTime = true;
01417     mySmcConnection = (SmcConn) sm.handle();
01418 
01419     if ( !bSessionManagement ) {
01420         sm.setRestartHint( TQSessionManager::RestartNever );
01421     d->session_save = false;
01422         return;
01423     }
01424     else
01425     sm.setRestartHint( TQSessionManager::RestartIfRunning );
01426 
01427     if ( firstTime ) {
01428         firstTime = false;
01429     d->session_save = false;
01430         return; // no need to save the state.
01431     }
01432 
01433     // remove former session config if still existing, we want a new
01434     // and fresh one. Note that we do not delete the config file here,
01435     // this is done by the session manager when it executes the
01436     // discard commands. In fact it would be harmful to remove the
01437     // file here, as the session might be stored under a different
01438     // name, meaning the user still might need it eventually.
01439     if ( pSessionConfig ) {
01440         delete pSessionConfig;
01441         pSessionConfig = 0;
01442     }
01443 
01444     // tell the session manager about our new lifecycle
01445     TQStringList restartCommand = sm.restartCommand();
01446 
01447     TQCString multiHead = getenv("KDE_MULTIHEAD");
01448     if (multiHead.lower() == "true") {
01449         // if multihead is enabled, we save our -display argument so that
01450         // we are restored onto the correct head... one problem with this
01451         // is that the display is hard coded, which means we cannot restore
01452         // to a different display (ie. if we are in a university lab and try,
01453         // try to restore a multihead session, our apps could be started on
01454         // someone else's display instead of our own)
01455         TQCString displayname = getenv(DISPLAY);
01456         if (! displayname.isNull()) {
01457             // only store the command if we actually have a DISPLAY
01458             // environment variable
01459             restartCommand.append("-display");
01460             restartCommand.append(displayname);
01461         }
01462         sm.setRestartCommand( restartCommand );
01463     }
01464 
01465     checkRestartVersion( sm );
01466 
01467     // finally: do session management
01468     emit saveYourself(); // for compatibility
01469     bool canceled = false;
01470     for (KSessionManaged* it = sessionClients()->first();
01471          it && !canceled;
01472          it = sessionClients()->next() ) {
01473         canceled = !it->saveState( sm );
01474     }
01475 
01476     // if we created a new session config object, register a proper discard command
01477     if ( pSessionConfig ) {
01478         pSessionConfig->sync();
01479         TQStringList discard;
01480         discard  << "rm" << locateLocal("config", sessionConfigName());
01481         sm.setDiscardCommand( discard );
01482     } else {
01483     sm.setDiscardCommand( TQStringList("") );
01484     }
01485 
01486     if ( canceled )
01487         sm.cancel();
01488 #else
01489     // FIXME(E): Implement for Qt Embedded
01490 #endif
01491     d->session_save = false;
01492 }
01493 
01494 bool KApplication::sessionSaving() const
01495 {
01496     return d->session_save;
01497 }
01498 
01499 void KApplication::startKdeinit()
01500 {
01501 #ifndef Q_WS_WIN //TODO
01502   KInstance inst( "startkdeinitlock" );
01503   KLockFile lock( locateLocal( "tmp", "startkdeinitlock", &inst ));
01504   if( lock.lock( KLockFile::LockNoBlock ) != KLockFile::LockOK ) {
01505      lock.lock();
01506      DCOPClient cl;
01507      if( cl.attach())
01508          return; // whoever held the lock has already started dcopserver
01509   }
01510   // Try to launch kdeinit.
01511   TQString srv = KStandardDirs::findExe(TQString::fromLatin1("kdeinit"));
01512   if (srv.isEmpty())
01513      srv = KStandardDirs::findExe(TQString::fromLatin1("kdeinit"), KGlobal::dirs()->kfsstnd_defaultbindir());
01514   if (srv.isEmpty())
01515      return;
01516   if (kapp && (Tty != kapp->type()))
01517     setOverrideCursor( tqwaitCursor );
01518   my_system(TQFile::encodeName(srv)+" --suicide"+" --new-startup");
01519   if (kapp && (Tty != kapp->type()))
01520     restoreOverrideCursor();
01521 #endif
01522 }
01523 
01524 void KApplication::dcopFailure(const TQString &msg)
01525 {
01526   static int failureCount = 0;
01527   failureCount++;
01528   if (failureCount == 1)
01529   {
01530      startKdeinit();
01531      return;
01532   }
01533   if (failureCount == 2)
01534   {
01535 #ifdef Q_WS_WIN
01536      KGlobal::config()->setGroup("General");
01537      if (KGlobal::config()->readBoolEntry("ignoreDCOPFailures", false))
01538          return;
01539 #endif
01540      TQString msgStr(i18n("There was an error setting up inter-process "
01541                       "communications for KDE. The message returned "
01542                       "by the system was:\n\n"));
01543      msgStr += msg;
01544      msgStr += i18n("\n\nPlease check that the \"dcopserver\" program is running!");
01545 
01546      if (Tty != kapp->type())
01547      {
01548        TQMessageBox::critical
01549          (
01550            kapp->mainWidget(),
01551            i18n("DCOP communications error (%1)").arg(kapp->caption()),
01552            msgStr,
01553            i18n("&OK")
01554          );
01555      }
01556      else
01557      {
01558        fprintf(stderr, "%s\n", msgStr.local8Bit().data());
01559      }
01560 
01561      return;
01562   }
01563 }
01564 
01565 static const KCmdLineOptions qt_options[] =
01566 {
01567   //FIXME: Check if other options are specific to Qt/X11
01568 #ifdef Q_WS_X11
01569    { "display <displayname>", I18N_NOOP("Use the X-server display 'displayname'"), 0},
01570 #else
01571    { "display <displayname>", I18N_NOOP("Use the QWS display 'displayname'"), 0},
01572 #endif
01573    { "session <sessionId>", I18N_NOOP("Restore the application for the given 'sessionId'"), 0},
01574    { "cmap", I18N_NOOP("Causes the application to install a private color\nmap on an 8-bit display"), 0},
01575    { "ncols <count>", I18N_NOOP("Limits the number of colors allocated in the color\ncube on an 8-bit display, if the application is\nusing the TQApplication::ManyColor color\nspecification"), 0},
01576    { "nograb", I18N_NOOP("tells Qt to never grab the mouse or the keyboard"), 0},
01577    { "dograb", I18N_NOOP("running under a debugger can cause an implicit\n-nograb, use -dograb to override"), 0},
01578    { "sync", I18N_NOOP("switches to synchronous mode for debugging"), 0},
01579    { "fn", 0, 0},
01580    { "font <fontname>", I18N_NOOP("defines the application font"), 0},
01581    { "bg", 0, 0},
01582    { "background <color>", I18N_NOOP("sets the default background color and an\napplication palette (light and dark shades are\ncalculated)"), 0},
01583    { "fg", 0, 0},
01584    { "foreground <color>", I18N_NOOP("sets the default foreground color"), 0},
01585    { "btn", 0, 0},
01586    { "button <color>", I18N_NOOP("sets the default button color"), 0},
01587    { "name <name>", I18N_NOOP("sets the application name"), 0},
01588    { "title <title>", I18N_NOOP("sets the application title (caption)"), 0},
01589 #ifdef Q_WS_X11
01590    { "visual TrueColor", I18N_NOOP("forces the application to use a TrueColor visual on\nan 8-bit display"), 0},
01591    { "inputstyle <inputstyle>", I18N_NOOP("sets XIM (X Input Method) input style. Possible\nvalues are onthespot, overthespot, offthespot and\nroot"), 0 },
01592    { "im <XIM server>", I18N_NOOP("set XIM server"),0},
01593    { "noxim", I18N_NOOP("disable XIM"), 0 },
01594 #endif
01595 #ifdef Q_WS_QWS
01596    { "qws", I18N_NOOP("forces the application to run as QWS Server"), 0},
01597 #endif
01598    { "reverse", I18N_NOOP("mirrors the whole layout of widgets"), 0},
01599    KCmdLineLastOption
01600 };
01601 
01602 static const KCmdLineOptions kde_options[] =
01603 {
01604    { "caption <caption>",       I18N_NOOP("Use 'caption' as name in the titlebar"), 0},
01605    { "icon <icon>",             I18N_NOOP("Use 'icon' as the application icon"), 0},
01606    { "miniicon <icon>",         I18N_NOOP("Use 'icon' as the icon in the titlebar"), 0},
01607    { "config <filename>",       I18N_NOOP("Use alternative configuration file"), 0},
01608    { "dcopserver <server>",     I18N_NOOP("Use the DCOP Server specified by 'server'"), 0},
01609    { "nocrashhandler",          I18N_NOOP("Disable crash handler, to get core dumps"), 0},
01610    { "waitforwm",          I18N_NOOP("Waits for a WM_NET compatible windowmanager"), 0},
01611    { "style <style>", I18N_NOOP("sets the application GUI style"), 0},
01612    { "geometry <geometry>", I18N_NOOP("sets the client geometry of the main widget - see man X for the argument format"), 0},
01613    { "smkey <sessionKey>", 0, 0}, // this option is obsolete and exists only to allow smooth upgrades from sessions
01614                                   // saved under Qt 3.0.x -- Qt 3.1.x includes the session key now automatically in
01615                   // the session id (Simon)
01616    KCmdLineLastOption
01617 };
01618 
01619 void
01620 KApplication::addCmdLineOptions()
01621 {
01622    KCmdLineArgs::addCmdLineOptions(qt_options, "Qt", "qt");
01623    KCmdLineArgs::addCmdLineOptions(kde_options, "KDE", "kde");
01624 }
01625 
01626 void KApplication::parseCommandLine( )
01627 {
01628     KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde");
01629 
01630     if ( !args ) return;
01631 
01632     if (args->isSet("config"))
01633     {
01634         TQString config = TQString::fromLocal8Bit(args->getOption("config"));
01635         setConfigName(config);
01636     }
01637 
01638     if (args->isSet("style"))
01639     {
01640 
01641         TQStringList plugins = KGlobal::dirs()->resourceDirs( "qtplugins" );
01642         TQStringList::Iterator itp = plugins.begin();
01643         while (itp != plugins.end()) {
01644             addLibraryPath( *itp );
01645             ++itp;
01646         }
01647 
01648        TQStringList styles = TQStyleFactory::keys();
01649        TQString reqStyle(args->getOption("style").lower());
01650 
01651     TQStringList list = libraryPaths();
01652     TQStringList::Iterator it = list.begin();
01653     while( it != list.end() ) {
01654         ++it;
01655     }
01656 
01657        for (TQStringList::ConstIterator it = styles.begin(); it != styles.end(); ++it) {
01658            if ((*it).lower() == reqStyle)
01659            {
01660                d->overrideStyle = *it;
01661                break;
01662            }
01663        }
01664 
01665        if (d->overrideStyle.isEmpty())
01666           fprintf(stderr, "%s", TQString(i18n("The style %1 was not found\n").arg(reqStyle)).local8Bit().data());
01667     }
01668 
01669     if (args->isSet("caption"))
01670     {
01671        aCaption = TQString::fromLocal8Bit(args->getOption("caption"));
01672     }
01673 
01674     if (args->isSet("miniicon"))
01675     {
01676        const char *tmp = args->getOption("miniicon");
01677        if (!aIconPixmap.pm.miniIcon) {
01678          aIconPixmap.pm.miniIcon = new TQPixmap;
01679        }
01680        *aIconPixmap.pm.miniIcon = SmallIcon(tmp);
01681        aMiniIconName = tmp;
01682     }
01683 
01684     if (args->isSet("icon"))
01685     {
01686        const char *tmp = args->getOption("icon");
01687        if (!aIconPixmap.pm.icon) {
01688           aIconPixmap.pm.icon = new TQPixmap;
01689        }
01690        *aIconPixmap.pm.icon = DesktopIcon( tmp );
01691        aIconName = tmp;
01692        if (!aIconPixmap.pm.miniIcon) {
01693          aIconPixmap.pm.miniIcon = new TQPixmap;
01694        }
01695        if (aIconPixmap.pm.miniIcon->isNull())
01696        {
01697           *aIconPixmap.pm.miniIcon = SmallIcon( tmp );
01698           aMiniIconName = tmp;
01699        }
01700     }
01701 
01702     bool nocrashhandler = (getenv("KDE_DEBUG") != NULL);
01703     if (!nocrashhandler && args->isSet("crashhandler"))
01704     {
01705         // set default crash handler / set emergency save function to nothing
01706         KCrash::setCrashHandler(KCrash::defaultCrashHandler);
01707         KCrash::setEmergencySaveFunction(NULL);
01708 
01709         KCrash::setApplicationName(TQString(args->appName()));
01710     }
01711 
01712 #ifdef Q_WS_X11
01713     if ( args->isSet( "waitforwm" ) ) {
01714         Atom type;
01715         (void) desktop(); // trigger desktop creation, we need PropertyNotify events for the root window
01716         int format;
01717         unsigned long length, after;
01718         unsigned char *data;
01719         while ( XGetWindowProperty( qt_xdisplay(), qt_xrootwin(), atom_NetSupported,
01720                     0, 1, false, AnyPropertyType, &type, &format,
01721                                     &length, &after, &data ) != Success || !length ) {
01722             if ( data )
01723                 XFree( data );
01724             XEvent event;
01725             XWindowEvent( qt_xdisplay(), qt_xrootwin(), PropertyChangeMask, &event );
01726         }
01727         if ( data )
01728             XFree( data );
01729     }
01730 #else
01731     // FIXME(E): Implement for Qt Embedded
01732 #endif
01733 
01734     if (args->isSet("geometry"))
01735     {
01736         d->geometry_arg = args->getOption("geometry");
01737     }
01738 
01739     if (args->isSet("smkey"))
01740     {
01741         d->sessionKey = args->getOption("smkey");
01742     }
01743 
01744 }
01745 
01746 TQString KApplication::geometryArgument() const
01747 {
01748     return d->geometry_arg;
01749 }
01750 
01751 TQPixmap KApplication::icon() const
01752 {
01753   if( !aIconPixmap.pm.icon) {
01754       aIconPixmap.pm.icon = new TQPixmap;
01755   }
01756   if( aIconPixmap.pm.icon->isNull()) {
01757       *aIconPixmap.pm.icon = DesktopIcon( instanceName() );
01758   }
01759   return *aIconPixmap.pm.icon;
01760 }
01761 
01762 TQString KApplication::iconName() const
01763 {
01764   return aIconName.isNull() ? (TQString)instanceName() : aIconName;
01765 }
01766 
01767 TQPixmap KApplication::miniIcon() const
01768 {
01769   if (!aIconPixmap.pm.miniIcon) {
01770       aIconPixmap.pm.miniIcon = new TQPixmap;
01771   }
01772   if (aIconPixmap.pm.miniIcon->isNull()) {
01773       *aIconPixmap.pm.miniIcon = SmallIcon( instanceName() );
01774   }
01775   return *aIconPixmap.pm.miniIcon;
01776 }
01777 
01778 TQString KApplication::miniIconName() const
01779 {
01780   return aMiniIconName.isNull() ? (TQString)instanceName() : aMiniIconName;
01781 }
01782 
01783 extern void kDebugCleanup();
01784 
01785 KApplication::~KApplication()
01786 {
01787   delete aIconPixmap.pm.miniIcon;
01788   aIconPixmap.pm.miniIcon = 0L;
01789   delete aIconPixmap.pm.icon;
01790   aIconPixmap.pm.icon = 0L;
01791   delete d->m_KAppDCOPInterface;
01792 
01793   // First call the static deleters and then call KLibLoader::cleanup()
01794   // The static deleters may delete libraries for which they need KLibLoader.
01795   // KLibLoader will take care of the remaining ones.
01796   KGlobal::deleteStaticDeleters();
01797   KLibLoader::cleanUp();
01798 
01799   delete smw;
01800 
01801   // close down IPC
01802   delete s_DCOPClient;
01803   s_DCOPClient = 0L;
01804 
01805   KProcessController::deref();
01806 
01807 #ifdef Q_WS_X11
01808   if ( d->oldXErrorHandler != NULL )
01809       XSetErrorHandler( d->oldXErrorHandler );
01810   if ( d->oldXIOErrorHandler != NULL )
01811       XSetIOErrorHandler( d->oldXIOErrorHandler );
01812   if ( d->oldIceIOErrorHandler != NULL )
01813       IceSetIOErrorHandler( d->oldIceIOErrorHandler );
01814 #endif
01815 
01816   delete d;
01817   KApp = 0;
01818 
01819 #ifdef Q_WS_X11
01820   mySmcConnection = 0;
01821   delete smModificationTime;
01822   smModificationTime = 0;
01823 
01824   // close the temporary smc connection
01825   if (tmpSmcConnection) {
01826       SmcCloseConnection( tmpSmcConnection, 0, 0 );
01827       tmpSmcConnection = 0;
01828   }
01829 #else
01830   // FIXME(E): Implement for Qt Embedded
01831 #endif
01832 }
01833 
01834 
01835 #ifdef Q_WS_X11
01836 class KAppX11HackWidget: public QWidget
01837 {
01838 public:
01839     bool publicx11Event( XEvent * e) { return x11Event( e ); }
01840 };
01841 #endif
01842 
01843 #if defined(Q_WS_X11) && defined(COMPOSITE)
01844 bool KApplication::isCompositionManagerAvailable() {
01845     bool have_manager = false;
01846     const char *home;
01847     struct passwd *p;
01848     p = getpwuid(getuid());
01849     if (p)
01850         home = p->pw_dir;
01851     else
01852         home = getenv("HOME");
01853 
01854     char *filename;
01855     const char *configfile = "/.kompmgr.available";
01856     int n = strlen(home)+strlen(configfile)+1;
01857     filename = (char*)malloc(n*sizeof(char));
01858     memset(filename,0,n);
01859     strcat(filename, home);
01860     strcat(filename, configfile);
01861 
01862         // Now that we did all that by way of introduction...read the file!
01863     FILE *pFile;
01864     pFile = fopen(filename, "r");
01865     if (pFile) {
01866         have_manager = true;
01867         fclose(pFile);
01868     }
01869 
01870     free(filename);
01871     filename = NULL;
01872 
01873     return have_manager;
01874 }
01875 
01876 bool KApplication::detectCompositionManagerAvailable(bool force_available, bool available) {
01877     bool compositing_manager_available;
01878     if (force_available) {
01879         compositing_manager_available = available;
01880     }
01881     else {
01882         // See if compositing has been enabled
01883         KCmdLineArgs *qtargs = KCmdLineArgs::parsedArgs("qt");
01884         char *displayname = 0;
01885         if ( qtargs->isSet("display"))
01886             displayname = qtargs->getOption( "display" ).data();
01887 
01888         Display *dpy = XOpenDisplay( displayname );
01889     
01890         x11_composite_error_generated = false;
01891         compositing_manager_available = false;
01892         XSetErrorHandler(x11_error);
01893         if (!XQueryExtension (dpy, COMPOSITE_NAME, &composite_opcode, &composite_event, &composite_error)) {
01894             XSetErrorHandler(NULL);
01895             compositing_manager_available = false;
01896         }
01897         else {
01898             if (available) {        // FIXME This variable does double duty to avoid breaking the ABI for R14.0.  In reality it should be called perform_deep_check
01899                 Window root_window = XDefaultRootWindow(dpy);
01900                 XCompositeRedirectSubwindows(dpy, root_window, CompositeRedirectManual);
01901                 XSync(dpy, false);
01902                 if (x11_composite_error_generated == true) {
01903                     compositing_manager_available = true;
01904                 }
01905                 else {
01906                     XCompositeUnredirectSubwindows(dpy, root_window, CompositeRedirectManual);
01907                     compositing_manager_available = false;
01908                 }
01909                 XSetErrorHandler(NULL);
01910                 XCloseDisplay(dpy);
01911             }
01912             else {
01913                 compositing_manager_available = true;
01914             }
01915         }
01916     }
01917     
01918     const char *home;
01919     struct passwd *p;
01920     p = getpwuid(getuid());
01921     if (p)
01922         home = p->pw_dir;
01923     else
01924         home = getenv("HOME");
01925 
01926     char *filename;
01927     const char *configfile = "/.kompmgr.available";
01928     int n = strlen(home)+strlen(configfile)+1;
01929     filename = (char*)malloc(n*sizeof(char));
01930     memset(filename,0,n);
01931     strcat(filename, home);
01932     strcat(filename, configfile);
01933 
01934     /* now that we did all that by way of introduction...create or remove the file! */
01935     if (compositing_manager_available) {
01936         FILE *pFile;
01937         char buffer[255];
01938         sprintf(buffer, "available");
01939         pFile = fopen(filename, "w");
01940         if (pFile) {
01941             fwrite(buffer,1,strlen(buffer), pFile);
01942             fclose(pFile);
01943         }
01944     }
01945     else {
01946         unlink(filename);
01947     }
01948 
01949     free(filename);
01950     filename = NULL;
01951 
01952     return compositing_manager_available;
01953 }
01954 
01955 Display* KApplication::openX11RGBADisplay() {
01956     KCmdLineArgs *qtargs = KCmdLineArgs::parsedArgs("qt");
01957     char *display = 0;
01958     if ( qtargs->isSet("display"))
01959         display = qtargs->getOption( "display" ).data();
01960 
01961     Display *dpy = XOpenDisplay( display );
01962     if ( !dpy ) {
01963         kdError() << "cannot connect to X server " << display << endl;
01964         exit( 1 );
01965     }
01966 
01967     return dpy;
01968 }
01969 
01970 Qt::HANDLE KApplication::getX11RGBAVisual(Display *dpy) {
01971     getX11RGBAInformation(dpy);
01972     if (KApplication::isCompositionManagerAvailable() == true) {
01973         return argb_x11_visual;
01974     }
01975     else {
01976         return (Qt::HANDLE)NULL;
01977     }
01978 }
01979 
01980 Qt::HANDLE KApplication::getX11RGBAColormap(Display *dpy) {
01981     getX11RGBAInformation(dpy);
01982     if (KApplication::isCompositionManagerAvailable() == true) {
01983         return argb_x11_colormap;
01984     }
01985     else {
01986         return (Qt::HANDLE)NULL;
01987     }
01988 }
01989 
01990 bool KApplication::isX11CompositionAvailable() {
01991     return (argb_visual & isCompositionManagerAvailable());
01992 }
01993 
01994 void KApplication::getX11RGBAInformation(Display *dpy) {
01995     if ( !dpy ) {
01996         argb_visual = false;
01997         return;
01998     }
01999 
02000     int screen = DefaultScreen( dpy );
02001     Colormap colormap = 0;
02002     Visual *visual = 0;
02003     int event_base, error_base;
02004     
02005     if ( XRenderQueryExtension( dpy, &event_base, &error_base ) ) {
02006         int nvi;
02007         XVisualInfo templ;
02008         templ.screen  = screen;
02009         templ.depth   = 32;
02010         templ.c_class = TrueColor;
02011         XVisualInfo *xvi = XGetVisualInfo( dpy, VisualScreenMask | VisualDepthMask
02012                 | VisualClassMask, &templ, &nvi );
02013         
02014         for ( int i = 0; i < nvi; i++ ) {
02015             XRenderPictFormat *format = XRenderFindVisualFormat( dpy, xvi[i].visual );
02016             if ( format->type == PictTypeDirect && format->direct.alphaMask ) {
02017                 visual = xvi[i].visual;
02018                 colormap = XCreateColormap( dpy, RootWindow( dpy, screen ), visual, AllocNone );
02019                 kdDebug() << "[kdecore-kapplication] Found visual with alpha support" << endl;
02020                 argb_visual = true;
02021                 break;
02022             }
02023         }
02024     }
02025     
02026     if( argb_visual ) {
02027         argb_x11_visual = Qt::HANDLE( visual );
02028         argb_x11_colormap = Qt::HANDLE( colormap );
02029         argb_visual = true;
02030         return;
02031     }
02032     argb_visual = false;
02033     return;
02034 }
02035 #else
02036 void KApplication::getX11RGBAInformation(Display *dpy) {
02037 }
02038 
02039 bool KApplication::isCompositionManagerAvailable() {
02040     return false;
02041 }
02042 
02043 bool KApplication::detectCompositionManagerAvailable(bool force_available, bool available) {
02044     const char *home;
02045     struct passwd *p;
02046     p = getpwuid(getuid());
02047     if (p)
02048         home = p->pw_dir;
02049     else
02050         home = getenv("HOME");
02051 
02052     char *filename;
02053     const char *configfile = "/.kompmgr.available";
02054     int n = strlen(home)+strlen(configfile)+1;
02055     filename = (char*)malloc(n*sizeof(char));
02056     memset(filename,0,n);
02057     strcat(filename, home);
02058     strcat(filename, configfile);
02059 
02060     /* now that we did all that by way of introduction...create or remove the file! */
02061     if (force_available) {
02062         FILE *pFile;
02063         char buffer[255];
02064         sprintf(buffer, "available");
02065         pFile = fopen(filename, "w");
02066         if (pFile) {
02067             fwrite(buffer,1,strlen(buffer), pFile);
02068             fclose(pFile);
02069         }
02070     }
02071     else {
02072         unlink(filename);
02073     }
02074 
02075     free(filename);
02076     filename = NULL;
02077 
02078     return false;
02079 }
02080 
02081 Display* KApplication::openX11RGBADisplay() {
02082     return 0;
02083 }
02084 
02085 Qt::HANDLE KApplication::getX11RGBAVisual(Display *dpy) {
02086     return 0;
02087 }
02088 
02089 Qt::HANDLE KApplication::getX11RGBAColormap(Display *dpy) {
02090     return 0;
02091 }
02092 
02093 bool KApplication::isX11CompositionAvailable() {
02094     return false;
02095 }
02096 #endif
02097 
02098 static bool kapp_block_user_input = false;
02099 
02100 void KApplication::dcopBlockUserInput( bool b )
02101 {
02102     kapp_block_user_input = b;
02103 }
02104 
02105 #ifdef Q_WS_X11
02106 bool KApplication::x11EventFilter( XEvent *_event )
02107 {
02108     if ( kapp_block_user_input ) {
02109         switch ( _event->type  ) {
02110         case ButtonPress:
02111         case ButtonRelease:
02112         case XKeyPress:
02113         case XKeyRelease:
02114         case MotionNotify:
02115         case EnterNotify:
02116         case LeaveNotify:
02117             return true;
02118         default:
02119             break;
02120         }
02121     }
02122 
02123     if (x11Filter) {
02124         for (TQWidget *w=x11Filter->first(); w; w=x11Filter->next()) {
02125             if (((KAppX11HackWidget*) w)->publicx11Event(_event))
02126                 return true;
02127         }
02128     }
02129 
02130     if ((_event->type == ClientMessage) &&
02131             (_event->xclient.message_type == kipcCommAtom))
02132     {
02133         XClientMessageEvent *cme = (XClientMessageEvent *) _event;
02134 
02135         int id = cme->data.l[0];
02136         int arg = cme->data.l[1];
02137         if ((id < 32) && (kipcEventMask & (1 << id)))
02138         {
02139             switch (id)
02140             {
02141             case KIPC::StyleChanged:
02142                 KGlobal::config()->reparseConfiguration();
02143                 kdisplaySetStyle();
02144                 break;
02145 
02146             case KIPC::ToolbarStyleChanged:
02147                 KGlobal::config()->reparseConfiguration();
02148                 if (useStyles)
02149                     emit toolbarAppearanceChanged(arg);
02150                 break;
02151 
02152             case KIPC::PaletteChanged:
02153                 KGlobal::config()->reparseConfiguration();
02154                 kdisplaySetPalette();
02155                 break;
02156 
02157             case KIPC::FontChanged:
02158                 KGlobal::config()->reparseConfiguration();
02159                 KGlobalSettings::rereadFontSettings();
02160                 kdisplaySetFont();
02161                 break;
02162 
02163             case KIPC::BackgroundChanged:
02164                 emit backgroundChanged(arg);
02165                 break;
02166 
02167             case KIPC::SettingsChanged:
02168                 KGlobal::config()->reparseConfiguration();
02169                 if (arg == SETTINGS_PATHS)
02170                     KGlobalSettings::rereadPathSettings();
02171                 else if (arg == SETTINGS_MOUSE)
02172                     KGlobalSettings::rereadMouseSettings();
02173                 propagateSettings((SettingsCategory)arg);
02174                 break;
02175 
02176             case KIPC::IconChanged:
02177                 TQPixmapCache::clear();
02178                 KGlobal::config()->reparseConfiguration();
02179                 KGlobal::instance()->newIconLoader();
02180                 emit updateIconLoaders();
02181                 emit iconChanged(arg);
02182                 break;
02183 
02184             case KIPC::ClipboardConfigChanged:
02185                 KClipboardSynchronizer::newConfiguration(arg);
02186                 break;
02187                 
02188             case KIPC::BlockShortcuts:
02189                 KGlobalAccel::blockShortcuts(arg);
02190                 emit kipcMessage(id, arg); // some apps may do additional things
02191                 break;
02192             }
02193         }
02194         else if (id >= 32)
02195         {
02196             emit kipcMessage(id, arg);
02197         }
02198         return true;
02199     }
02200     return false;
02201 }
02202 #endif // Q_WS_X11
02203 
02204 void KApplication::updateUserTimestamp( unsigned long time )
02205 {
02206 #if defined Q_WS_X11
02207     Display *display = qt_xdisplay();
02208     if (!display) {
02209         return;
02210     }
02211     if( time == 0 )
02212     { // get current X timestamp
02213         Window w = XCreateSimpleWindow( display, qt_xrootwin(), 0, 0, 1, 1, 0, 0, 0 );
02214         XSelectInput( qt_xdisplay(), w, PropertyChangeMask );
02215         unsigned char data[ 1 ];
02216         XChangeProperty( display, w, XA_ATOM, XA_ATOM, 8, PropModeAppend, data, 1 );
02217         XEvent ev;
02218         XWindowEvent( display, w, PropertyChangeMask, &ev );
02219         time = ev.xproperty.time;
02220         XDestroyWindow( display, w );
02221     }
02222     if( GET_QT_X_USER_TIME() == 0
02223         || NET::timestampCompare( time, GET_QT_X_USER_TIME() ) > 0 ) // check time > qt_x_user_time
02224         SET_QT_X_USER_TIME(time);
02225 #endif
02226 }
02227 
02228 unsigned long KApplication::userTimestamp() const
02229 {
02230 #if defined Q_WS_X11
02231     return GET_QT_X_USER_TIME();
02232 #else
02233     return 0;
02234 #endif
02235 }
02236 
02237 void KApplication::updateRemoteUserTimestamp( const TQCString& dcopId, unsigned long time )
02238 {
02239 #if defined Q_WS_X11
02240     if( time == 0 )
02241         time = GET_QT_X_USER_TIME();
02242     DCOPRef( dcopId, "MainApplication-Interface" ).call( "updateUserTimestamp", time );
02243 #endif
02244 }
02245 
02246 void KApplication::invokeEditSlot( const char *slot )
02247 {
02248   TQObject *object = TQT_TQOBJECT(focusWidget());
02249   if( !object )
02250     return;
02251 
02252   TQMetaObject *meta = object->metaObject();
02253 
02254   int idx = meta->findSlot( slot + 1, true );
02255   if( idx < 0 )
02256     return;
02257 
02258   object->qt_invoke( idx, 0 );
02259 }
02260 
02261 void KApplication::addKipcEventMask(int id)
02262 {
02263     if (id >= 32)
02264     {
02265         kdDebug(101) << "[kdecore-kapplication] Cannot use KIPC event mask for message IDs >= 32\n";
02266         return;
02267     }
02268     kipcEventMask |= (1 << id);
02269 }
02270 
02271 void KApplication::removeKipcEventMask(int id)
02272 {
02273     if (id >= 32)
02274     {
02275         kdDebug(101) << "[kdecore-kapplication] Cannot use KIPC event mask for message IDs >= 32\n";
02276         return;
02277     }
02278     kipcEventMask &= ~(1 << id);
02279 }
02280 
02281 void KApplication::enableStyles()
02282 {
02283     if (!useStyles)
02284     {
02285         useStyles = true;
02286         applyGUIStyle();
02287     }
02288 }
02289 
02290 void KApplication::disableStyles()
02291 {
02292     useStyles = false;
02293 }
02294 
02295 void KApplication::applyGUIStyle()
02296 {
02297     if ( !useStyles ) return;
02298 
02299     KConfigGroup pConfig (KGlobal::config(), "General");
02300     TQString defaultStyle = KStyle::defaultStyle();
02301     TQString styleStr = pConfig.readEntry("widgetStyle", defaultStyle);
02302 
02303     if (d->overrideStyle.isEmpty()) {
02304       // ### add check whether we already use the correct style to return then
02305       // (workaround for Qt misbehavior to avoid double style initialization)
02306 
02307       TQStyle* sp = TQStyleFactory::create( styleStr );
02308 
02309       // If there is no default style available, try falling back any available style
02310       if ( !sp && styleStr != defaultStyle)
02311           sp = TQStyleFactory::create( defaultStyle );
02312       if ( !sp )
02313           sp = TQStyleFactory::create( *(TQStyleFactory::keys().begin()) );
02314       setStyle(sp);
02315     }
02316     else
02317         setStyle(d->overrideStyle);
02318     // Reread palette from config file.
02319     kdisplaySetPalette();
02320 }
02321 
02322 TQString KApplication::caption() const
02323 {
02324   // Caption set from command line ?
02325   if( !aCaption.isNull() )
02326         return aCaption;
02327   else
02328       // We have some about data ?
02329       if ( KGlobal::instance()->aboutData() )
02330         return KGlobal::instance()->aboutData()->programName();
02331       else
02332         // Last resort : application name
02333         return name();
02334 }
02335 
02336 
02337 //
02338 // 1999-09-20: Espen Sand
02339 // An attempt to simplify consistent captions.
02340 //
02341 TQString KApplication::makeStdCaption( const TQString &userCaption,
02342                                       bool withAppName, bool modified ) const
02343 {
02344   TQString s = userCaption.isEmpty() ? caption() : userCaption;
02345 
02346   // If the document is modified, add '[modified]'.
02347   if (modified)
02348       s += TQString::fromUtf8(" [") + i18n("modified") + TQString::fromUtf8("]");
02349 
02350   if ( !userCaption.isEmpty() ) {
02351       // Add the application name if:
02352       // User asked for it, it's not a duplication  and the app name (caption()) is not empty
02353       if ( withAppName && !caption().isNull() && !userCaption.endsWith(caption())  )
02354       s += TQString::fromUtf8(" - ") + caption();
02355   }
02356 
02357   return s;
02358 }
02359 
02360 TQPalette KApplication::createApplicationPalette()
02361 {
02362     KConfig *config = KGlobal::config();
02363     KConfigGroupSaver saver( config, "General" );
02364     return createApplicationPalette( config, KGlobalSettings::contrast() );
02365 }
02366 
02367 TQPalette KApplication::createApplicationPalette( KConfig *config, int contrast_ )
02368 {
02369     TQColor trinity4Background( 239, 239, 239 );
02370     TQColor trinity4Blue( 103,141,178 );
02371 
02372     TQColor trinity4Button;
02373     if ( TQPixmap::defaultDepth() > 8 )
02374       trinity4Button.setRgb( 221, 223, 228 );
02375     else
02376       trinity4Button.setRgb( 220, 220, 220 );
02377 
02378     TQColor trinity4Link( 0, 0, 238 );
02379     TQColor trinity4VisitedLink( 82, 24, 139 );
02380 
02381     TQColor background = config->readColorEntry( "background", &trinity4Background );
02382     TQColor foreground = config->readColorEntry( "foreground", tqblackptr );
02383     TQColor button = config->readColorEntry( "buttonBackground", &trinity4Button );
02384     TQColor buttonText = config->readColorEntry( "buttonForeground", tqblackptr );
02385     TQColor highlight = config->readColorEntry( "selectBackground", &trinity4Blue );
02386     TQColor highlightedText = config->readColorEntry( "selectForeground", tqwhiteptr );
02387     TQColor base = config->readColorEntry( "windowBackground", tqwhiteptr );
02388     TQColor baseText = config->readColorEntry( "windowForeground", tqblackptr );
02389     TQColor link = config->readColorEntry( "linkColor", &trinity4Link );
02390     TQColor visitedLink = config->readColorEntry( "visitedLinkColor", &trinity4VisitedLink );
02391 
02392     int highlightVal, lowlightVal;
02393     highlightVal = 100 + (2*contrast_+4)*16/10;
02394     lowlightVal = 100 + (2*contrast_+4)*10;
02395 
02396     TQColor disfg = foreground;
02397 
02398     int h, s, v;
02399     disfg.hsv( &h, &s, &v );
02400     if (v > 128)
02401     // dark bg, light fg - need a darker disabled fg
02402     disfg = disfg.dark(lowlightVal);
02403     else if (disfg != Qt::black)
02404     // light bg, dark fg - need a lighter disabled fg - but only if !black
02405     disfg = disfg.light(highlightVal);
02406     else
02407     // black fg - use darkgray disabled fg
02408     disfg = Qt::darkGray;
02409 
02410 
02411     TQColorGroup disabledgrp(disfg, background,
02412                             background.light(highlightVal),
02413                             background.dark(lowlightVal),
02414                             background.dark(120),
02415                             background.dark(120), base);
02416 
02417     TQColorGroup colgrp(foreground, background, background.light(highlightVal),
02418                        background.dark(lowlightVal),
02419                        background.dark(120),
02420                        baseText, base);
02421 
02422     int inlowlightVal = lowlightVal-25;
02423     if(inlowlightVal < 120)
02424         inlowlightVal = 120;
02425 
02426     colgrp.setColor(TQColorGroup::Highlight, highlight);
02427     colgrp.setColor(TQColorGroup::HighlightedText, highlightedText);
02428     colgrp.setColor(TQColorGroup::Button, button);
02429     colgrp.setColor(TQColorGroup::ButtonText, buttonText);
02430     colgrp.setColor(TQColorGroup::Midlight, background.light(110));
02431     colgrp.setColor(TQColorGroup::Link, link);
02432     colgrp.setColor(TQColorGroup::LinkVisited, visitedLink);
02433 
02434     disabledgrp.setColor(TQColorGroup::Button, button);
02435 
02436     TQColor disbtntext = buttonText;
02437     disbtntext.hsv( &h, &s, &v );
02438     if (v > 128)
02439     // dark button, light buttonText - need a darker disabled buttonText
02440     disbtntext = disbtntext.dark(lowlightVal);
02441     else if (disbtntext != Qt::black)
02442     // light buttonText, dark button - need a lighter disabled buttonText - but only if !black
02443     disbtntext = disbtntext.light(highlightVal);
02444     else
02445     // black button - use darkgray disabled buttonText
02446     disbtntext = Qt::darkGray;
02447 
02448     disabledgrp.setColor(TQColorGroup::ButtonText, disbtntext);
02449     disabledgrp.setColor(TQColorGroup::Midlight, background.light(110));
02450     disabledgrp.setColor(TQColorGroup::Highlight, highlight.dark(120));
02451     disabledgrp.setColor(TQColorGroup::Link, link);
02452     disabledgrp.setColor(TQColorGroup::LinkVisited, visitedLink);
02453 
02454     return TQPalette(colgrp, disabledgrp, colgrp);
02455 }
02456 
02457 
02458 void KApplication::kdisplaySetPalette()
02459 {
02460 #ifdef Q_WS_MACX
02461     //Can I have this on other platforms, please!? --Sam
02462     {
02463         KConfig *config = KGlobal::config();
02464         KConfigGroupSaver saver( config, "General" );
02465         bool do_not_set_palette = FALSE;
02466         if(config->readBoolEntry("nopaletteChange", &do_not_set_palette))
02467             return;
02468     }
02469 #endif
02470     TQApplication::setPalette( createApplicationPalette(), true);
02471     emit kdisplayPaletteChanged();
02472     emit appearanceChanged();
02473 }
02474 
02475 
02476 void KApplication::kdisplaySetFont()
02477 {
02478     TQApplication::setFont(KGlobalSettings::generalFont(), true);
02479     TQApplication::setFont(KGlobalSettings::menuFont(), true, TQMENUBAR_OBJECT_NAME_STRING);
02480     TQApplication::setFont(KGlobalSettings::menuFont(), true, TQPOPUPMENU_OBJECT_NAME_STRING);
02481     TQApplication::setFont(KGlobalSettings::menuFont(), true, "KPopupTitle");
02482 
02483     // "patch" standard TQStyleSheet to follow our fonts
02484     TQStyleSheet* sheet = TQStyleSheet::defaultSheet();
02485     sheet->item ("pre")->setFontFamily (KGlobalSettings::fixedFont().family());
02486     sheet->item ("code")->setFontFamily (KGlobalSettings::fixedFont().family());
02487     sheet->item ("tt")->setFontFamily (KGlobalSettings::fixedFont().family());
02488 
02489     emit kdisplayFontChanged();
02490     emit appearanceChanged();
02491 }
02492 
02493 
02494 void KApplication::kdisplaySetStyle()
02495 {
02496     if (useStyles)
02497     {
02498         applyGUIStyle();
02499         emit kdisplayStyleChanged();
02500         emit appearanceChanged();
02501     }
02502 }
02503 
02504 
02505 void KApplication::propagateSettings(SettingsCategory arg)
02506 {
02507     KConfigBase* config = KGlobal::config();
02508     KConfigGroupSaver saver( config, "KDE" );
02509 
02510 #ifdef QT_HAVE_MAX_IMAGE_SIZE
02511     TQSize maxImageSize(4096, 4096);
02512     maxImageSize = config->readSizeEntry("MaxImageSize", &maxImageSize);
02513     TQImage::setMaxImageSize(maxImageSize);
02514 #endif
02515 
02516     int num = config->readNumEntry("CursorBlinkRate", TQApplication::cursorFlashTime());
02517     if ((num != 0) && (num < 200))
02518         num = 200;
02519     if (num > 2000)
02520         num = 2000;
02521     TQApplication::setCursorFlashTime(num);
02522     num = config->readNumEntry("DoubleClickInterval", TQApplication::doubleClickInterval());
02523     TQApplication::setDoubleClickInterval(num);
02524     num = config->readNumEntry("StartDragTime", TQApplication::startDragTime());
02525     TQApplication::setStartDragTime(num);
02526     num = config->readNumEntry("StartDragDist", TQApplication::startDragDistance());
02527     TQApplication::setStartDragDistance(num);
02528     num = config->readNumEntry("WheelScrollLines", TQApplication::wheelScrollLines());
02529     TQApplication::setWheelScrollLines(num);
02530 
02531     bool b = config->readBoolEntry("EffectAnimateMenu", false);
02532     TQApplication::setEffectEnabled( Qt::UI_AnimateMenu, b);
02533     b = config->readBoolEntry("EffectFadeMenu", false);
02534     TQApplication::setEffectEnabled( Qt::UI_FadeMenu, b);
02535     b = config->readBoolEntry("EffectAnimateCombo", false);
02536     TQApplication::setEffectEnabled( Qt::UI_AnimateCombo, b);
02537     b = config->readBoolEntry("EffectAnimateTooltip", false);
02538     TQApplication::setEffectEnabled( Qt::UI_AnimateTooltip, b);
02539     b = config->readBoolEntry("EffectFadeTooltip", false);
02540     TQApplication::setEffectEnabled( Qt::UI_FadeTooltip, b);
02541     b = !config->readBoolEntry("EffectNoTooltip", false);
02542     TQToolTip::setGloballyEnabled( b );
02543 
02544     emit settingsChanged(arg);
02545 }
02546 
02547 void KApplication::installKDEPropertyMap()
02548 {
02549 #ifndef QT_NO_SQL
02550     static bool installed = false;
02551     if (installed) return;
02552     installed = true;
02559     // TQSqlPropertyMap takes ownership of the new default map.
02560     TQSqlPropertyMap *kdeMap = new TQSqlPropertyMap;
02561     kdeMap->insert( "KColorButton", "color" );
02562     kdeMap->insert( "KComboBox", "currentItem" );
02563     kdeMap->insert( "KDatePicker", "date" );
02564     kdeMap->insert( "KDateWidget", "date" );
02565     kdeMap->insert( "KDateTimeWidget", "dateTime" );
02566     kdeMap->insert( "KEditListBox", "items" );
02567     kdeMap->insert( "KFontCombo", "family" );
02568     kdeMap->insert( "KFontRequester", "font" );
02569     kdeMap->insert( "KFontChooser", "font" );
02570     kdeMap->insert( "KHistoryCombo", "currentItem" );
02571     kdeMap->insert( "KListBox", "currentItem" );
02572     kdeMap->insert( "KLineEdit", "text" );
02573     kdeMap->insert( "KRestrictedLine", "text" );
02574     kdeMap->insert( "KSqueezedTextLabel", "text" );
02575     kdeMap->insert( "KTextBrowser", "source" );
02576     kdeMap->insert( "KTextEdit", "text" );
02577     kdeMap->insert( "KURLRequester", "url" );
02578     kdeMap->insert( "KPasswordEdit", "password" );
02579     kdeMap->insert( "KIntNumInput", "value" );
02580     kdeMap->insert( "KIntSpinBox", "value" );
02581     kdeMap->insert( "KDoubleNumInput", "value" );
02582     // Temp til fixed in QT then enable ifdef with the correct version num
02583     kdeMap->insert( TQGROUPBOX_OBJECT_NAME_STRING, "checked" );
02584     kdeMap->insert( TQTABWIDGET_OBJECT_NAME_STRING, "currentPage" );
02585     TQSqlPropertyMap::installDefaultMap( kdeMap );
02586 #endif
02587 }
02588 
02589 void KApplication::invokeHelp( const TQString& anchor,
02590                                const TQString& _appname) const
02591 {
02592     return invokeHelp( anchor, _appname, "" );
02593 }
02594 
02595 #ifndef Q_WS_WIN
02596 // for win32 we're using simple help tools like Qt Assistant,
02597 // see kapplication_win.cpp
02598 void KApplication::invokeHelp( const TQString& anchor,
02599                                const TQString& _appname,
02600                                const TQCString& startup_id ) const
02601 {
02602    TQString url;
02603    TQString appname;
02604    if (_appname.isEmpty())
02605      appname = name();
02606    else
02607      appname = _appname;
02608 
02609    if (!anchor.isEmpty())
02610      url = TQString("help:/%1?anchor=%2").arg(appname).arg(anchor);
02611    else
02612      url = TQString("help:/%1/index.html").arg(appname);
02613 
02614    TQString error;
02615    if ( !dcopClient()->isApplicationRegistered("khelpcenter") )
02616    {
02617        if (startServiceByDesktopName("khelpcenter", url, &error, 0, 0, startup_id, false))
02618        {
02619            if (Tty != kapp->type())
02620                TQMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Help Center"),
02621                i18n("Could not launch the KDE Help Center:\n\n%1").arg(error), i18n("&OK"));
02622            else
02623                kdWarning() << "Could not launch help:\n" << error << endl;
02624        return;
02625        }
02626    }
02627    else
02628        DCOPRef( "khelpcenter", "KHelpCenterIface" ).send( "openUrl", url, startup_id );
02629 }
02630 #endif
02631 
02632 void KApplication::invokeHTMLHelp( const TQString& _filename, const TQString& topic ) const
02633 {
02634    kdWarning() << "invoking HTML help is deprecated! use docbook and invokeHelp!\n";
02635 
02636    TQString filename;
02637 
02638    if( _filename.isEmpty() )
02639      filename = TQString(name()) + "/index.html";
02640    else
02641      filename = _filename;
02642 
02643    TQString url;
02644    if (!topic.isEmpty())
02645      url = TQString("help:/%1#%2").arg(filename).arg(topic);
02646    else
02647      url = TQString("help:/%1").arg(filename);
02648 
02649    TQString error;
02650    if ( !dcopClient()->isApplicationRegistered("khelpcenter") )
02651    {
02652        if (startServiceByDesktopName("khelpcenter", url, &error, 0, 0, "", false))
02653        {
02654            if (Tty != kapp->type())
02655                TQMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Help Center"),
02656                i18n("Could not launch the KDE Help Center:\n\n%1").arg(error), i18n("&OK"));
02657            else
02658                kdWarning() << "Could not launch help:\n" << error << endl;
02659            return;
02660        }
02661    }
02662    else
02663        DCOPRef( "khelpcenter", "KHelpCenterIface" ).send( "openUrl", url );
02664 }
02665 
02666 
02667 void KApplication::invokeMailer(const TQString &address, const TQString &subject)
02668 {
02669     return invokeMailer(address,subject,"");
02670 }
02671 
02672 void KApplication::invokeMailer(const TQString &address, const TQString &subject, const TQCString& startup_id)
02673 {
02674    invokeMailer(address, TQString::null, TQString::null, subject, TQString::null, TQString::null,
02675        TQStringList(), startup_id );
02676 }
02677 
02678 void KApplication::invokeMailer(const KURL &mailtoURL)
02679 {
02680     return invokeMailer( mailtoURL, "" );
02681 }
02682 
02683 void KApplication::invokeMailer(const KURL &mailtoURL, const TQCString& startup_id )
02684 {
02685     return invokeMailer( mailtoURL, startup_id, false);
02686 }
02687 
02688 void KApplication::invokeMailer(const KURL &mailtoURL, const TQCString& startup_id, bool allowAttachments )
02689 {
02690    TQString address = KURL::decode_string(mailtoURL.path()), subject, cc, bcc, body;
02691    TQStringList queries = TQStringList::split('&', mailtoURL.query().mid(1));
02692    TQStringList attachURLs;
02693    for (TQStringList::Iterator it = queries.begin(); it != queries.end(); ++it)
02694    {
02695      TQString q = (*it).lower();
02696      if (q.startsWith("subject="))
02697        subject = KURL::decode_string((*it).mid(8));
02698      else
02699      if (q.startsWith("cc="))
02700        cc = cc.isEmpty()? KURL::decode_string((*it).mid(3)): cc + ',' + KURL::decode_string((*it).mid(3));
02701      else
02702      if (q.startsWith("bcc="))
02703        bcc = bcc.isEmpty()? KURL::decode_string((*it).mid(4)): bcc + ',' + KURL::decode_string((*it).mid(4));
02704      else
02705      if (q.startsWith("body="))
02706        body = KURL::decode_string((*it).mid(5));
02707      else
02708      if (allowAttachments && q.startsWith("attach="))
02709        attachURLs.push_back(KURL::decode_string((*it).mid(7)));
02710      else
02711      if (allowAttachments && q.startsWith("attachment="))
02712        attachURLs.push_back(KURL::decode_string((*it).mid(11)));
02713      else
02714      if (q.startsWith("to="))
02715        address = address.isEmpty()? KURL::decode_string((*it).mid(3)): address + ',' + KURL::decode_string((*it).mid(3));
02716    }
02717 
02718    invokeMailer( address, cc, bcc, subject, body, TQString::null, attachURLs, startup_id );
02719 }
02720 
02721 void KApplication::invokeMailer(const TQString &to, const TQString &cc, const TQString &bcc,
02722                                 const TQString &subject, const TQString &body,
02723                                 const TQString & messageFile, const TQStringList &attachURLs)
02724 {
02725     return invokeMailer(to,cc,bcc,subject,body,messageFile,attachURLs,"");
02726 }
02727 
02728 #ifndef Q_WS_WIN
02729 // on win32, for invoking browser we're using win32 API
02730 // see kapplication_win.cpp
02731 
02732 static TQStringList splitEmailAddressList( const TQString & aStr )
02733 {
02734   // This is a copy of KPIM::splitEmailAddrList().
02735   // Features:
02736   // - always ignores quoted characters
02737   // - ignores everything (including parentheses and commas)
02738   //   inside quoted strings
02739   // - supports nested comments
02740   // - ignores everything (including double quotes and commas)
02741   //   inside comments
02742 
02743   TQStringList list;
02744 
02745   if (aStr.isEmpty())
02746     return list;
02747 
02748   TQString addr;
02749   uint addrstart = 0;
02750   int commentlevel = 0;
02751   bool insidequote = false;
02752 
02753   for (uint index=0; index<aStr.length(); index++) {
02754     // the following conversion to latin1 is o.k. because
02755     // we can safely ignore all non-latin1 characters
02756     switch (aStr[index].latin1()) {
02757     case '"' : // start or end of quoted string
02758       if (commentlevel == 0)
02759         insidequote = !insidequote;
02760       break;
02761     case '(' : // start of comment
02762       if (!insidequote)
02763         commentlevel++;
02764       break;
02765     case ')' : // end of comment
02766       if (!insidequote) {
02767         if (commentlevel > 0)
02768           commentlevel--;
02769         else {
02770           //kdDebug() << "[kdecore-kapplication] Error in address splitting: Unmatched ')'"
02771           //          << endl;
02772           return list;
02773         }
02774       }
02775       break;
02776     case '\\' : // quoted character
02777       index++; // ignore the quoted character
02778       break;
02779     case ',' :
02780       if (!insidequote && (commentlevel == 0)) {
02781         addr = aStr.mid(addrstart, index-addrstart);
02782         if (!addr.isEmpty())
02783           list += addr.simplifyWhiteSpace();
02784         addrstart = index+1;
02785       }
02786       break;
02787     }
02788   }
02789   // append the last address to the list
02790   if (!insidequote && (commentlevel == 0)) {
02791     addr = aStr.mid(addrstart, aStr.length()-addrstart);
02792     if (!addr.isEmpty())
02793       list += addr.simplifyWhiteSpace();
02794   }
02795   //else
02796   //  kdDebug() << "[kdecore-kapplication] Error in address splitting: "
02797   //            << "Unexpected end of address list"
02798   //            << endl;
02799 
02800   return list;
02801 }
02802 
02803 void KApplication::invokeMailer(const TQString &_to, const TQString &_cc, const TQString &_bcc,
02804                                 const TQString &subject, const TQString &body,
02805                                 const TQString & /*messageFile TODO*/, const TQStringList &attachURLs,
02806                                 const TQCString& startup_id )
02807 {
02808    KConfig config("emaildefaults");
02809 
02810    config.setGroup("Defaults");
02811    TQString group = config.readEntry("Profile","Default");
02812 
02813    config.setGroup( TQString("PROFILE_%1").arg(group) );
02814    TQString command = config.readPathEntry("EmailClient");
02815 
02816    TQString to, cc, bcc;
02817    if (command.isEmpty() || command == TQString::fromLatin1("kmail")
02818        || command.endsWith("/kmail"))
02819    {
02820      command = TQString::fromLatin1("kmail --composer -s %s -c %c -b %b --body %B --attach %A -- %t");
02821      if ( !_to.isEmpty() )
02822      {
02823        // put the whole address lists into RFC2047 encoded blobs; technically
02824        // this isn't correct, but KMail understands it nonetheless
02825        to = TQString( "=?utf8?b?%1?=" )
02826             .arg( QString(KCodecs::base64Encode( _to.utf8(), false )) );
02827      }
02828      if ( !_cc.isEmpty() )
02829        cc = TQString( "=?utf8?b?%1?=" )
02830             .arg( QString(KCodecs::base64Encode( _cc.utf8(), false )) );
02831      if ( !_bcc.isEmpty() )
02832        bcc = TQString( "=?utf8?b?%1?=" )
02833              .arg( QString(KCodecs::base64Encode( _bcc.utf8(), false )) );
02834    } else {
02835      to = _to;
02836      cc = _cc;
02837      bcc = _bcc;
02838      if( !command.contains( '%' ))
02839          command += " %u";
02840    }
02841 
02842    if (config.readBoolEntry("TerminalClient", false))
02843    {
02844      KConfigGroup confGroup( KGlobal::config(), "General" );
02845      TQString preferredTerminal = confGroup.readPathEntry("TerminalApplication", "konsole");
02846      command = preferredTerminal + " -e " + command;
02847    }
02848 
02849    TQStringList cmdTokens = KShell::splitArgs(command);
02850    TQString cmd = cmdTokens[0];
02851    cmdTokens.remove(cmdTokens.begin());
02852 
02853    KURL url;
02854    TQStringList qry;
02855    if (!to.isEmpty())
02856    {
02857      TQStringList tos = splitEmailAddressList( to );
02858      url.setPath( tos.first() );
02859      tos.remove( tos.begin() );
02860      for (TQStringList::ConstIterator it = tos.begin(); it != tos.end(); ++it)
02861        qry.append( "to=" + KURL::encode_string( *it ) );
02862    }
02863    const TQStringList ccs = splitEmailAddressList( cc );
02864    for (TQStringList::ConstIterator it = ccs.begin(); it != ccs.end(); ++it)
02865       qry.append( "cc=" + KURL::encode_string( *it ) );
02866    const TQStringList bccs = splitEmailAddressList( bcc );
02867    for (TQStringList::ConstIterator it = bccs.begin(); it != bccs.end(); ++it)
02868       qry.append( "bcc=" + KURL::encode_string( *it ) );
02869    for (TQStringList::ConstIterator it = attachURLs.begin(); it != attachURLs.end(); ++it)
02870       qry.append( "attach=" + KURL::encode_string( *it ) );
02871    if (!subject.isEmpty())
02872       qry.append( "subject=" + KURL::encode_string( subject ) );
02873    if (!body.isEmpty())
02874       qry.append( "body=" + KURL::encode_string( body ) );
02875    url.setQuery( qry.join( "&" ) );
02876    if ( ! (to.isEmpty() && qry.isEmpty()) )
02877       url.setProtocol("mailto");
02878 
02879    TQMap<TQChar, TQString> keyMap;
02880    keyMap.insert('t', to);
02881    keyMap.insert('s', subject);
02882    keyMap.insert('c', cc);
02883    keyMap.insert('b', bcc);
02884    keyMap.insert('B', body);
02885    keyMap.insert('u', url.url());
02886 
02887    TQString attachlist = attachURLs.join(",");
02888    attachlist.prepend('\'');
02889    attachlist.append('\'');
02890    keyMap.insert('A', attachlist);
02891 
02892    for (TQStringList::Iterator it = cmdTokens.begin(); it != cmdTokens.end(); )
02893    {
02894      if (*it == "%A")
02895      {
02896          if (it == cmdTokens.begin()) // better safe than sorry ...
02897              continue;
02898          TQStringList::ConstIterator urlit = attachURLs.begin();
02899          TQStringList::ConstIterator urlend = attachURLs.end();
02900          if ( urlit != urlend )
02901          {
02902              TQStringList::Iterator previt = it;
02903              --previt;
02904              *it = *urlit;
02905              ++it;
02906              while ( ++urlit != urlend )
02907              {
02908                  cmdTokens.insert( it, *previt );
02909                  cmdTokens.insert( it, *urlit );
02910              }
02911          } else {
02912              --it;
02913              it = cmdTokens.remove( cmdTokens.remove( it ) );
02914          }
02915      } else {
02916          *it = KMacroExpander::expandMacros(*it, keyMap);
02917          ++it;
02918      }
02919    }
02920 
02921    TQString error;
02922    // TODO this should check if cmd has a .desktop file, and use data from it, together
02923    // with sending more ASN data
02924    if (kdeinitExec(cmd, cmdTokens, &error, NULL, startup_id )) {
02925      if (Tty != kapp->type()) {
02926        TQMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Mail Client"),
02927              i18n("Could not launch the mail client:\n\n%1").arg(error), i18n("&OK"));
02928        }
02929      else {
02930        kdWarning() << "Could not launch mail client:\n" << error << endl;
02931      }
02932    }
02933 }
02934 #endif
02935 
02936 void KApplication::invokeBrowser( const TQString &url )
02937 {
02938     return invokeBrowser( url, "" );
02939 }
02940 
02941 #ifndef Q_WS_WIN
02942 // on win32, for invoking browser we're using win32 API
02943 // see kapplication_win.cpp
02944 void KApplication::invokeBrowser( const TQString &url, const TQCString& startup_id )
02945 {
02946    TQString error;
02947 
02948    if (startServiceByDesktopName("kfmclient", url, &error, 0, 0, startup_id, false))
02949    {
02950       if (Tty != kapp->type())
02951           TQMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Browser"),
02952                i18n("Could not launch the browser:\n\n%1").arg(error), i18n("&OK"));
02953       else
02954           kdWarning() << "Could not launch browser:\n" << error << endl;
02955       return;
02956    }
02957 }
02958 #endif
02959 
02960 void KApplication::cut()
02961 {
02962   invokeEditSlot( TQT_SLOT( cut() ) );
02963 }
02964 
02965 void KApplication::copy()
02966 {
02967   invokeEditSlot( TQT_SLOT( copy() ) );
02968 }
02969 
02970 void KApplication::paste()
02971 {
02972   invokeEditSlot( TQT_SLOT( paste() ) );
02973 }
02974 
02975 void KApplication::clear()
02976 {
02977   invokeEditSlot( TQT_SLOT( clear() ) );
02978 }
02979 
02980 void KApplication::selectAll()
02981 {
02982   invokeEditSlot( TQT_SLOT( selectAll() ) );
02983 }
02984 
02985 void KApplication::broadcastKeyCode(unsigned int keyCode)
02986 {
02987   emit coreFakeKeyPress(keyCode);
02988 }
02989 
02990 TQCString
02991 KApplication::launcher()
02992 {
02993    return "klauncher";
02994 }
02995 
02996 static int
02997 startServiceInternal( const TQCString &function,
02998               const TQString& _name, const TQStringList &URLs,
02999               TQString *error, TQCString *dcopService, int *pid, const TQCString& startup_id, bool noWait )
03000 {
03001    struct serviceResult
03002    {
03003       int result;
03004       TQCString dcopName;
03005       TQString error;
03006       pid_t pid;
03007    };
03008 
03009    // Register app as able to send DCOP messages
03010    DCOPClient *dcopClient;
03011    if (kapp)
03012       dcopClient = kapp->dcopClient();
03013    else
03014       dcopClient = new DCOPClient;
03015 
03016    if (!dcopClient->isAttached())
03017    {
03018       if (!dcopClient->attach())
03019       {
03020          if (error)
03021             *error = i18n("Could not register with DCOP.\n");
03022          if (!kapp)
03023             delete dcopClient;
03024 
03025          return -1;
03026       }
03027    }
03028    TQByteArray params;
03029    TQDataStream stream(params, IO_WriteOnly);
03030    stream << _name << URLs;
03031    TQCString replyType;
03032    TQByteArray replyData;
03033    TQCString _launcher = KApplication::launcher();
03034    TQValueList<TQCString> envs;
03035 #ifdef Q_WS_X11
03036    if (qt_xdisplay()) {
03037        TQCString dpystring(XDisplayString(qt_xdisplay()));
03038        envs.append( TQCString("DISPLAY=") + dpystring );
03039    } else if( getenv( "DISPLAY" )) {
03040        TQCString dpystring( getenv( "DISPLAY" ));
03041        envs.append( TQCString("DISPLAY=") + dpystring );
03042    }
03043 #endif
03044    stream << envs;
03045 #if defined Q_WS_X11
03046    // make sure there is id, so that user timestamp exists
03047    stream << ( startup_id.isEmpty() ? KStartupInfo::createNewStartupId() : startup_id );
03048 #endif
03049    if( function.left( 12 ) != "kdeinit_exec" )
03050        stream << noWait;
03051 
03052    if (!dcopClient->call(_launcher, _launcher,
03053         function, params, replyType, replyData))
03054    {
03055         if (error)
03056            *error = i18n("KLauncher could not be reached via DCOP.\n");
03057         if (!kapp)
03058            delete dcopClient;
03059         return -1;
03060    }
03061    if (!kapp)
03062       delete dcopClient;
03063 
03064    if (noWait)
03065       return 0;
03066 
03067    TQDataStream stream2(replyData, IO_ReadOnly);
03068    serviceResult result;
03069    stream2 >> result.result >> result.dcopName >> result.error >> result.pid;
03070    if (dcopService)
03071       *dcopService = result.dcopName;
03072    if (error)
03073       *error = result.error;
03074    if (pid)
03075       *pid = result.pid;
03076    return result.result;
03077 }
03078 
03079 int
03080 KApplication::startServiceByName( const TQString& _name, const TQString &URL,
03081                   TQString *error, TQCString *dcopService, int *pid, const TQCString& startup_id, bool noWait )
03082 {
03083    TQStringList URLs;
03084    if (!URL.isEmpty())
03085       URLs.append(URL);
03086    return startServiceInternal(
03087                       "start_service_by_name(TQString,TQStringList,TQValueList<TQCString>,TQCString,bool)",
03088                       _name, URLs, error, dcopService, pid, startup_id, noWait);
03089 }
03090 
03091 int
03092 KApplication::startServiceByName( const TQString& _name, const TQStringList &URLs,
03093                   TQString *error, TQCString *dcopService, int *pid, const TQCString& startup_id, bool noWait )
03094 {
03095    return startServiceInternal(
03096                       "start_service_by_name(TQString,TQStringList,TQValueList<TQCString>,TQCString,bool)",
03097                       _name, URLs, error, dcopService, pid, startup_id, noWait);
03098 }
03099 
03100 int
03101 KApplication::startServiceByDesktopPath( const TQString& _name, const TQString &URL,
03102                   TQString *error, TQCString *dcopService, int *pid, const TQCString& startup_id, bool noWait )
03103 {
03104    TQStringList URLs;
03105    if (!URL.isEmpty())
03106       URLs.append(URL);
03107    return startServiceInternal(
03108                       "start_service_by_desktop_path(TQString,TQStringList,TQValueList<TQCString>,TQCString,bool)",
03109                       _name, URLs, error, dcopService, pid, startup_id, noWait);
03110 }
03111 
03112 int
03113 KApplication::startServiceByDesktopPath( const TQString& _name, const TQStringList &URLs,
03114                   TQString *error, TQCString *dcopService, int *pid, const TQCString& startup_id, bool noWait )
03115 {
03116    return startServiceInternal(
03117                       "start_service_by_desktop_path(TQString,TQStringList,TQValueList<TQCString>,TQCString,bool)",
03118                       _name, URLs, error, dcopService, pid, startup_id, noWait);
03119 }
03120 
03121 int
03122 KApplication::startServiceByDesktopName( const TQString& _name, const TQString &URL,
03123                   TQString *error, TQCString *dcopService, int *pid, const TQCString& startup_id, bool noWait )
03124 {
03125    TQStringList URLs;
03126    if (!URL.isEmpty())
03127       URLs.append(URL);
03128    return startServiceInternal(
03129                       "start_service_by_desktop_name(TQString,TQStringList,TQValueList<TQCString>,TQCString,bool)",
03130                       _name, URLs, error, dcopService, pid, startup_id, noWait);
03131 }
03132 
03133 int
03134 KApplication::startServiceByDesktopName( const TQString& _name, const TQStringList &URLs,
03135                   TQString *error, TQCString *dcopService, int *pid, const TQCString& startup_id, bool noWait )
03136 {
03137    return startServiceInternal(
03138                       "start_service_by_desktop_name(TQString,TQStringList,TQValueList<TQCString>,TQCString,bool)",
03139                       _name, URLs, error, dcopService, pid, startup_id, noWait);
03140 }
03141 
03142 int
03143 KApplication::kdeinitExec( const TQString& name, const TQStringList &args,
03144                            TQString *error, int *pid )
03145 {
03146     return kdeinitExec( name, args, error, pid, "" );
03147 }
03148 
03149 int
03150 KApplication::kdeinitExec( const TQString& name, const TQStringList &args,
03151                            TQString *error, int *pid, const TQCString& startup_id )
03152 {
03153    return startServiceInternal("kdeinit_exec(TQString,TQStringList,TQValueList<TQCString>,TQCString)",
03154         name, args, error, 0, pid, startup_id, false);
03155 }
03156 
03157 int
03158 KApplication::kdeinitExecWait( const TQString& name, const TQStringList &args,
03159                            TQString *error, int *pid )
03160 {
03161     return kdeinitExecWait( name, args, error, pid, "" );
03162 }
03163 
03164 int
03165 KApplication::kdeinitExecWait( const TQString& name, const TQStringList &args,
03166                            TQString *error, int *pid, const TQCString& startup_id )
03167 {
03168    return startServiceInternal("kdeinit_exec_wait(TQString,TQStringList,TQValueList<TQCString>,TQCString)",
03169         name, args, error, 0, pid, startup_id, false);
03170 }
03171 
03172 TQString KApplication::tempSaveName( const TQString& pFilename ) const
03173 {
03174   TQString aFilename;
03175 
03176   if( TQDir::isRelativePath(pFilename) )
03177     {
03178       kdWarning(101) << "Relative filename passed to KApplication::tempSaveName" << endl;
03179       aFilename = TQFileInfo( TQDir( "." ), pFilename ).absFilePath();
03180     }
03181   else
03182     aFilename = pFilename;
03183 
03184   TQDir aAutosaveDir( TQDir::homeDirPath() + "/autosave/" );
03185   if( !aAutosaveDir.exists() )
03186     {
03187       if( !aAutosaveDir.mkdir( aAutosaveDir.absPath() ) )
03188         {
03189           // Last chance: use temp dir
03190           aAutosaveDir.setPath( KGlobal::dirs()->saveLocation("tmp") );
03191         }
03192     }
03193 
03194   aFilename.replace( "/", "\\!" ).prepend( "#" ).append( "#" ).prepend( "/" ).prepend( aAutosaveDir.absPath() );
03195 
03196   return aFilename;
03197 }
03198 
03199 
03200 TQString KApplication::checkRecoverFile( const TQString& pFilename,
03201         bool& bRecover ) const
03202 {
03203   TQString aFilename;
03204 
03205   if( TQDir::isRelativePath(pFilename) )
03206     {
03207       kdWarning(101) << "Relative filename passed to KApplication::tempSaveName" << endl;
03208       aFilename = TQFileInfo( TQDir( "." ), pFilename ).absFilePath();
03209     }
03210   else
03211     aFilename = pFilename;
03212 
03213   TQDir aAutosaveDir( TQDir::homeDirPath() + "/autosave/" );
03214   if( !aAutosaveDir.exists() )
03215     {
03216       if( !aAutosaveDir.mkdir( aAutosaveDir.absPath() ) )
03217         {
03218           // Last chance: use temp dir
03219           aAutosaveDir.setPath( KGlobal::dirs()->saveLocation("tmp") );
03220         }
03221     }
03222 
03223   aFilename.replace( "/", "\\!" ).prepend( "#" ).append( "#" ).prepend( "/" ).prepend( aAutosaveDir.absPath() );
03224 
03225   if( TQFile( aFilename ).exists() )
03226     {
03227       bRecover = true;
03228       return aFilename;
03229     }
03230   else
03231     {
03232       bRecover = false;
03233       return pFilename;
03234     }
03235 }
03236 
03237 
03238 bool checkAccess(const TQString& pathname, int mode)
03239 {
03240   int accessOK = access( TQFile::encodeName(pathname), mode );
03241   if ( accessOK == 0 )
03242     return true;  // OK, I can really access the file
03243 
03244   // else
03245   // if we want to write the file would be created. Check, if the
03246   // user may write to the directory to create the file.
03247   if ( (mode & W_OK) == 0 )
03248     return false;   // Check for write access is not part of mode => bail out
03249 
03250 
03251   if (!access( TQFile::encodeName(pathname), F_OK)) // if it already exists
03252       return false;
03253 
03254   //strip the filename (everything until '/' from the end
03255   TQString dirName(pathname);
03256   int pos = dirName.findRev('/');
03257   if ( pos == -1 )
03258     return false;   // No path in argument. This is evil, we won't allow this
03259   else if ( pos == 0 ) // don't turn e.g. /root into an empty string
03260       pos = 1;
03261 
03262   dirName.truncate(pos); // strip everything starting from the last '/'
03263 
03264   accessOK = access( TQFile::encodeName(dirName), W_OK );
03265   // -?- Can I write to the accessed diretory
03266   if ( accessOK == 0 )
03267     return true;  // Yes
03268   else
03269     return false; // No
03270 }
03271 
03272 void KApplication::setTopWidget( TQWidget *topWidget )
03273 {
03274   if( !topWidget )
03275       return;
03276 
03277     // set the specified caption
03278     if ( !topWidget->inherits("KMainWindow") ) { // KMainWindow does this already for us
03279         topWidget->setCaption( caption() );
03280     }
03281 
03282     // set the specified icons
03283     topWidget->setIcon( icon() ); //standard X11
03284 #if defined Q_WS_X11
03285 //#ifdef Q_WS_X11 // FIXME(E): Implement for Qt/Embedded
03286     KWin::setIcons(topWidget->winId(), icon(), miniIcon() ); // NET_WM hints for KWin
03287 
03288     // set the app startup notification window property
03289     KStartupInfo::setWindowStartupId( topWidget->winId(), startupId());
03290 #endif
03291 }
03292 
03293 TQCString KApplication::startupId() const
03294 {
03295     return d->startup_id;
03296 }
03297 
03298 void KApplication::setStartupId( const TQCString& startup_id )
03299 {
03300     if( startup_id == d->startup_id )
03301         return;
03302 #if defined Q_WS_X11
03303     KStartupInfo::handleAutoAppStartedSending(); // finish old startup notification if needed
03304 #endif
03305     if( startup_id.isEmpty())
03306         d->startup_id = "0";
03307     else
03308         {
03309         d->startup_id = startup_id;
03310 #if defined Q_WS_X11
03311         KStartupInfoId id;
03312         id.initId( startup_id );
03313         long timestamp = id.timestamp();
03314         if( timestamp != 0 )
03315             updateUserTimestamp( timestamp );
03316 #endif
03317         }
03318 }
03319 
03320 // read the startup notification env variable, save it and unset it in order
03321 // not to propagate it to processes started from this app
03322 void KApplication::read_app_startup_id()
03323 {
03324 #if defined Q_WS_X11
03325     KStartupInfoId id = KStartupInfo::currentStartupIdEnv();
03326     KStartupInfo::resetStartupEnv();
03327     d->startup_id = id.id();
03328 #endif
03329 }
03330 
03331 int KApplication::random()
03332 {
03333    static bool init = false;
03334    if (!init)
03335    {
03336       unsigned int seed;
03337       init = true;
03338       int fd = open("/dev/urandom", O_RDONLY);
03339       if (fd < 0 || ::read(fd, &seed, sizeof(seed)) != sizeof(seed))
03340       {
03341             // No /dev/urandom... try something else.
03342             srand(getpid());
03343             seed = rand()+time(0);
03344       }
03345       if (fd >= 0) close(fd);
03346       srand(seed);
03347    }
03348    return rand();
03349 }
03350 
03351 TQString KApplication::randomString(int length)
03352 {
03353    if (length <=0 ) return TQString::null;
03354 
03355    TQString str; str.setLength( length );
03356    int i = 0;
03357    while (length--)
03358    {
03359       int r=random() % 62;
03360       r+=48;
03361       if (r>57) r+=7;
03362       if (r>90) r+=6;
03363       str[i++] =  char(r);
03364       // so what if I work backwards?
03365    }
03366    return str;
03367 }
03368 
03369 bool KApplication::authorize(const TQString &genericAction)
03370 {
03371    if (!d->actionRestrictions)
03372       return true;
03373 
03374    KConfig *config = KGlobal::config();
03375    KConfigGroupSaver saver( config, "KDE Action Restrictions" );
03376    return config->readBoolEntry(genericAction, true);
03377 }
03378 
03379 bool KApplication::authorizeKAction(const char *action)
03380 {
03381    if (!d->actionRestrictions || !action)
03382       return true;
03383 
03384    static const TQString &action_prefix = KGlobal::staticQString( "action/" );
03385 
03386    return authorize(action_prefix + action);
03387 }
03388 
03389 bool KApplication::authorizeControlModule(const TQString &menuId)
03390 {
03391    if (menuId.isEmpty() || kde_kiosk_exception)
03392       return true;
03393    KConfig *config = KGlobal::config();
03394    KConfigGroupSaver saver( config, "KDE Control Module Restrictions" );
03395    return config->readBoolEntry(menuId, true);
03396 }
03397 
03398 TQStringList KApplication::authorizeControlModules(const TQStringList &menuIds)
03399 {
03400    KConfig *config = KGlobal::config();
03401    KConfigGroupSaver saver( config, "KDE Control Module Restrictions" );
03402    TQStringList result;
03403    for(TQStringList::ConstIterator it = menuIds.begin();
03404        it != menuIds.end(); ++it)
03405    {
03406       if (config->readBoolEntry(*it, true))
03407          result.append(*it);
03408    }
03409    return result;
03410 }
03411 
03412 void KApplication::initUrlActionRestrictions()
03413 {
03414   d->urlActionRestrictions.setAutoDelete(true);
03415   d->urlActionRestrictions.clear();
03416   d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03417   ("open", TQString::null, TQString::null, TQString::null, TQString::null, TQString::null, TQString::null, true));
03418   d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03419   ("list", TQString::null, TQString::null, TQString::null, TQString::null, TQString::null, TQString::null, true));
03420 // TEST:
03421 //  d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03422 //  ("list", TQString::null, TQString::null, TQString::null, TQString::null, TQString::null, TQString::null, false));
03423 //  d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03424 //  ("list", TQString::null, TQString::null, TQString::null, "file", TQString::null, TQDir::homeDirPath(), true));
03425   d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03426   ("link", TQString::null, TQString::null, TQString::null, ":internet", TQString::null, TQString::null, true));
03427   d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03428   ("redirect", TQString::null, TQString::null, TQString::null, ":internet", TQString::null, TQString::null, true));
03429 
03430   // We allow redirections to file: but not from internet protocols, redirecting to file:
03431   // is very popular among io-slaves and we don't want to break them
03432   d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03433   ("redirect", TQString::null, TQString::null, TQString::null, "file", TQString::null, TQString::null, true));
03434   d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03435   ("redirect", ":internet", TQString::null, TQString::null, "file", TQString::null, TQString::null, false));
03436 
03437   // local protocols may redirect everywhere
03438   d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03439   ("redirect", ":local", TQString::null, TQString::null, TQString::null, TQString::null, TQString::null, true));
03440 
03441   // Anyone may redirect to about:
03442   d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03443   ("redirect", TQString::null, TQString::null, TQString::null, "about", TQString::null, TQString::null, true));
03444 
03445   // Anyone may redirect to itself, cq. within it's own group
03446   d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03447   ("redirect", TQString::null, TQString::null, TQString::null, "=", TQString::null, TQString::null, true));
03448 
03449   KConfig *config = KGlobal::config();
03450   KConfigGroupSaver saver( config, "KDE URL Restrictions" );
03451   int count = config->readNumEntry("rule_count");
03452   TQString keyFormat = TQString("rule_%1");
03453   for(int i = 1; i <= count; i++)
03454   {
03455     TQString key = keyFormat.arg(i);
03456     TQStringList rule = config->readListEntry(key);
03457     if (rule.count() != 8)
03458       continue;
03459     TQString action = rule[0];
03460     TQString refProt = rule[1];
03461     TQString refHost = rule[2];
03462     TQString refPath = rule[3];
03463     TQString urlProt = rule[4];
03464     TQString urlHost = rule[5];
03465     TQString urlPath = rule[6];
03466     TQString strEnabled = rule[7].lower();
03467 
03468     bool bEnabled = (strEnabled == "true");
03469 
03470     if (refPath.startsWith("$HOME"))
03471        refPath.replace(0, 5, TQDir::homeDirPath());
03472     else if (refPath.startsWith("~"))
03473        refPath.replace(0, 1, TQDir::homeDirPath());
03474     if (urlPath.startsWith("$HOME"))
03475        urlPath.replace(0, 5, TQDir::homeDirPath());
03476     else if (urlPath.startsWith("~"))
03477        urlPath.replace(0, 1, TQDir::homeDirPath());
03478 
03479     if (refPath.startsWith("$TMP"))
03480        refPath.replace(0, 4, KGlobal::dirs()->saveLocation("tmp"));
03481     if (urlPath.startsWith("$TMP"))
03482        urlPath.replace(0, 4, KGlobal::dirs()->saveLocation("tmp"));
03483 
03484     d->urlActionRestrictions.append(new KApplicationPrivate::URLActionRule
03485         ( action, refProt, refHost, refPath, urlProt, urlHost, urlPath, bEnabled));
03486   }
03487 }
03488 
03489 void KApplication::allowURLAction(const TQString &action, const KURL &_baseURL, const KURL &_destURL)
03490 {
03491   if (authorizeURLAction(action, _baseURL, _destURL))
03492      return;
03493 
03494   d->urlActionRestrictions.append(new KApplicationPrivate::URLActionRule
03495         ( action, _baseURL.protocol(), _baseURL.host(), _baseURL.path(-1),
03496                   _destURL.protocol(), _destURL.host(), _destURL.path(-1), true));
03497 }
03498 
03499 bool KApplication::authorizeURLAction(const TQString &action, const KURL &_baseURL, const KURL &_destURL)
03500 {
03501   if (_destURL.isEmpty())
03502      return true;
03503 
03504   bool result = false;
03505   if (d->urlActionRestrictions.isEmpty())
03506      initUrlActionRestrictions();
03507 
03508   KURL baseURL(_baseURL);
03509   baseURL.setPath(TQDir::cleanDirPath(baseURL.path()));
03510   TQString baseClass = KProtocolInfo::protocolClass(baseURL.protocol());
03511   KURL destURL(_destURL);
03512   destURL.setPath(TQDir::cleanDirPath(destURL.path()));
03513   TQString destClass = KProtocolInfo::protocolClass(destURL.protocol());
03514 
03515   for(KApplicationPrivate::URLActionRule *rule = d->urlActionRestrictions.first();
03516       rule; rule = d->urlActionRestrictions.next())
03517   {
03518      if ((result != rule->permission) && // No need to check if it doesn't make a difference
03519          (action == rule->action) &&
03520          rule->baseMatch(baseURL, baseClass) &&
03521          rule->destMatch(destURL, destClass, baseURL, baseClass))
03522      {
03523         result = rule->permission;
03524      }
03525   }
03526   return result;
03527 }
03528 
03529 
03530 uint KApplication::keyboardModifiers()
03531 {
03532 #ifdef Q_WS_X11
03533     Window root;
03534     Window child;
03535     int root_x, root_y, win_x, win_y;
03536     uint keybstate;
03537     XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
03538                    &root_x, &root_y, &win_x, &win_y, &keybstate );
03539     return keybstate & 0x00ff;
03540 #elif defined W_WS_MACX
03541     return GetCurrentEventKeyModifiers() & 0x00ff;
03542 #else
03543     //TODO for win32
03544     return 0;
03545 #endif
03546 }
03547 
03548 uint KApplication::mouseState()
03549 {
03550     uint mousestate;
03551 #ifdef Q_WS_X11
03552     Window root;
03553     Window child;
03554     int root_x, root_y, win_x, win_y;
03555     XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
03556                    &root_x, &root_y, &win_x, &win_y, &mousestate );
03557 #elif defined(Q_WS_WIN)
03558     const bool mousebtn_swapped = GetSystemMetrics(SM_SWAPBUTTON);
03559     if (GetAsyncKeyState(VK_LBUTTON))
03560         mousestate |= (mousebtn_swapped ? Button3Mask : Button1Mask);
03561     if (GetAsyncKeyState(VK_MBUTTON))
03562         mousestate |= Button2Mask;
03563     if (GetAsyncKeyState(VK_RBUTTON))
03564         mousestate |= (mousebtn_swapped ? Button1Mask : Button3Mask);
03565 #elif defined(Q_WS_MACX)
03566     mousestate = GetCurrentEventButtonState();
03567 #else
03568     //TODO: other platforms
03569 #endif
03570     return mousestate & 0xff00;
03571 }
03572 
03573 TQ_ButtonState KApplication::keyboardMouseState()
03574 {
03575     int ret = 0;
03576 #ifdef Q_WS_X11
03577     Window root;
03578     Window child;
03579     int root_x, root_y, win_x, win_y;
03580     uint state;
03581     XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
03582                    &root_x, &root_y, &win_x, &win_y, &state );
03583     // transform the same way like Qt's qt_x11_translateButtonState()
03584     if( state & Button1Mask )
03585         ret |= TQ_LeftButton;
03586     if( state & Button2Mask )
03587         ret |= TQ_MidButton;
03588     if( state & Button3Mask )
03589         ret |= TQ_RightButton;
03590     if( state & ShiftMask )
03591         ret |= TQ_ShiftButton;
03592     if( state & ControlMask )
03593         ret |= TQ_ControlButton;
03594     if( state & KKeyNative::modX( KKey::ALT ))
03595         ret |= TQ_AltButton;
03596     if( state & KKeyNative::modX( KKey::WIN ))
03597         ret |= TQ_MetaButton;
03598 #elif defined(Q_WS_WIN)
03599     const bool mousebtn_swapped = GetSystemMetrics(SM_SWAPBUTTON);
03600     if (GetAsyncKeyState(VK_LBUTTON))
03601         ret |= (mousebtn_swapped ? RightButton : LeftButton);
03602     if (GetAsyncKeyState(VK_MBUTTON))
03603         ret |= TQ_MidButton;
03604     if (GetAsyncKeyState(VK_RBUTTON))
03605         ret |= (mousebtn_swapped ? TQ_LeftButton : TQ_RightButton);
03606     if (GetAsyncKeyState(VK_SHIFT))
03607         ret |= TQ_ShiftButton;
03608     if (GetAsyncKeyState(VK_CONTROL))
03609         ret |= TQ_ControlButton;
03610     if (GetAsyncKeyState(VK_MENU))
03611         ret |= TQ_AltButton;
03612     if (GetAsyncKeyState(VK_LWIN) || GetAsyncKeyState(VK_RWIN))
03613         ret |= TQ_MetaButton;
03614 #else
03615     //TODO: other platforms
03616 #endif
03617     return static_cast< ButtonState >( ret );
03618 }
03619 
03620 void KApplication::installSigpipeHandler()
03621 {
03622 #ifdef Q_OS_UNIX
03623     struct sigaction act;
03624     act.sa_handler = SIG_IGN;
03625     sigemptyset( &act.sa_mask );
03626     act.sa_flags = 0;
03627     sigaction( SIGPIPE, &act, 0 );
03628 #endif
03629 }
03630 
03631 void KApplication::sigpipeHandler(int)
03632 {
03633     int saved_errno = errno;
03634     // Using kdDebug from a signal handler is not a good idea.
03635 #ifndef NDEBUG
03636     char msg[1000];
03637     sprintf(msg, "*** SIGPIPE *** (ignored, pid = %ld)\n", (long) getpid());
03638     if (write(2, msg, strlen(msg)) < 0) {
03639       // ERROR
03640     }
03641 #endif
03642 
03643     // Do nothing.
03644     errno = saved_errno;
03645 }
03646 
03647 bool KApplication::guiEnabled()
03648 {
03649     return kapp && kapp->d->guiEnabled;
03650 }
03651 
03652 void KApplication::virtual_hook( int id, void* data )
03653 { KInstance::virtual_hook( id, data ); }
03654 
03655 void KSessionManaged::virtual_hook( int, void* )
03656 { /*BASE::virtual_hook( id, data );*/ }
03657 
03658 #include "kapplication.moc"

kdecore

Skip menu "kdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdecore

Skip menu "kdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdecore by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |