--nextPart8292681.OIEt6Ki1OR Content-Type: multipart/mixed; boundary="Boundary-01=_4ytrC25StuwCmTW" Content-Transfer-Encoding: 7bit Content-Disposition: inline --Boundary-01=_4ytrC25StuwCmTW Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Hi There has been a discussion on kde-optimize about KIconLoader improvements.= =20 I'm working to create an icon server that is used to share icons between=20 applications. The original idea and its initial implementation is from Lubo= s=20 Lunak.=20 The idea is to have a daemon running which publishes icons and stay=20 refcounting their usage. When an application requests an icon to KIconLoade= r,=20 it checks for the icon in a cache file which contains just the key and the = X=20 resource id for the icon. If the icon is there, it creates a pixmap using t= he=20 given resource id (sharing the pixmap in the X server). If the icon is not= =20 there, it queue the icon to be sent to the server.=20 One problem I had (and I want a little help on that) is when using=20 KUniqueApplication. When it forks, there is a race condition on the DCOP=20 calls (when the KIconLoader is created, it checks for the iconserver to be= =20 running using a DCOP call). Simply commenting the dc->setPriorityCall(true)= =20 lines in kuniqueapplication.cpp solved the problem, but I don't think that = is=20 the best way of doing it, help is appreciated. I have been playing with it and it is quite stable. I have some results (I= =20 didn't measure memory usage yet, just time for loading icons) that I want y= ou=20 to take a look: test1: 369 icons (32x32) w/o disk cache: 3628 ms cached: 361 ms iconserver: 74 ms =2D----------------------- test2: 222 icons (48x48) w/o disk cache: 2262 ms cached: 322 ms iconserver: 35ms =2D----------------------- test3: 774 icons (32x32) w/o disk cache: 4974 ms cached: 1170 ms iconserver: 709 ms The patch for this icon server is attached. Please take it a look and give me a feedback about that. Thanks in advance =2D-=20 Gustavo Pichorim Boiko ----------------------------------------------------- KDE Developer Computer Science - UFPR =20 Mandriva Labs gustavo . boiko @ kdemail . net=20 ----------------------------------------------------- --Boundary-01=_4ytrC25StuwCmTW Content-Type: text/x-diff; charset="us-ascii"; name="kdecore_iconserver.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="kdecore_iconserver.patch" Index: iconserver/bla.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- iconserver/bla.cpp (revis=C3=A3o 0) +++ iconserver/bla.cpp (revis=C3=A3o 0) @@ -0,0 +1,49 @@ +#include +#include +#include +#include + +int write_fd =3D -1; + =20 +void parent_wait() + { + int fds[ 2 ]; + if( pipe( fds ) < 0 ) + exit( 1 ); + switch( fork()) + { + case -1: + exit( 1 ); + case 0: + { + write_fd =3D fds[ 1 ]; + close( fds[ 0 ] ); + return; // ok, continue + } + default: + { + close( fds[ 1 ] ); + char tmp; + read( fds[ 0 ], &tmp, 1 ); // wait for parent to finish initia= lization + exit( 0 ); + } + } + } +int main( int argc, char* argv[] ) + { + parent_wait(); +// KCmdLineArgs::init( argc, argv, "a", "b", "c" ); + // tohle s KUniqueApp nefunguje + if( KApplication::dcopClient()->isApplicationRegistered( "iconserver" = )) + return 0; +// KApplication app; + QApplication app( argc, argv ); + KInstance inst( "a" ); + KIconServer server; +// app.disableSessionManagement(); + char tmp; + write( write_fd, &tmp, 1 ); // tell parent init is done + return app.exec(); + // CHECKME zajistit, at ostatni cekaji, dokud se nenahraji vsechny iko= ny + } +=20 Index: iconserver/kiconserver.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- iconserver/kiconserver.h (revis=C3=A3o 0) +++ iconserver/kiconserver.h (revis=C3=A3o 0) @@ -0,0 +1,81 @@ +/*************************************************************************= *** + + $Id: iconserver.h,v 1.11 2001/08/29 15:25:38 bero Exp $ + + Copyright (C) 2001 Lubos Lunak + + This file is part of the KDE libraries + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +**************************************************************************= **/ + +#ifndef __KICONSERVER_H +#define __KICONSERVER_H + +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#define appref_h "appref.h" +#include appref_h // avoid including it in stub generated from this .h file +#undef appref_h + +class KDECORE_EXPORT KIconServer + : public QObject, public DCOPObject + { + Q_OBJECT + K_DCOP + k_dcop: + bool serverRunning(); + ASYNC newIcons( KIconSendDataList icons ); // means also refIcons + ASYNC refIcons( QValueList< QCString > keys ); + ASYNC derefIcons( QValueList< QCString > keys ); + public: + KIconServer(); + ~KIconServer(); + private slots: + void flushIcons(); + void ageIcons(); + void app_reg( const QCString& ); + void app_rem( const QCString& ); + void app_ren( const QCString&, const QCString& ); + private: + void createIconsFile( const QString& path_P ); + bool readOldIconsFile( const QString& path_P ); + int makeKeySizes(); + bool publishIcons( const QString& path_P, int mmap_size_P ); + void defaultIcons(); + void addIcon( const QString& name, int group, int size, int state = ); + bool splitKey( const QString& key, QString& name, int& size ) cons= t; + void app_ref_deref( const QCString& app_id_P, const QValueList< QC= String >& keys_P ,bool ref_P ); + QTimer update_timer; + QTimer age_timer; + int old_icons_count; // number of icons scheduled for removal ( no= longer published ) + IconsMap icons; + typedef QValueList< KIconAppRef > AppRefList; + AppRefList app_ref_list; + }; + +#endif Index: iconserver/appref.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- iconserver/appref.h (revis=C3=A3o 0) +++ iconserver/appref.h (revis=C3=A3o 0) @@ -0,0 +1,122 @@ +/*************************************************************************= *** + + $Id: iconserver.h,v 1.11 2001/08/29 15:25:38 bero Exp $ + + Copyright (C) 2001 Lubos Lunak + + This file is part of the KDE libraries + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +**************************************************************************= **/ + +#ifndef __APP_REF_H +#define __APP_REF_H + +#include + +#include "kicondata.h" + +struct KIconAppRefData + { + QCString key; + int count; + bool operator=3D=3D( const KIconAppRefData& r_P ) const; + bool operator<( const KIconAppRefData& r_P ) const; + bool operator>( const KIconAppRefData& r_P ) const; + bool operator!=3D( const KIconAppRefData& r_P ) const; + bool operator<=3D( const KIconAppRefData& r_P ) const; + bool operator>=3D( const KIconAppRefData& r_P ) const; + static int cmp( const QCString& l_P, const QCString& r_P ); + }; + =20 +class KIconAppRef + { + public: + KIconAppRef( const QCString& app_id_P ); + KIconAppRef(); // only for QValueList + KIconAppRef( const KIconAppRef& src_P ); // only for QValueList + ~KIconAppRef(); + void ref( const QValueList< QCString > keys_P ); + void deref( const QValueList< QCString > keys_P ); + void free( IconsMap& icons ); + void change_app_id( const QCString& app_id_P ); + const QCString& app_id() const; + private: + void resize( unsigned int new_size_P ); + QCString _app_id; + mutable KIconAppRefData* arr; // mutable only because of KIconAppR= ef( const KIconAppRef& ); + int used_size; + int allocated_size; + }; + +// Inline + +inline +KIconAppRef::KIconAppRef() + { + } + =20 +inline +void KIconAppRef::change_app_id( const QCString& app_id_P ) + { + _app_id =3D app_id_P; + } + =20 +inline +const QCString& KIconAppRef::app_id() const + { + return _app_id; + } + +inline +bool KIconAppRefData::operator=3D=3D( const KIconAppRefData& r_P ) const + { + return cmp( key, r_P.key ) =3D=3D 0; + } + =20 +inline +bool KIconAppRefData::operator<( const KIconAppRefData& r_P ) const + { + return cmp( key, r_P.key ) < 0; + } + =20 +inline +bool KIconAppRefData::operator>( const KIconAppRefData& r_P ) const + { + return cmp( key, r_P.key ) > 0; + } + =20 +inline +bool KIconAppRefData::operator!=3D( const KIconAppRefData& r_P ) const + { + return cmp( key, r_P.key ) !=3D 0; + } + =20 +inline +bool KIconAppRefData::operator<=3D( const KIconAppRefData& r_P ) const + { + return cmp( key, r_P.key ) <=3D 0; + } + =20 +inline +bool KIconAppRefData::operator>=3D( const KIconAppRefData& r_P ) const + { + return cmp( key, r_P.key ) >=3D 0; + } + =20 + =20 +#endif Index: iconserver/kicondata.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- iconserver/kicondata.h (revis=C3=A3o 0) +++ iconserver/kicondata.h (revis=C3=A3o 0) @@ -0,0 +1,97 @@ +/*************************************************************************= *** + + $Id: iconserver.h,v 1.11 2001/08/29 15:25:38 bero Exp $ + + Copyright (C) 2001 Lubos Lunak + + This file is part of the KDE libraries + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +**************************************************************************= **/ + +#ifndef __KICONDATA_H +#define __KICONDATA_H + +#include + +#include + +struct KIconData + { + public: + KIconData(); + KIconData( const QPixmap& pm_P, int group_P, int state_P, int usag= e_P ); + bool ref(); // true if was old before ref() + bool deref(); // false if became unused + bool in_use() const; + bool age(); // return true if became old + bool old() const; // scheduled for removal + bool too_old() const; + KIconDataPixmap pixmap; + int group; + int state; + int key_pos; // used only when saving + private: + int usage; // >0 =3D refcount, <0 =3D age + }; + +typedef QMap< QCString, KIconData > IconsMap; + +// Inline + +inline +KIconData::KIconData() + { + } + +inline +KIconData::KIconData( const QPixmap& pm_P, int group_P, int state_P, int u= sage_P ) + : pixmap( pm_P ), group( group_P ), state( state_P ), usage( usage_P ) + { + } + =20 +inline +bool KIconData::deref() + { + return usage > 0 && --usage =3D=3D 0; + } + =20 +inline +bool KIconData::in_use() const + { + return usage > 0; + } + =20 +inline +bool KIconData::age() + { + return usage <=3D 0 && --usage =3D=3D -5; // <=3D -5 =3D old + } + +inline +bool KIconData::old() const + { + return usage <=3D -5; // < -5 =3D old + } + +inline +bool KIconData::too_old() const + { + return usage <=3D -10; // <=3D - 10 =3D too old + } + +#endif Index: iconserver/icontest.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- iconserver/icontest.cpp (revis=C3=A3o 0) +++ iconserver/icontest.cpp (revis=C3=A3o 0) @@ -0,0 +1,51 @@ +/*************************************************************************= *** + + $Id: iconserver.h,v 1.11 2001/08/29 15:25:38 bero Exp $ + + Copyright (C) 2001 Lubos Lunak + + This file is part of the KDE libraries + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +**************************************************************************= **/ + +#include +#include +#include +#include +#include +#include +#include + +int main( int argc, char* argv[] ) + { + KCmdLineArgs::init( argc, argv, "a", "b", "c" ); + KApplication app; + app.dcopClient()->attach(); + QPixmap pm =3D DesktopIcon( "go" ); + QWidget w; + w.setGeometry( 10, 10, 100, 100 ); + QLabel l( &w ); + l.resize( pm.width(), pm.height()); + l.setPixmap( pm ); + l.move( 10, 10 ); + w.show(); + app.setMainWidget( &w ); + return app.exec(); + } + =20 +//#include "iconserver.moc" Index: iconserver/Makefile.am =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- iconserver/Makefile.am (revis=C3=A3o 0) +++ iconserver/Makefile.am (revis=C3=A3o 0) @@ -0,0 +1,33 @@ +INCLUDES =3D $(all_includes) -I$(srcdir)/.. + +bin_PROGRAMS =3D kiconserver +lib_LTLIBRARIES =3D kiconserver.la + +kiconserver_la_SOURCES =3D kiconserver.cpp kiconserver.skel appref.cpp +kiconserver_la_LDFLAGS =3D $(all_libraries) -module -avoid-version +kiconserver_la_LIBADD =3D $(LIB_KDECORE) + +kiconserver_SOURCES =3D dummy.cpp +kiconserver_LDFLAGS =3D $(all_libraries) $(KDE_RPATH) +kiconserver_LDADD =3D kiconserver.la + +noinst_HEADERS =3D kiconserver.h appref.h kicondata.h + +#kde_module_LTLIBRARIES =3D libkded_iconserver.la + +#libkded_iconserver_la_SOURCES =3D iconserver.cpp iconserver.skel iconserv= er.h +#libkded_iconserver_la_LDFLAGS =3D $(all_libraries) -module -avoid-version +#libkded_iconserver_la_LIBADD =3D $(LIB_KDECORE) + +METASOURCES =3D AUTO + +#servicesdir =3D $(kde_servicesdir)/kded +#services_DATA =3D kiconserver.desktop + +check_PROGRAMS =3D icontest +icontest_SOURCES =3D icontest.cpp +icontest_LDFLAGS =3D $(all_libraries) $(KDE_RPATH) +icontest_LDADD =3D $(LIB_KDECORE) + +dummy.cpp: + echo >dummy.cpp Index: iconserver/kiconserver.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- iconserver/kiconserver.cpp (revis=C3=A3o 0) +++ iconserver/kiconserver.cpp (revis=C3=A3o 0) @@ -0,0 +1,491 @@ +/*************************************************************************= *** + + $Id: iconserver.h,v 1.11 2001/08/29 15:25:38 bero Exp $ + + Copyright (C) 2001 Lubos Lunak + + This file is part of the KDE libraries + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +**************************************************************************= **/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef HAVE_MMAP +#error This works only with HAVE_MMAP +#endif + +#include "kiconserver.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +// CHECKME chybi tu osetreni NO_XRENDER + =20 +KIconServer::KIconServer() + : DCOPObject( "iconserver" ), old_icons_count( 0 ) + { + + kdDebug( 179 ) << k_funcinfo << "starting up" << endl; + ( void ) KGlobal::iconLoader(); // trigger iconloader ( and iconserver= client ) creation + // register as iconserver here, so we don't ask ourselves for loading = icons + kapp->dcopClient()->registerAs( "iconserver", false ); + kapp->dcopClient()->setNotifications( true ); + kdDebug( 197) << k_funcinfo << "added DCOP calls" << endl; + connect( kapp->dcopClient(), SIGNAL( applicationRegistered( const QCSt= ring& )), + SLOT( app_reg( const QCString& ))); + connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCStrin= g& )), + SLOT( app_rem( const QCString& ))); + connect( kapp->dcopClient(), SIGNAL( applicationRenamed( const QCStrin= g&, const QCString& )), + SLOT( app_ren( const QCString&, const QCString& ))); + connect( &update_timer, SIGNAL( timeout()), this, SLOT( flushIcons())); + connect( &age_timer, SIGNAL( timeout()), this, SLOT( ageIcons())); + age_timer.start( 20000 ); // 20s * 5 =3D 100s before becomes old and a= nother 100s before removed +// CHECKME hledat nejnovejsi kiconsfile a z nej nacist seznam pro nahrani + QString path =3D KGlobal::dirs()->saveLocation("tmp") + "kiconsfile-" = + getenv( "DISPLAY" ); + if( !QFile::exists( path ) || !readOldIconsFile( path )) + defaultIcons(); + createIconsFile( path ); + kdDebug(179) << k_funcinfo << "running" << endl; + } + +KIconServer::~KIconServer() + { + } + +bool KIconServer::serverRunning() + { + return true; + } + +bool KIconServer::readOldIconsFile( const QString& path_P ) + { // from KIconLoader + QFile* icons_file =3D new QFile( path_P ); + if( !icons_file->open( IO_ReadOnly )) + return false; + int mmap_size =3D icons_file->size(); + KIconsFile* icons_mmap =3D reinterpret_cast< KIconsFile* >( mmap( 0, m= map_size, + PROT_READ, MAP_PRIVATE, icons_file->handle(), 0 )); + if( icons_mmap =3D=3D NULL ) + { + return false; + } + if( icons_mmap->version !=3D KICONSFILEVERSION ) + { + munmap( (char*) icons_mmap, mmap_size ); + delete icons_file; + return false; + } + kdDebug( 179 ) << "reading old icons file, size=3D" << icons_mmap->cou= nt << endl; + for( int i =3D 0; + i < icons_mmap->count; + ++i ) + { + KIconFileEntry& data =3D icons_mmap->entries[ i ]; + const char* key =3D reinterpret_cast< char* >( icons_mmap ) + data= =2Ekey_ref; + QString name; + int size; + if( !splitKey( QString::fromUtf8( key ), name, size )) + continue; + // CHECKME zkusit ze vsech images udelat jednu velkou qimage a pak= z ni jednu qpixmap? + KIconDataPixmap pm =3D KGlobal::iconLoader()->loadIcon( name, KIco= n::Group(data.group), size, data.state, + NULL, true ); + if( pm.isNull()) + { + kdDebug( 179 ) << "cannot load old icon " << key << endl; + continue; + } + if( pm.width() !=3D pm.height()) + { + kdWarning( 179 ) << "icon \"" << key << "\" has size " << pm.w= idth() << "x" << pm.height() << endl; + continue; + } + kdDebug( 179 ) << "reading icon from old file \"" << key << "\" (" + << pm.handle() << "/" << pm.maskHandle() << "/" << pm.alphaHan= dle() << ")" << endl; + icons[ key ] =3D KIconData( pm, data.group, data.state, 0 ); + } + munmap( (char*) icons_mmap, mmap_size ); + delete icons_file; + return true; + } + +bool KIconServer::splitKey( const QString& key, QString& name, int& size )= const +{ + QString k =3D key.mid( 6 ); // strip leading "$kico_" + int pos =3D k.find( ':' ); + if( pos < 1 ) + return false; + name =3D k.left( pos ); // name + k =3D k.mid( pos + 1 ); + pos =3D k.find( '_' ); + if( pos < 1 ) + return false; + size =3D k.left( pos ).toInt(); // size + return true; =20 +} + + +void KIconServer::createIconsFile( const QString& path_P ) + { + int mmap_size =3D makeKeySizes(); + if( !publishIcons( path_P, mmap_size )) + kapp->quit(); // oops CHECKME tohle se nesmi, musi zustat bezet, d= okud je refcount + } + +int KIconServer::makeKeySizes() + { + int pos =3D sizeof( KIconsFile ) + ( icons.size() - old_icons_count - = 1 ) * sizeof( KIconFileEntry ); + for( IconsMap::Iterator it =3D icons.begin(); + it !=3D icons.end(); + ++it ) + { + ( *it ).key_pos =3D pos; + pos +=3D it.key().length() + 1; + } + return pos; + } + +bool KIconServer::publishIcons( const QString& path_P, int mmap_size_P ) + { + bool ok =3D true; + KIconsFile* file_data =3D static_cast< KIconsFile* >( operator new( mm= ap_size_P )); + file_data->version =3D KICONSFILEVERSION; + file_data->depth =3D QPixmap::defaultDepth(); + int pos =3D -1; + for( IconsMap::Iterator it =3D icons.begin(); + it !=3D icons.end(); + ++it ) + { + if( ( *it ).old()) // scheduled for removal + continue; + ++pos; +#if 0 + kdDebug( 179 ) << "putting " << it.key() << " (" + << ( *it ).pixmap.handle() << "/" << ( *it ).pixmap.maskHandle= () + << "/" << ( *it ).pixmap.alphaHandle() << ")" << endl; +#endif + file_data->entries[ pos ].key_ref =3D ( *it ).key_pos; + file_data->entries[ pos ].xid =3D ( *it ).pixmap.handle(); + file_data->entries[ pos ].mask_xid =3D ( *it ).pixmap.maskHandle(); + file_data->entries[ pos ].alpha_xid =3D ( *it ).pixmap.alphaHandle= (); +#ifdef KICON_SHARE_XRENDER + file_data->entries[ pos ].pic =3D ( *it ).pixmap.x11RenderHandle(); + file_data->entries[ pos ].mask_pic =3D ( *it ).pixmap.maskX11Rende= rHandle(); + file_data->entries[ pos ].alpha_pic =3D ( *it ).pixmap.alphaX11Ren= derHandle(); +#endif =20 + file_data->entries[ pos ].size =3D ( *it ).pixmap.width(); + file_data->entries[ pos ].group =3D ( *it ).group; + file_data->entries[ pos ].state =3D ( *it ).state; + } + char* keys =3D reinterpret_cast< char* >( file_data ) + sizeof( KIcons= =46ile ) + + ( icons.size() - old_icons_count - 1 ) * sizeof( KIconFileEntry = ); + for( IconsMap::Iterator it =3D icons.begin(); + it !=3D icons.end(); + ++it ) + { + strcpy( keys, it.key().data()); + keys +=3D it.key().length() + 1; + } + file_data->count =3D icons.size() - old_icons_count; + kdDebug( 179 ) << "saving icons file, published=3D" << icons.size() - = old_icons_count + << ", hidden=3D" << old_icons_count << endl; + KSaveFile file( path_P ); + if( file.status() !=3D 0 ) + ok =3D false; + else + { + file.file()->writeBlock( reinterpret_cast< char* >( file_data ), m= map_size_P ); + operator delete( file_data ); + ok =3D file.close(); + } + // notify ALL applications + QByteArray data; + QDataStream stream( data, IO_WriteOnly ); + stream << ok; + // je tohle ok i pro 2 klienty v jedne app ? + kdDebug( 179 ) << "sending update to apps (" << ok << ")" << endl; + kapp->dcopClient()->send( "*", "iconserverclient*", "iconsFileChanged(= bool)", data ); + return ok; + } =20 + +// only for adding often used icons ... such icons won't age +void KIconServer::addIcon( const QString& name, int group, int size, int s= tate ) + { + KIconDataPixmap pm =3D KGlobal::iconLoader()->loadIcon( name, KIcon::G= roup(group), size, state, NULL, true ); + if( pm.isNull()) + return; + if( size =3D=3D 0 ) + size =3D IconSize( KIcon::Group(group) ); + QString dummy; + QCString key =3D KGlobal::iconLoader()->makeKey( name, group, size, st= ate, dummy ).utf8(); + if( pm.width() !=3D pm.height()) + { + kdWarning( 179 ) << "icon \"" << key << "\" has size " << pm.width= () << "x" << pm.height() << endl; + return; + } + icons[ key ] =3D KIconData( pm, group, state, 1 ); // 1 =3D> prevent a= ging + kdDebug( 179 ) << "added icon: " << pm.handle() << "(" << key << ") (" + << pm.handle() << "/" << pm.maskHandle() << "/" << pm.alphaHan= dle() << ")" << endl; + } + +// CHECKME mit nejaky timeout pri ruseni pixmap, kdyz aplikace pouzije jes= te stary +// index file + =20 +void KIconServer::defaultIcons() + { +// addIcon( "go", KIcon::Desktop, 0, KIcon::DefaultState ); + // TODO + } + + +// CHECKME pak jeste kontrola toho, ze ta aplikace mezitim nespadla +void KIconServer::newIcons( KIconSendDataList icons_P ) + { + kdDebug( 179 ) << "got new icons from app" << endl; + bool added =3D false; + QValueList< QCString > keys; + for( KIconSendDataList::ConstIterator it =3D icons_P.begin(); + it !=3D icons_P.end(); + ++it ) + { + const KIconSendData& data =3D ( *it ); + kdDebug( 179 ) << "checking new icon " << data.key << endl; + if( icons.contains( data.key )) + { + kdDebug( 179 ) << "increasing refcount" << endl; + if( icons[ data.key ].ref()) + --old_icons_count; + continue; + } + // holder_pix must be destroyed before holder_alpha and holder_mask + // all three of them must be destroyed before pix + KIconPixmapHolder holder_mask, holder_alpha, holder_pix; + KIconPixmap pix( data.size, data.size, data.xid, data.mask_xid, da= ta.alpha_xid +#ifdef KICON_SHARE_XRENDER + , data.pic, data.mask_pic, data.alpha_pic +#endif + ); + if( pix.isNull()) // just in case... ? + continue; + holder_pix =3D pix; // prevent QPixmap from freeing the client's p= ixmap + if( pix.mask() !=3D NULL ) + holder_mask =3D *pix.mask(); + if( pix.alpha() !=3D NULL ) + holder_alpha =3D *pix.alpha(); + QPixmap pix_copy( pix ); + pix_copy.detach(); // force creating a deep copy of the p= ixmap + if( pix.mask() !=3D NULL ) // X pixmap handles we got from the = client + { // will become invalid after the clien= t exits + QBitmap bm_copy( *pix.mask()); + bm_copy.detach(); + pix_copy.setMask( bm_copy ); + } +#ifndef NDEBUG + Q_ASSERT( data.xid !=3D pix_copy.handle()); + Q_ASSERT( pix_copy.mask() =3D=3D NULL || pix_copy.mask()->handle()= !=3D data.mask_xid ); + KIconDataPixmap dt( pix_copy ); + Q_ASSERT( pix.alpha() =3D=3D NULL || dt.alphaHandle() !=3D data.al= pha_xid ); +#ifdef KICON_SHARE_XRENDER + Q_ASSERT( pix_copy.x11RenderHandle() =3D=3D None || pix_copy.x11Re= nderHandle() !=3D data.pic ); + Q_ASSERT( dt.maskX11RenderHandle() =3D=3D None + || dt.maskX11RenderHandle() !=3D data.mask_pic ); + Q_ASSERT( dt.alphaX11RenderHandle() =3D=3D None + || dt.alphaX11RenderHandle() !=3D data.alpha_pic ); +#endif +#endif + icons[ data.key ] =3D KIconData( pix_copy, data.group, data.state,= 1 ); // 1 =3D used by the app + kdDebug( 179 ) << "icon added" << endl; + keys.prepend( data.key ); + added =3D true; + } + refIcons( keys ); + if( added && !update_timer.isActive()) + update_timer.start( 10000, true ); // CHECKME 10 secs ? + // asi spis 20 sekund prvni a dalsi 5 sekund + } + +void KIconServer::flushIcons() + { + QString path =3D KGlobal::dirs()->saveLocation("tmp") + "kiconsfile-" = + getenv( "DISPLAY" ); + createIconsFile( path ); + } + =20 +void KIconServer::refIcons( QValueList< QCString > keys_P ) + { + kdDebug( 179 ) << "refIcons" << endl; + if( keys_P.empty()) + return; + for( QValueList< QCString >::ConstIterator it =3D keys_P.begin(); + it !=3D keys_P.end(); + ++it ) + { + if( icons.contains( *it )) + { + kdDebug( 179 ) << "increasing refcount: " << *it << endl; + if( icons[ *it ].ref()) + --old_icons_count; + continue; + } + kdWarning( 179 ) << "unknown icon in refIcons" << endl; + } + app_ref_deref( kapp->dcopClient()->senderId(), keys_P, true ); + } + =20 +void KIconServer::derefIcons( QValueList< QCString > keys_P ) + { + kdDebug( 179 ) << "derefIcons" << endl; + if( keys_P.empty()) + return; + for( QValueList< QCString >::ConstIterator it =3D keys_P.begin(); + it !=3D keys_P.end(); + ++it ) + { + if( icons.contains( *it )) + { + if( icons[ *it ].deref()) + kdDebug( 179 ) << "no longer in use: " << *it << endl; + continue; + } + kdWarning( 179 ) << "unknown icon in refIcons" << endl; + } + app_ref_deref( kapp->dcopClient()->senderId(), keys_P, false ); + } + =20 +void KIconServer::ageIcons() + { +// CHECKME TODO delat jen kdyz je ikon moc + bool flush =3D false; + for( IconsMap::Iterator it =3D icons.begin(); + it !=3D icons.end(); + ) + { + if( ( *it ).in_use()) + { + ++it; + continue; + } + if( ( *it ).age()) + { + kdDebug( 179 ) << "hiding icon:" << it.key() << endl; + ++old_icons_count; + flush =3D true; + } + if( ( *it ).too_old()) + { + kdDebug( 179 ) << "deleting icon:" << it.key() << endl; + --old_icons_count; + IconsMap::Iterator it2 =3D it; + ++it2; + icons.remove( it ); + it =3D it2; + continue; + } + ++it; + } + if( flush && !update_timer.isActive()) + update_timer.start( 10000, true ); // CHECKME 10 secs ? + } + +void KIconServer::app_reg( const QCString& app_id_P ) + { + for( AppRefList::ConstIterator it =3D app_ref_list.begin(); + it !=3D app_ref_list.end(); + ++it ) + if( ( *it ).app_id() =3D=3D app_id_P ) + return; + app_ref_list.prepend( KIconAppRef( app_id_P )); + } + =20 +void KIconServer::app_rem( const QCString& app_id_P ) + { + for( AppRefList::Iterator it =3D app_ref_list.begin(); + it !=3D app_ref_list.end(); + ++it ) + if( ( *it ).app_id() =3D=3D app_id_P ) + { + ( *it ).free( icons ); + app_ref_list.remove( it ); + return; + } +// CHECKME tady bude problem, kdyz aplikace udela dcop detach, ale zustane= bezet + } + =20 +void KIconServer::app_ren( const QCString& old_app_id_P, const QCString& n= ew_app_id_P ) + { + for( AppRefList::Iterator it =3D app_ref_list.begin(); + it !=3D app_ref_list.end(); + ++it ) + if( ( *it ).app_id() =3D=3D old_app_id_P ) + { + ( *it ).change_app_id( new_app_id_P ); + return; + } + } + +void KIconServer::app_ref_deref( const QCString& app_id_P, const QValueLis= t< QCString >& keys_P ,bool ref_P ) + { + for( AppRefList::Iterator it =3D app_ref_list.begin(); + it !=3D app_ref_list.end(); + ++it ) + { + if( ( *it ).app_id() =3D=3D app_id_P ) + { + kdDebug( 179 ) << "(de)ref-ing in " << app_id_P << endl; + if( ref_P ) + ( *it ).ref( keys_P ); + else + ( *it ).deref( keys_P ); + return; + } + } + if( ref_P ) + { + app_ref_list.prepend( KIconAppRef( app_id_P )); + app_ref_list.front().ref( keys_P ); + } + } + =20 +bool KIconData::ref() + { + bool ret =3D ( usage <=3D -5 ); + if( usage < 0 ) + usage =3D 1; + else + ++usage; + return ret; + } + =20 +#include "kiconserver.moc" Index: iconserver/configure.in.in =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- iconserver/configure.in.in (revis=C3=A3o 0) +++ iconserver/configure.in.in (revis=C3=A3o 0) @@ -0,0 +1,10 @@ +AC_TRY_COMPILE([], + [ + #ifdef HAVE_MMAP + return 0; + #else + return 1; + #endif + ], [ ICONSERVER_COMPILE=3Diconserver + AC_SUBST( ICONSERVER_COMPILE ) ] + ) Index: iconserver/appref.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- iconserver/appref.cpp (revis=C3=A3o 0) +++ iconserver/appref.cpp (revis=C3=A3o 0) @@ -0,0 +1,157 @@ +/*************************************************************************= *** + + $Id: iconserver.h,v 1.11 2001/08/29 15:25:38 bero Exp $ + + Copyright (C) 2001 Lubos Lunak + + This file is part of the KDE libraries + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +**************************************************************************= **/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "appref.h" + +#include + +KIconAppRef::KIconAppRef( const QCString& app_id_P ) + : _app_id( app_id_P ), arr( NULL ), used_size( 0 ), allocated_size( 0 ) + { + } + =20 +KIconAppRef::KIconAppRef( const KIconAppRef& src_P ) + : _app_id( src_P._app_id ), arr( src_P.arr ), used_size( src_P.used_si= ze ), + allocated_size( src_P.allocated_size ) + { + kdDebug( 174 ) << "copy (" << (void*)this << "<-" << (void*)&src_P << = ") :" << arr << endl; + src_P.arr =3D NULL; // copies will be created only when passing to QVa= lueList + } + =20 +KIconAppRef::~KIconAppRef() + { + kdDebug( 174 ) << "deleting (" << (void*)this << ") :" << (void*)arr <= < endl; + delete[] arr; + } + +void KIconAppRef::free( IconsMap& icons ) + { + for( KIconAppRefData* pos =3D arr; + pos !=3D arr + used_size; + ++pos ) + { + if( pos->key.isNull()) + continue; + KIconData& ref =3D icons[ pos->key ]; + kdDebug( 174 ) << "appderef: " << pos->key << endl; + for( int i =3D 0; + i < pos->count; + ++i ) + ref.deref(); + } + used_size =3D 0; + } + +void KIconAppRef::ref( const QValueList< QCString > keys_P ) + { + QValueList< QCString > keys( keys_P ); + qHeapSort( keys ); + resize( keys.count() + used_size ); + KIconAppRefData* pos =3D arr; + for( QValueList< QCString >::ConstIterator it =3D keys.begin(); + it !=3D keys.end(); + ++it ) + { + int dif; + kdDebug( 174 ) << "appref: " << *it << endl; + while(( dif =3D KIconAppRefData::cmp( pos->key, *it ) ) < 0 ) + ++pos; + if( dif =3D=3D 0 ) + ++pos->count; + else + { + arr[ used_size ].key =3D ( *it ); + arr[ used_size ].count =3D 1; + ++used_size; + } + } + qHeapSort( arr, arr + used_size ); + kdDebug( 174 ) << "KIconAppRef: refs : " << used_size << endl; + } + =20 +void KIconAppRef::deref( const QValueList< QCString > keys_P ) + { + QValueList< QCString > keys( keys_P ); + qHeapSort( keys ); + KIconAppRefData* pos =3D arr; + for( QValueList< QCString >::ConstIterator it =3D keys.begin(); + it !=3D keys.end(); + ++it ) + { + int dif; + while(( dif =3D KIconAppRefData::cmp( pos->key, *it )) < 0 ) + ++pos; + if( dif =3D=3D 0 ) + { + kdDebug( 174 ) << "appderef: " << pos->key << endl; + if( --pos->count =3D=3D 0 ) + { + pos->key =3D QCString(); + ++pos; // position after this one + } + } + else + kdDebug( 174 ) << "KIconAppRef::deref(): key not found:" << *i= t << endl; + } + qHeapSort( arr, arr + used_size ); + while( used_size > 0 && arr[ used_size - 1 ].key.isNull()) + --used_size; + kdDebug( 174 ) << "KIconAppRef: derefs : " << used_size << endl; + } + +void KIconAppRef::resize( unsigned int new_size_P ) + { + unsigned int old_size =3D allocated_size; + unsigned int new_size =3D old_size; + if( new_size =3D=3D 0 ) + new_size =3D 4; + while( new_size < new_size_P ) + new_size *=3D 2; + if( new_size =3D=3D old_size ) + return; + KIconAppRefData* new_arr =3D new KIconAppRefData[ new_size ]; + KIconAppRefData* src =3D arr; + KIconAppRefData* dst =3D new_arr; + while( old_size-- > 0 ) + *dst++ =3D *src++; + delete[] arr; + arr =3D new_arr; + allocated_size =3D new_size; + } + =20 +int KIconAppRefData::cmp( const QCString& l_P, const QCString& r_P ) + { + if( !l_P.isNull() && !r_P.isNull() ) + return strcmp( l_P, r_P ); + if( !l_P.isNull()) + return -1; // NULL keys go last, not first + if( !r_P.isNull()) + return 1; // NULL keys go last, not first + return 0; + } Index: kiconpixmap_p.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- kiconpixmap_p.h (revis=C3=A3o 0) +++ kiconpixmap_p.h (revis=C3=A3o 0) @@ -0,0 +1,94 @@ +/*************************************************************************= *** + + $Id: iconserver.h,v 1.11 2001/08/29 15:25:38 bero Exp $ + +**************************************************************************= **/ + +#ifndef __KICONPIXMAP_H +#define __KICONPIXMAP_H + +#include + +#include +#include + +#include + +#ifndef QT_NO_XRENDER // CHECKME +#include +#endif + +// CHECKME musi byt natvrdo na jedno nastaveno +#define KICON_SHARE_XRENDER + +class KDECORE_EXPORT KIconPixmap + : public QPixmap + { + public: + KIconPixmap( int w_P, int h_P, Pixmap pm_P, Pixmap mask_P, Pixmap = alpha_P +#ifdef KICON_SHARE_XRENDER + , Picture pic_P, Picture mask_pic_P, Picture alpha_pic_P +#endif + ); + const QPixmap* alpha() const; + }; + =20 +class KDECORE_EXPORT KIconBitmap + : public QBitmap + { + public: + KIconBitmap( int w_P, int h_P, Pixmap pixmap_P +#ifdef KICON_SHARE_XRENDER + , Picture pic_P +#endif + ); + }; + =20 +class KDECORE_EXPORT KIconAlpha + : public QPixmap + { + public: + KIconAlpha( int w_P, int h_P, Pixmap pixmap_P +#ifdef KICON_SHARE_XRENDER + , Picture pic_P +#endif + ); + }; + +class KDECORE_EXPORT KIconDataPixmap + : public QPixmap + { + public: =20 + KIconDataPixmap( const QPixmap& pm_P ); + KIconDataPixmap() {}; // for QValueList + const QPixmap* alpha() const; + Pixmap maskHandle() const; + Pixmap alphaHandle() const; +#ifdef KICON_SHARE_XRENDER + Picture maskX11RenderHandle() const; + Picture alphaX11RenderHandle() const; +#endif + }; + +// prevents freeing the X pixmap and XRender handle +class KDECORE_EXPORT KIconPixmapHolder + : public QPixmap + { + public: + KIconPixmapHolder(); + KIconPixmapHolder( const QPixmap& pm_P ); + KIconPixmapHolder& operator=3D( const QPixmap& pm_P ); + virtual ~KIconPixmapHolder(); + }; + +class KDECORE_EXPORT KIconSharedPixmap + : public QPixmap + { + public: + KIconSharedPixmap( const QCString& key_P, const QPixmap& pm_P ); + virtual ~KIconSharedPixmap(); + bool unused() const; + QCString key; + }; + +#endif Index: Makefile.am =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- Makefile.am (revis=C3=A3o 412784) +++ Makefile.am (c=C3=B3pia de trabalho) @@ -27,7 +27,7 @@ SVGICON_LIB=3Dsvgicons/libkdesvgicons.la endif =20 =2DSUBDIRS =3D malloc network $(SVGICONS) . kconfig_compiler tests +SUBDIRS =3D malloc network $(SVGICONS) . kconfig_compiler iconserver tests =20 # For the future: examine if condensing the tons of *_LDFLAGS variables # into $(all_libraries) isn't better @@ -81,7 +81,7 @@ kregpriv.h kshortcutmenu.h ksycocadict.h ksycocafactory.h netsupp.h \ kcheckaccelerators.h kcalendarsystemgregorian.h \ kcalendarsystemhijri.h kcalendarsystemhebrew.h kcalendarsystemjalali.h \ =2D kprotocolinfofactory.h + kprotocolinfofactory.h kiconserverclient_p.h kiconpixmap_p.h =20 libkdecore_la_SOURCES =3D libintl.cpp kapplication.cpp \ kdebug.cpp netwm.cpp kconfigbase.cpp kconfig.cpp ksimpleconfig.cpp \ @@ -112,7 +112,8 @@ kcalendarsystemfactory.cpp kmacroexpander.cpp kidna.cpp \ ktempdir.cpp kshell.cpp kmountpoint.cpp kcalendarsystemjalali.cpp \ kprotocolinfo_kdecore.cpp kprotocolinfofactory.cpp kxerrorhandler.cpp \ =2D kuser.cpp kconfigskeleton.cpp kconfigdialogmanager.cpp klockfile.cpp + kuser.cpp kconfigskeleton.cpp kconfigdialogmanager.cpp klockfile.cpp \ + kiconserverclient.cpp kiconserver.stub kiconserverclient_p.skel kiconp= ixmap.cpp =20 libkdecore_la_LDFLAGS =3D $(QT_LDFLAGS) $(KDE_RPATH) $(KDE_MT_LDFLAGS) $(X= _LDFLAGS) $(USER_LDFLAGS) -version-info 6:0:2 -no-undefined libkdecore_la_LIBADD =3D malloc/libklmalloc.la network/libkdecorenetwork.l= a $(SVGICON_LIB) ../dcop/libDCOP.la ../libltdl/libltdlc.la $(LIB_XEXT) $(LI= BRESOLV) $(LIBUTIL) $(LIBART_LIBS) $(LIB_IDN) ../kdefx/libkdefx.la @@ -124,6 +125,8 @@ =20 SRCDOC_DEST=3D$(kde_htmldir)/en/kdelibs/kdecore =20 +kiconserver_DIR =3D $(srcdir)/iconserver + kdebugdir =3D $(kde_confdir) kdebug_DATA =3D kdebug.areas kdebugrc language.codes =20 Index: kiconpixmap.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- kiconpixmap.cpp (revis=C3=A3o 0) +++ kiconpixmap.cpp (revis=C3=A3o 0) @@ -0,0 +1,322 @@ +/*************************************************************************= *** + + $Id: iconserver.h,v 1.11 2001/08/29 15:25:38 bero Exp $ + +**************************************************************************= **/ + +#warning license problem + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "kiconpixmap_p.h" + +#include +#include + +#ifndef QT_NO_XRENDER +#include +#endif + +extern bool qt_use_xrender; + +/* + The code here is based on QPixmap code from Qt (actually often just copy&= pasted). +*/ + +// Based on QPixmap::init() and QPixmap::setMask() +KIconPixmap::KIconPixmap( int w, int h, Pixmap pm_P, Pixmap mask_P, Pixmap= alpha_P +#ifdef KICON_SHARE_XRENDER + , Picture pic_P, Picture mask_pic_P, Picture alpha_pic_P +#endif + ) + : QPixmap( 0, 0, -1 ) +{ + data->w =3D w; + data->uninit =3D false; + data->h =3D h; + assert( pm_P !=3D None ); + hd =3D pm_P; + + +#ifndef QT_NO_XRENDER + if (qt_use_xrender) { +#ifdef KICON_SHARE_XRENDER + rendhd =3D pic_P; +#else + XRenderPictFormat *format =3D 0; + XRenderPictFormat req; + ulong mask =3D PictFormatType | PictFormatDepth; + + req.type =3D PictTypeDirect; + req.depth =3D data->d; + + if (data->d =3D=3D 1) { + req.direct.alpha =3D 0; + req.direct.alphaMask =3D 1; + mask |=3D PictFormatAlpha | PictFormatAlphaMask; + } else { + format =3D XRenderFindVisualFormat(x11Display(), (Visual *) x11Visual= ()); + } + + if (! format) + format =3D XRenderFindFormat(x11Display(), mask, &req, 0); + if (format) + rendhd =3D XRenderCreatePicture(x11Display(), hd, format, 0, 0); +#endif + } +#endif // QT_NO_XRENDER + + data->selfmask =3D FALSE; + if( mask_P !=3D None ) { + KIconBitmap* newmaskcopy; + newmaskcopy =3D new KIconBitmap( w, h, mask_P +#ifdef KICON_SHARE_XRENDER + , mask_pic_P +#endif + ); +#ifdef Q_WS_X11 + newmaskcopy->x11SetScreen( x11Screen() ); // CHECKME +#endif + data->mask =3D newmaskcopy; + } + + if( alpha_P !=3D None ) { =20 +#ifndef QT_NO_XRENDER + if (qt_use_xrender) { + KIconAlpha* alpha =3D new KIconAlpha( w, h, alpha_P +#ifdef KICON_SHARE_XRENDER + , alpha_pic_P +#endif + ); + data->alphapm =3D alpha; + } +#endif + } +} + +// Once again for bitmap + +// Based on QPixmap::init() +KIconBitmap::KIconBitmap( int w, int h, Pixmap pm_P +#ifdef KICON_SHARE_XRENDER + , Picture pic_P +#endif + ) + : QBitmap( 0, 0 ) +{ + data->uninit =3D false; + data->w =3D w; + data->h =3D h; + hd =3D pm_P; + +#ifndef QT_NO_XRENDER + if (qt_use_xrender) { +#ifdef KICON_SHARE_XRENDER + rendhd =3D pic_P; +#else + XRenderPictFormat *format =3D 0; + XRenderPictFormat req; + ulong mask =3D PictFormatType | PictFormatDepth; + + req.type =3D PictTypeDirect; + req.depth =3D data->d; + + if (data->d =3D=3D 1) { + req.direct.alpha =3D 0; + req.direct.alphaMask =3D 1; + mask |=3D PictFormatAlpha | PictFormatAlphaMask; + } else { + format =3D XRenderFindVisualFormat(x11Display(), (Visual *) x11Visual= ()); + } + + if (! format) + format =3D XRenderFindFormat(x11Display(), mask, &req, 0); + if (format) + rendhd =3D XRenderCreatePicture(x11Display(), hd, format, 0, 0); +#endif + } +#endif // QT_NO_XRENDER + +} + +// Once again for alpha pixmap + +// Based on QPixmap::convertFromImage() +KIconAlpha::KIconAlpha( int w, int h, Pixmap pm_P +#ifdef KICON_SHARE_XRENDER + , Picture pic_P +#endif + ) + : QPixmap( 0, 0, 8 ) +{ + data->uninit =3D false; +#ifndef QT_NO_XRENDER + if(qt_use_xrender) { + // setup pixmap data + data->w =3D w; + data->h =3D h; + + hd =3D pm_P; + =20 +#ifdef KICON_SHARE_XRENDER + rendhd =3D pic_P; +#else + XRenderPictFormat *format =3D 0; + XRenderPictFormat req; + ulong mask =3D PictFormatType | PictFormatDepth | PictFormatAlphaMask; + req.type =3D PictTypeDirect; + req.depth =3D 8; + req.direct.alphaMask =3D 0xff; + format =3D XRenderFindFormat(x11Display(), mask, &req, 0); + if (format) + rendhd =3D + XRenderCreatePicture(x11Display(), hd, format, 0, 0); +#endif + } +#endif // QT_NO_XRENDER +} + +KIconDataPixmap::KIconDataPixmap( const QPixmap& pm_P ) + : QPixmap( pm_P ) + { + } + =20 +Pixmap KIconDataPixmap::maskHandle() const + { + return mask() !=3D NULL ? mask()->handle() : None; + } + +Pixmap KIconDataPixmap::alphaHandle() const + { + return data->alphapm !=3D NULL ? data->alphapm->handle() : None; + } + +#ifdef KICON_SHARE_XRENDER +Picture KIconDataPixmap::maskX11RenderHandle() const + { + return mask() !=3D NULL ? mask()->x11RenderHandle() : None; + } + +Picture KIconDataPixmap::alphaX11RenderHandle() const + { + return data->alphapm !=3D NULL ? data->alphapm->x11RenderHandle() : No= ne; + } +#endif + +const QPixmap* KIconDataPixmap::alpha() const + { + return data->alphapm; + } + +const QPixmap* KIconPixmap::alpha() const + { + return data->alphapm; + } + +KIconPixmapHolder::KIconPixmapHolder() + { + } + =20 +// just attach to the shared QPixmapData, it doesn't matter if it's +// QPixmap or QBitmap +KIconPixmapHolder::KIconPixmapHolder( const QPixmap& pm_P ) + : QPixmap( pm_P ) + { + } + +// just attach to the shared QPixmapData, it doesn't matter if it's +// QPixmap or QBitmap +KIconPixmapHolder& KIconPixmapHolder::operator=3D( const QPixmap& pm_P ) + { + QPixmap::operator=3D( pm_P ); + return *this; + } + =20 +// based on QPixmap::deref() +KIconPixmapHolder::~KIconPixmapHolder() + { + if( data->count > 1 ) // if it's still in use + { + // it looks like most KDE apps don't delete their widgets, so comp= lain only if the app + // is not quiting + if( !QApplication::closingDown()) + fprintf( stderr, "KIconPixmapHolder: Cannot free pixmap holder= (count=3D=3D%d)\n", data->count );; + ++data->count; // prevent QPixmap from freeing the X pixmap + } + else { + if ( qApp && hd) { + +#ifndef QT_NO_XRENDER + if (rendhd) { +#ifndef KICON_SHARE_XRENDER + XRenderFreePicture(x11Display(), rendhd); +#endif + rendhd =3D 0; + } +#endif // QT_NO_XRENDER + + hd =3D 0; + } + } + } + +KIconSharedPixmap::KIconSharedPixmap( const QCString& key_P, const QPixmap= & pm_P ) + : QPixmap( pm_P ), key( key_P ) + { + } + +class QPixmapDataHack + : public QBitmap + { + public: + bool unused() const { return data->count =3D=3D 1; } + }; + =20 +bool KIconSharedPixmap::unused() const + { + return data->count =3D=3D 1 + && ( data->mask =3D=3D NULL || static_cast< QPixmapDataHack* >( da= ta->mask )->unused() =3D=3D 1 ) + && ( data->alphapm =3D=3D NULL || static_cast< QPixmapDataHack* >(= data->alphapm )->unused() =3D=3D 1 ); + } + =20 +KIconSharedPixmap::~KIconSharedPixmap() + { + if( !unused()) // if it's still in use + { + // it looks like most KDE apps don't delete their widgets, so comp= lain only if the app + // is not quiting + if( !QApplication::closingDown()) + fprintf( stderr, "KIconSharedPixmap: Cannot free pixmap holder= (count=3D=3D%d)\n", data->count );; + ++data->count; // prevent QPixmap from freeing the X pixmaps + return; + } + if( data->alphapm !=3D NULL ) + { + KIconPixmapHolder hold( *data->alphapm ); + delete data->alphapm; + data->alphapm =3D NULL; + } + if( data->mask !=3D NULL ) + { + KIconPixmapHolder hold( *data->mask ); + delete data->mask; + data->mask =3D NULL; + } + if ( qApp && hd) { + +#ifndef QT_NO_XRENDER + if (rendhd) { +#ifndef KICON_SHARE_XRENDER + XRenderFreePicture(x11Display(), rendhd); +#endif + rendhd =3D 0; + } +#endif // QT_NO_XRENDER + + hd =3D 0; + } + } Index: kiconloader.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- kiconloader.cpp (revis=C3=A3o 412784) +++ kiconloader.cpp (c=C3=B3pia de trabalho) @@ -36,6 +36,7 @@ #include #include #include +#include =20 #include #include //for abs @@ -134,6 +135,7 @@ QPtrList links; bool extraDesktopIconsLoaded :1; bool delayedLoading :1; + KIconServerClient* iconClient; }; =20 #define KICONLOADER_CHECKS @@ -197,6 +199,21 @@ else d->mpDirs =3D KGlobal::dirs(); =20 + d->iconClient =3D NULL; + if( d->mpDirs =3D=3D KGlobal::dirs()) + { + KConfigGroupSaver saver( KGlobal::config(), "Icons" ); + if( KGlobal::config()->readBoolEntry( "UseIconServer", true )) + { + d->iconClient =3D new KIconServerClient; + if( !d->iconClient->isActive()) // some startup problem + { + delete d->iconClient; + d->iconClient =3D NULL; + } + } + } + =20 // If this is unequal to 0, the iconloader is initialized // successfully. d->mpThemeRoot =3D 0L; @@ -292,6 +309,7 @@ deleted when the elements of d->links are deleted */ d->mpThemeRoot=3D0; delete[] d->mpGroups; + delete d->iconClient; delete d; } =20 @@ -687,31 +705,20 @@ } favIconOverlay =3D favIconOverlay && size > 22; =20 =2D // Generate a unique cache key for the icon. =2D =2D key =3D "$kico_"; =2D key +=3D name; key +=3D '_'; =2D key +=3D QString::number(size); key +=3D '_'; =2D =2D QString overlayStr =3D QString::number( overlay ); =2D =2D QString noEffectKey =3D key + '_' + overlayStr; =2D =2D if (group >=3D 0) =2D { =2D key +=3D d->mpEffect.fingerprint(group, state); =2D if (d->mpGroups[group].dblPixels) =2D key +=3D QString::fromLatin1(":dblsize"); =2D } else =2D key +=3D QString::fromLatin1("noeffect"); =2D key +=3D '_'; =2D key +=3D overlayStr; =2D + QString noEffectKey; + key =3D makeKey( name, group, size, state | overlay, noEffectKey ); + =20 // Is the icon in the cache? bool inCache =3D QPixmapCache::find(key, pix); if (inCache && (path_store =3D=3D 0L)) return pix; =20 + if( d->iconClient && d->iconClient->iconServerCheck( key, pix )) + { + QPixmapCache::insert(key, pix); + return pix; + } + =20 QImage *img =3D 0; int iconType; int iconThreshold; @@ -736,7 +743,7 @@ { // Try "User" icon too. Some apps expect this. if (!name.isEmpty()) =2D pix =3D loadIcon(name, KIcon::User, size, state, pat= h_store, true); + pix =3D loadIcon(name, KIcon::User, size, state | over= lay, path_store, true); if (!pix.isNull() || canReturnNull) return pix; =20 @@ -870,9 +877,39 @@ } =20 QPixmapCache::insert(key, pix); + =20 + if( d->iconClient ) + d->iconClient->iconServerAdd( key, pix, group, state | overlay ); + =20 return pix; } =20 +QString KIconLoader::makeKey( const QString& name, int group, int size, in= t state, + QString& noEffectKey ) const +{ + int overlay =3D (state & KIcon::OverlayMask); + state &=3D ~KIcon::OverlayMask; + + QString key =3D "$kico_"; + key +=3D name; key +=3D ':'; + key +=3D QString::number(size); key +=3D '_'; + + QString overlayStr =3D QString::number( overlay ); + + noEffectKey =3D key + '_' + overlayStr; + + if (group >=3D 0) + { + key +=3D d->mpEffect.fingerprint(group, state); + if (d->mpGroups[group].dblPixels) + key +=3D QString::fromLatin1(":dblsize"); + } else + key +=3D QString::fromLatin1("noeffect"); + key +=3D '_'; + key +=3D overlayStr; + return key; + } + QImage *KIconLoader::loadOverlay(const QString &name, int size) const { QString key =3D name + '_' + QString::number(size); Index: kiconserverstructs.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- kiconserverstructs.h (revis=C3=A3o 0) +++ kiconserverstructs.h (revis=C3=A3o 0) @@ -0,0 +1,71 @@ +#ifndef KICONSERVERSTRUCTS_H +#define KICONSERVERSTRUCTS_H + +struct KIconFileEntry + { + int key_ref; + Pixmap xid; + Pixmap mask_xid; + Pixmap alpha_xid; +#ifdef KICON_SHARE_XRENDER + Picture pic; + Picture mask_pic; + Picture alpha_pic; +#endif + int size; + int group; + int state; + }; + =20 +struct KIconsFile + { + int version; + int depth; + int count; + KIconFileEntry entries[ 1 ]; // will grow + }; // + keys + =20 +const int KICONSFILEVERSION =3D 1; + +// KIconLoader saves these for sending them to iconserver later +struct KIconNewData + { + KIconNewData( const QString& key_P, const QPixmap& pix_P, int group_P,= int state_P ); + KIconNewData() {}; // for QValueList + QString key; + KIconDataPixmap pix; + int group; + int state; + }; + +typedef QValueList< KIconNewData > KIconNewDataList; + +inline +KIconNewData::KIconNewData( const QString& key_P, const QPixmap& pix_P, in= t group_P, int state_P ) + : key( key_P ), pix( pix_P ), group( group_P ), state( state_P ) + { + } + +// for the newIcons DCOP call +struct KIconSendData + { + KIconSendData( const KIconNewData& data_P ); + KIconSendData() {}; // for QValueList + QCString key; + Pixmap xid; + Pixmap mask_xid; + Pixmap alpha_xid; +#ifdef KICON_SHARE_XRENDER + Picture pic; + Picture mask_pic; + Picture alpha_pic; +#endif + int size; + int group; + int state; + }; + =20 +KDECORE_EXPORT QDataStream& operator<<( QDataStream& stream_P, const KIcon= SendData& data_P ); +KDECORE_EXPORT QDataStream& operator>>( QDataStream& stream_P, KIconSendDa= ta& data_P ); + +#endif Index: kiconloader.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- kiconloader.h (revis=C3=A3o 412784) +++ kiconloader.h (c=C3=B3pia de trabalho) @@ -337,6 +337,13 @@ bool isDelayedIconSetLoadingEnabled() const; =20 =20 + /** + * Generate a unique cache key for the icon. + * @internal + */ + QString makeKey( const QString& name, int group, int size, int state, + QString& noEffectKey ) const; + private: /** * @internal Index: kiconserverclient_p.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- kiconserverclient_p.h (revis=C3=A3o 0) +++ kiconserverclient_p.h (revis=C3=A3o 0) @@ -0,0 +1,92 @@ +/*************************************************************************= *** + + $Id: iconserver.h,v 1.11 2001/08/29 15:25:38 bero Exp $ + + Copyright (C) 2001 Lubos Lunak + + This file is part of the KDE libraries + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +**************************************************************************= **/ + +#ifndef __KICONSERVERCLIENT_H +#define __KICONSERVERCLIENT_H + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +class QFile; + +// int: count +// *count : int xid +// int key_ref +// *count : char[] key + + +typedef QValueList< KIconSendData > KIconSendDataList; + +class KIconSharedPixmap; + +class KDECORE_EXPORT KIconServerClient + : public QObject, public DCOPObject + { + Q_OBJECT + K_DCOP + k_dcop: + void iconsFileChanged( bool serverRunning ); + public: + KIconServerClient(); + virtual ~KIconServerClient(); + bool iconServerCheck( const QString& key_P, QPixmap& pix_O ); + void iconServerAdd( const QString& key_P, QPixmap& pix_P, int grou= p_P, int state_P ); + bool isActive() const; + private: + bool openIconsFile(); + void closeIconsFile(); + bool iconServerRunning(); + private slots: + void sendIconsToServer(); =20 + void refDerefIcons(); + void checkUnusedIcons(); + private: + static void init_icons_holder(); + static void finish_icons_holder(); + bool active; + const KIconsFile* icons_mmap; + int icons_size; + QFile* icons_file; + QTimer send_timer; + QTimer ref_timer; + QTimer unused_check_timer; + KIconNewDataList icons_send; + QValueList< QCString > ref_icons; + QValueList< QCString > deref_icons; + static QValueList< KIconSharedPixmap* >* icons_holder; // CHECKME = static ? + }; + +#endif Index: kdebug.areas =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- kdebug.areas (revis=C3=A3o 412784) +++ kdebug.areas (c=C3=B3pia de trabalho) @@ -22,6 +22,7 @@ 176 kdecore (KWin) 177 kdecore (KConfigSkeleton) 178 kdecore (KConfigDialogManager) +179 kdecore (KIconServer) 180 kdecore (kdelibs) 200 kdeui (KMainWindow) 220 kdeui (KToolBar) Index: kiconserverclient.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- kiconserverclient.cpp (revis=C3=A3o 0) +++ kiconserverclient.cpp (revis=C3=A3o 0) @@ -0,0 +1,345 @@ +/*************************************************************************= *** + + $Id: iconserver.h,v 1.11 2001/08/29 15:25:38 bero Exp $ + + Copyright (C) 2001 Lubos Lunak + + This file is part of the KDE libraries + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +**************************************************************************= **/ + +//#define NDEBUG +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +#include + +#include + +#include "kiconserverclient_p.h" +#include "kiconpixmap_p.h" + + +// CHECKME co to bude delat na multihead, bude to fungovat ? + +KIconServerClient::KIconServerClient() + : DCOPObject( "iconserverclient" ), active( false ), icons_mmap( NULL ) + // co kdyz budou dva klienti ? + { +// CHECKME tohle asi nebude fungovat s multihead !? ( ruzne bpp ) +// shared_icons.setAutoDelete( true ); // CHECKME + KConfigGroupSaver saver( KGlobal::config(), "Icons" ); + if( !KGlobal::config()->readBoolEntry( "UseIconServer", true )) + return; + if( !kapp->dcopClient()->isAttached()) // apps usually automatically r= egister with DCOP, + return; // so if this one has it turned= off, don't attach either + KIconServer_stub stub( "iconserver", "iconserver" ); // CHECKME kded ? + bool ok =3D stub.serverRunning() && stub.ok(); +// CHECKME jen lokalni iconserver ?? + if( !ok ) + { + kdDebug( 174 ) << "no icon server available" << endl; + return; + } + if( !openIconsFile()) + return; + connect( &send_timer, SIGNAL( timeout()), this, SLOT( sendIconsToServe= r())); + connect( &ref_timer, SIGNAL( timeout()), this, SLOT( refDerefIcons())); + connect( &unused_check_timer, SIGNAL( timeout()), this, SLOT( checkUnu= sedIcons())); + unused_check_timer.start( 30000 ); // CHECKME 30s ? + active =3D true; + } + =20 +KIconServerClient::~KIconServerClient() + { + closeIconsFile(); + } + =20 +bool KIconServerClient::openIconsFile() + { +#ifndef HAVE_MMAP + return false; // sorry +#else + Q_ASSERT( icons_mmap =3D=3D NULL ); + QString path =3D KGlobal::dirs()->saveLocation("tmp") + "kiconsfile-" = + getenv( "DISPLAY" ); + icons_file =3D new QFile( path ); + if( !icons_file->open( IO_ReadOnly )) + { + delete icons_file; + return false; + } + icons_size =3D icons_file->size(); + icons_mmap =3D reinterpret_cast< KIconsFile* >( mmap( 0, icons_size, + PROT_READ, MAP_PRIVATE, icons_file->handle(), 0 )); + if( icons_mmap =3D=3D NULL ) + { + kdDebug( 174 ) << "mmap failed. (length =3D " << icons_size << ")"= << endl; + delete icons_file; + return false; // sorry + } + if( icons_mmap->version !=3D KICONSFILEVERSION ) + { + kdDebug( 174 ) << "icons file version doesn't match (found " << ic= ons_mmap->version + << ", expected " << KICONSFILEVERSION << ")" << endl; + closeIconsFile(); + return false; + } + if( icons_mmap->depth !=3D QPixmap::defaultDepth()) + { + kdDebug( 174 ) << "icons file depth doesn't match (found " << icon= s_mmap->depth + << ", depth is " << QPixmap::defaultDepth() << ")" << endl; + closeIconsFile(); + return false; + } + return true; +#endif + } + =20 +void KIconServerClient::closeIconsFile() + { + if( icons_mmap =3D=3D NULL ) + return; =20 +#ifdef HAVE_MMAP + munmap( (char*) icons_mmap, icons_size ); + icons_mmap =3D NULL; + delete icons_file; +#endif + } + +bool KIconServerClient::iconServerCheck( const QString& key_P, QPixmap& pi= x_O ) + { + if( !active ) + return false; +#if 0 + kdDebug( 174 ) << "checking for \"" << key_P << "\" icon in iconserver= " <count - 1; + QCString key =3D key_P.utf8(); + int index =3D -1; + while( min <=3D max ) + { + int pos =3D ( min + max ) / 2; + const char* pos_key =3D reinterpret_cast< const char* >( icons_mma= p ) + + icons_mmap->entries[ pos ].key_ref; + int dif =3D qstrcmp( key, pos_key ); + if( dif < 0 ) + max =3D pos - 1; + else if( dif > 0 ) + min =3D pos + 1; + else // key =3D=3D pos_key + { + index =3D pos; + break; + } + } + if( index < 0 ) + return false; + const KIconFileEntry& data =3D icons_mmap->entries[ index ]; +#if 0 + kdDebug( 174 ) << "getting icon from iconserver: " << data.xid << "/" + << data.mask_xid << "/" << data.alpha_xid << endl; +#endif +#ifdef KICON_SHARE_XRENDER +#if 0 + kdDebug( 174 ) << "pics: " << data.pic << "/" << data.mask_pic << "/" = << data.alpha_pic << endl; +#endif +#endif + KIconPixmap pix( data.size, data.size, data.xid, + data.mask_xid, data.alpha_xid +#ifdef KICON_SHARE_XRENDER + , data.pic, data.mask_pic, data.alpha_pic +#endif + ); + pix_O =3D pix; + init_icons_holder(); + icons_holder->prepend( new KIconSharedPixmap( key, pix )); + ref_icons.prepend( key ); + if( !ref_timer.isActive()) + ref_timer.start( 10000, true ); // CHECKME 10 sec ? + return true; + } + +void KIconServerClient::iconServerAdd( const QString& key_P, QPixmap& pix_= P, int group_P, int state_P ) + { + if( !active ) + return; + if( pix_P.width() !=3D pix_P.height()) + { + kdWarning( 174 ) << "icon \"" << key_P << "\" has size " + << pix_P.width() << "x" << pix_P.height() << endl; + return; + } + icons_send.append( KIconNewData( key_P, pix_P, group_P, state_P )); + if( !send_timer.isActive()) + send_timer.start( 10000, true ); // CHECKME 10 sec ? + } + +void KIconServerClient::sendIconsToServer() + { + if( icons_send.empty()) + return; + kdDebug( 174 ) << "sending icons to icon server" << endl; + KIconSendDataList send_data; + for( KIconNewDataList::ConstIterator it =3D icons_send.begin(); + it !=3D icons_send.end(); + ++it ) + { + send_data.append( KIconSendData( *it )); + KIconDataPixmap pix( ( *it ).pix ); +#if 0 + kdDebug( 174 ) << "sending icon \"" << ( *it ).key << "\"" << endl; +#endif + init_icons_holder(); + icons_holder->prepend( new KIconSharedPixmap( ( *it ).key.utf8(), = pix )); // CHECKME utf8 ? + } + KIconServer_stub stub( "iconserver", "iconserver" ); // CHECKME kded ? + stub.newIcons( send_data ); =20 + // CHECKME tohle dole az s delay, at si stihne iconserver vsechno prec= ist + // nebo kdyby tahle app spadla + icons_send.clear(); + } + +void KIconServerClient::iconsFileChanged( bool server_running_P ) + { + if( !active ) + return; + if( server_running_P ) + { + kdDebug( 174 ) << "reloading index file" << endl; + closeIconsFile(); + if( !openIconsFile()) + active =3D false; + } + else + { + kdDebug( 174 ) << "shutting down icon client" << endl; + closeIconsFile(); + active =3D false; + } + } + =20 +void KIconServerClient::refDerefIcons() + { + KIconServer_stub stub( "iconserver", "iconserver" ); // CHECKME kded ? + if( !ref_icons.empty()) + { + stub.refIcons( ref_icons ); =20 + ref_icons.clear(); + } + if( !deref_icons.empty()) + { + stub.derefIcons( deref_icons ); =20 + deref_icons.clear(); + } + } + +void KIconServerClient::checkUnusedIcons() + { + if( icons_holder =3D=3D NULL ) + return; + for( QValueList< KIconSharedPixmap* >::Iterator it =3D icons_holder->b= egin(); + it !=3D icons_holder->end(); + ) + { + if( ( *it )->unused()) + { + deref_icons.prepend( ( *it )->key ); + if( !ref_timer.isActive()) + ref_timer.start( 10000, true ); // CHECKME 10 sec ? + delete *it; // must delete manually (QValueList is used) + it =3D icons_holder->remove( it ); + continue; + } + ++it; + } + } + =20 +bool KIconServerClient::isActive() const + { + return active; + } + =20 +QDataStream& operator<<( QDataStream& stream_P, const KIconSendData& data_= P ) + { + return stream_P << data_P.key << data_P.xid << data_P.mask_xid << data= _P.alpha_xid +#ifdef KICON_SHARE_XRENDER + << data_P.pic << data_P.mask_pic << data_P.alpha_pic +#endif + << data_P.size << data_P.group << data_P.state; + } + =20 +QDataStream& operator>>( QDataStream& stream_P, KIconSendData& data_P ) + { + return stream_P >> data_P.key >> data_P.xid >> data_P.mask_xid >> data= _P.alpha_xid +#ifdef KICON_SHARE_XRENDER + >> data_P.pic >> data_P.mask_pic >> data_P.alpha_pic +#endif + >> data_P.size >> data_P.group >> data_P.state; + } + +KIconSendData::KIconSendData( const KIconNewData& data_P ) + : key( data_P.key.utf8()), + xid( data_P.pix.handle()), + mask_xid( data_P.pix.maskHandle()), + alpha_xid( data_P.pix.alphaHandle()), +#ifdef KICON_SHARE_XRENDER + pic( data_P.pix.x11RenderHandle()), + mask_pic( data_P.pix.maskX11RenderHandle()), + alpha_pic( data_P.pix.alphaX11RenderHandle()), +#endif + size( data_P.pix.width()), + group( data_P.group ), + state( data_P.state ) + { + } + +// asi mit i nejake casove cisteni +QValueList< KIconSharedPixmap* >* KIconServerClient::icons_holder =3D NULL; + +void KIconServerClient::init_icons_holder() + { + if( icons_holder !=3D NULL ) + return; + icons_holder =3D new QValueList< KIconSharedPixmap* >; + qAddPostRoutine( finish_icons_holder ); + } + +void KIconServerClient::finish_icons_holder() + { + if( icons_holder =3D=3D NULL ) + return; + delete icons_holder; + icons_holder =3D NULL; + } + =20 +#include "kiconserverclient_p.moc" --Boundary-01=_4ytrC25StuwCmTW-- --nextPart8292681.OIEt6Ki1OR Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQBCrtzJZQYlDr5VjykRAsCBAJ9OM1F687HZifbGx0vkgST8ZjO6KQCbBeOG WFnoU7sJAm4VE7zWwWRrAcg= =VTUE -----END PGP SIGNATURE----- --nextPart8292681.OIEt6Ki1OR--