You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
3.5 KiB
80 lines
3.5 KiB
/*
|
|
* Copyright (C) 2013 Open Education Foundation
|
|
*
|
|
* Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
|
|
* l'Education Numérique en Afrique (GIP ENA)
|
|
*
|
|
* This file is part of OpenBoard.
|
|
*
|
|
* OpenBoard is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, version 3 of the License,
|
|
* with a specific linking exception for the OpenSSL project's
|
|
* "OpenSSL" library (or with modified versions of it that use the
|
|
* same license as the "OpenSSL" library).
|
|
*
|
|
* OpenBoard 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with OpenBoard. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
|
|
|
|
#import <Carbon/Carbon.h>
|
|
#import <dlfcn.h>
|
|
|
|
/*
|
|
* Returns an array of CFDictionaryRef types, each of which contains information about one of the processes.
|
|
* The processes are ordered in front to back, i.e. in the same order they appear when typing command + tab, from left to right.
|
|
* See the ProcessInformationCopyDictionary function documentation for the keys used in the dictionaries.
|
|
* If something goes wrong, then this function returns NULL.
|
|
*/
|
|
CFArrayRef CopyLaunchedApplicationsInFrontToBackOrder(void)
|
|
{
|
|
CFArrayRef (*_LSCopyApplicationArrayInFrontToBackOrder)(uint32_t sessionID) = NULL;
|
|
void (*_LSASNExtractHighAndLowParts)(void const* asn, UInt32* psnHigh, UInt32* psnLow) = NULL;
|
|
CFTypeID (*_LSASNGetTypeID)(void) = NULL;
|
|
|
|
void *lsHandle = dlopen("/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/LaunchServices", RTLD_LAZY);
|
|
if (!lsHandle) { return NULL; }
|
|
|
|
_LSCopyApplicationArrayInFrontToBackOrder = (CFArrayRef(*)(uint32_t))dlsym(lsHandle, "_LSCopyApplicationArrayInFrontToBackOrder");
|
|
_LSASNExtractHighAndLowParts = (void(*)(void const*, UInt32*, UInt32*))dlsym(lsHandle, "_LSASNExtractHighAndLowParts");
|
|
_LSASNGetTypeID = (CFTypeID(*)(void))dlsym(lsHandle, "_LSASNGetTypeID");
|
|
|
|
if (_LSCopyApplicationArrayInFrontToBackOrder == NULL || _LSASNExtractHighAndLowParts == NULL || _LSASNGetTypeID == NULL) { return NULL; }
|
|
|
|
CFMutableArrayRef orderedApplications = CFArrayCreateMutable(kCFAllocatorDefault, 64, &kCFTypeArrayCallBacks);
|
|
if (!orderedApplications) { return NULL; }
|
|
|
|
CFArrayRef apps = _LSCopyApplicationArrayInFrontToBackOrder(-1);
|
|
if (!apps) { CFRelease(orderedApplications); return NULL; }
|
|
|
|
CFIndex count = CFArrayGetCount(apps);
|
|
for (CFIndex i = 0; i < count; i++)
|
|
{
|
|
ProcessSerialNumber psn = {0, kNoProcess};
|
|
CFTypeRef asn = CFArrayGetValueAtIndex(apps, i);
|
|
if (CFGetTypeID(asn) == _LSASNGetTypeID())
|
|
{
|
|
_LSASNExtractHighAndLowParts(asn, &psn.highLongOfPSN, &psn.lowLongOfPSN);
|
|
|
|
CFDictionaryRef processInfo = ProcessInformationCopyDictionary(&psn, kProcessDictionaryIncludeAllInformationMask);
|
|
if (processInfo)
|
|
{
|
|
CFArrayAppendValue(orderedApplications, processInfo);
|
|
CFRelease(processInfo);
|
|
}
|
|
}
|
|
}
|
|
CFRelease(apps);
|
|
|
|
CFArrayRef result = CFArrayGetCount(orderedApplications) == 0 ? NULL : CFArrayCreateCopy(kCFAllocatorDefault, orderedApplications);
|
|
CFRelease(orderedApplications);
|
|
return result;
|
|
}
|
|
|