KDEUI
kapplication_win.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of the KDE libraries 00003 Copyright (C) 2004-2008 Jarosław Staniek <staniek@kde.org> 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 version 2 as published by the Free Software Foundation. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include <QtGui/QApplication> 00021 #include <kstandarddirs.h> 00022 #include <klocale.h> 00023 #include <kwindowsystem.h> 00024 00025 #include <QTranslator> 00026 #include <QLocale> 00027 #include <QLibraryInfo> 00028 #include <QLibrary> 00029 00030 #include <stdio.h> 00031 00043 void KApplication_init_windows() 00044 { 00045 //QString qt_transl_file = ::locate( "locale", KGlobal::locale()->language() 00046 // + "/LC_MESSAGES/qt_" + KGlobal::locale()->language() + ".qm" ); 00047 00048 QString qt_transl_file = QString("qt_") + QLocale::system().name(); 00049 qt_transl_file.truncate(5); 00050 QTranslator *qt_transl = new QTranslator(); 00051 if (qt_transl->load( qt_transl_file, 00052 QLibraryInfo::location(QLibraryInfo::TranslationsPath))) 00053 qApp->installTranslator( qt_transl ); 00054 else 00055 delete qt_transl; 00056 00057 // For apps like KMail which have lots of open files, the default is too low 00058 // so increase it to the maximum. 00059 #ifndef _WIN32_WCE 00060 _setmaxstdio(2048); 00061 #endif 00062 00063 } 00064 00065 // <copy of kdepim/libkdepim/utils.cpp, TODO: move to a shared helper library> 00066 00067 #include <windows.h> 00068 #include <winperf.h> 00069 #include <psapi.h> 00070 #include <signal.h> 00071 #include <unistd.h> 00072 00073 #include <QtCore/QList> 00074 #include <QtCore/QtDebug> 00075 00076 static PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData ) 00077 { 00078 return (PPERF_OBJECT_TYPE)((PBYTE)PerfData + PerfData->HeaderLength); 00079 } 00080 00081 static PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj ) 00082 { 00083 return (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfObj + PerfObj->DefinitionLength); 00084 } 00085 00086 static PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj ) 00087 { 00088 return (PPERF_OBJECT_TYPE)((PBYTE)PerfObj + PerfObj->TotalByteLength); 00089 } 00090 00091 static PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj ) 00092 { 00093 return (PPERF_COUNTER_DEFINITION) ((PBYTE)PerfObj + PerfObj->HeaderLength); 00094 } 00095 00096 static PPERF_INSTANCE_DEFINITION NextInstance( PPERF_INSTANCE_DEFINITION PerfInst ) 00097 { 00098 PPERF_COUNTER_BLOCK PerfCntrBlk 00099 = (PPERF_COUNTER_BLOCK)((PBYTE)PerfInst + PerfInst->ByteLength); 00100 return (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfCntrBlk + PerfCntrBlk->ByteLength); 00101 } 00102 00103 static PPERF_COUNTER_DEFINITION NextCounter( PPERF_COUNTER_DEFINITION PerfCntr ) 00104 { 00105 return (PPERF_COUNTER_DEFINITION)((PBYTE)PerfCntr + PerfCntr->ByteLength); 00106 } 00107 00108 static PPERF_COUNTER_BLOCK CounterBlock(PPERF_INSTANCE_DEFINITION PerfInst) 00109 { 00110 return (PPERF_COUNTER_BLOCK) ((LPBYTE) PerfInst + PerfInst->ByteLength); 00111 } 00112 00113 #define GETPID_TOTAL 64 * 1024 00114 #define GETPID_BYTEINCREMENT 1024 00115 #define GETPID_PROCESS_OBJECT_INDEX 230 00116 #define GETPID_PROC_ID_COUNTER 784 00117 00118 QString fromWChar(const wchar_t *string, int size = -1) 00119 { 00120 return (sizeof(wchar_t) == sizeof(QChar)) ? QString::fromUtf16((ushort *)string, size) 00121 : QString::fromUcs4((uint *)string, size); 00122 } 00123 00124 #ifndef _WIN32_WCE 00125 void KApplication_getProcessesIdForName( const QString& processName, QList<int>& pids ) 00126 { 00127 qDebug() << "KApplication_getProcessesIdForName" << processName; 00128 PPERF_OBJECT_TYPE perfObject; 00129 PPERF_INSTANCE_DEFINITION perfInstance; 00130 PPERF_COUNTER_DEFINITION perfCounter, curCounter; 00131 PPERF_COUNTER_BLOCK counterPtr; 00132 DWORD bufSize = GETPID_TOTAL; 00133 PPERF_DATA_BLOCK perfData = (PPERF_DATA_BLOCK) malloc( bufSize ); 00134 00135 char key[64]; 00136 sprintf(key,"%d %d", GETPID_PROCESS_OBJECT_INDEX, GETPID_PROC_ID_COUNTER); 00137 LONG lRes; 00138 while( (lRes = RegQueryValueExA( HKEY_PERFORMANCE_DATA, 00139 key, 00140 NULL, 00141 NULL, 00142 (LPBYTE) perfData, 00143 &bufSize )) == ERROR_MORE_DATA ) 00144 { 00145 // get a buffer that is big enough 00146 bufSize += GETPID_BYTEINCREMENT; 00147 perfData = (PPERF_DATA_BLOCK) realloc( perfData, bufSize ); 00148 } 00149 00150 // Get the first object type. 00151 perfObject = FirstObject( perfData ); 00152 00153 // Process all objects. 00154 for( uint i = 0; i < perfData->NumObjectTypes; i++ ) { 00155 if (perfObject->ObjectNameTitleIndex != GETPID_PROCESS_OBJECT_INDEX) { 00156 perfObject = NextObject( perfObject ); 00157 continue; 00158 } 00159 pids.clear(); 00160 perfCounter = FirstCounter( perfObject ); 00161 perfInstance = FirstInstance( perfObject ); 00162 // retrieve the instances 00163 qDebug() << "INSTANCES: " << perfObject->NumInstances; 00164 for( int instance = 0; instance < perfObject->NumInstances; instance++ ) { 00165 curCounter = perfCounter; 00166 const QString foundProcessName( 00167 fromWChar( (wchar_t *)( (PBYTE)perfInstance + perfInstance->NameOffset ) ) ); 00168 qDebug() << "foundProcessName: " << foundProcessName; 00169 if ( foundProcessName == processName ) { 00170 // retrieve the counters 00171 for( uint counter = 0; counter < perfObject->NumCounters; counter++ ) { 00172 if (curCounter->CounterNameTitleIndex == GETPID_PROC_ID_COUNTER) { 00173 counterPtr = CounterBlock(perfInstance); 00174 DWORD *value = (DWORD*)((LPBYTE) counterPtr + curCounter->CounterOffset); 00175 pids.append( int( *value ) ); 00176 qDebug() << "found PID: " << int( *value ); 00177 break; 00178 } 00179 curCounter = NextCounter( curCounter ); 00180 } 00181 } 00182 perfInstance = NextInstance( perfInstance ); 00183 } 00184 } 00185 free(perfData); 00186 RegCloseKey(HKEY_PERFORMANCE_DATA); 00187 } 00188 00189 bool KApplication_otherProcessesExist( const QString& processName ) 00190 { 00191 QList<int> pids; 00192 KApplication_getProcessesIdForName( processName, pids ); 00193 int myPid = getpid(); 00194 foreach ( int pid, pids ) { 00195 if (myPid != pid) { 00196 // kDebug() << "Process ID is " << pid; 00197 return true; 00198 } 00199 } 00200 return false; 00201 } 00202 00203 bool KApplication_killProcesses( const QString& processName ) 00204 { 00205 QList<int> pids; 00206 KApplication_getProcessesIdForName( processName, pids ); 00207 if ( pids.empty() ) 00208 return true; 00209 qWarning() << "Killing process \"" << processName << " (pid=" << pids[0] << ").."; 00210 int overallResult = 0; 00211 foreach( int pid, pids ) { 00212 int result = kill( pid, SIGTERM ); 00213 if ( result == 0 ) 00214 continue; 00215 result = kill( pid, SIGKILL ); 00216 if ( result != 0 ) 00217 overallResult = result; 00218 } 00219 return overallResult == 0; 00220 } 00221 00222 struct EnumWindowsStruct 00223 { 00224 EnumWindowsStruct() : windowId( 0 ) {} 00225 int pid; 00226 HWND windowId; 00227 }; 00228 00229 BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam ) 00230 { 00231 if ( GetWindowLong( hwnd, GWL_STYLE ) & WS_VISIBLE ) { 00232 DWORD pidwin; 00233 GetWindowThreadProcessId(hwnd, &pidwin); 00234 if ( pidwin == ((EnumWindowsStruct*)lParam)->pid ) { 00235 ((EnumWindowsStruct*)lParam)->windowId = hwnd; 00236 return false; 00237 } 00238 } 00239 return true; 00240 } 00241 00242 void KApplication_activateWindowForProcess( const QString& executableName ) 00243 { 00244 QList<int> pids; 00245 KApplication_getProcessesIdForName( executableName, pids ); 00246 int myPid = getpid(); 00247 int foundPid = 0; 00248 foreach ( int pid, pids ) { 00249 if (myPid != pid) { 00250 qDebug() << "activateWindowForProcess(): PID to activate:" << pid; 00251 foundPid = pid; 00252 break; 00253 } 00254 } 00255 if ( foundPid == 0 ) 00256 return; 00257 EnumWindowsStruct winStruct; 00258 winStruct.pid = foundPid; 00259 EnumWindows( EnumWindowsProc, (LPARAM)&winStruct ); 00260 if ( winStruct.windowId == NULL ) 00261 return; 00262 KWindowSystem::forceActiveWindow( winStruct.windowId, 0 ); 00263 } 00264 #endif 00265 00266 // </copy>
KDE 4.6 API Reference