/filesystems/grabfs/windowfs_windows.cc
C++ | 147 lines | 114 code | 25 blank | 8 comment | 26 complexity | bb29d3973b71291ad91513f03f9ce48f MD5 | raw file
1/* 2 * MacFUSE-Based windowfs 3 * 4 * Copyright Amit Singh. All Rights Reserved. 5 * http://osxbook.com 6 * 7 */ 8 9#include <ApplicationServices/ApplicationServices.h> 10 11extern "C" { 12 13#include "windowfs_windows.h" 14 15static void 16WINDOWFS_WindowListApplierFunction(const void *inputDictionary, void *context) 17{ 18 CFDictionaryRef entry = (CFDictionaryRef)inputDictionary; 19 WindowListData *data = (WindowListData *)context; 20 21 CFNumberRef sharingState; /* SInt32 */ 22 CFNumberRef windowNumber; /* SInt64 */ 23 CFNumberRef ownerPID; /* SInt64 */ 24 25 Boolean status; 26 SInt32 sint32; 27 SInt64 sint64; 28 29 status = CFDictionaryGetValueIfPresent(entry, kCGWindowSharingState, 30 (const void **)&sharingState); 31 if (status == true) { 32 status = CFNumberGetValue(sharingState, kCFNumberSInt32Type, 33 (void *)&sint32); 34 CFRelease(sharingState); 35 if ((status == true) && (sint32 == 0)) { 36 return; 37 } 38 } else { 39 /* proceed */ 40 } 41 42 status = CFDictionaryGetValueIfPresent(entry, kCGWindowOwnerPID, 43 (const void **)&ownerPID); 44 if (status == true) { 45 status = CFNumberGetValue(ownerPID, kCFNumberSInt64Type, 46 (void *)&sint64); 47 CFRelease(ownerPID); 48 if (status == true) { 49 if ((pid_t)sint64 != data->pid) { 50 return; 51 } 52 } else { 53 return; 54 } 55 } else { 56 return; 57 } 58 59 status = CFDictionaryGetValueIfPresent(entry, kCGWindowNumber, 60 (const void **)&windowNumber); 61 if (status == true) { 62 status = CFNumberGetValue(windowNumber, kCFNumberSInt64Type, 63 (void *)&sint64); 64 CFRelease(windowNumber); 65 if (status == true) { 66 data->windowIDs[data->windowCount] = (CGSWindowID)sint64; 67 data->windowCount++; 68 } else { 69 return; 70 } 71 } else { 72 return; 73 } 74} 75 76int 77WINDOWFS_GetWindowList(WindowListData *data) 78{ 79 CFArrayRef windowList = CGWindowListCopyWindowInfo( 80 kCGWindowListOptionOnScreenOnly, 81 kCGNullWindowID); 82 if (!windowList) { 83 return -1; 84 } 85 86 CFArrayApplyFunction(windowList, 87 CFRangeMake(0, CFArrayGetCount(windowList)), 88 &WINDOWFS_WindowListApplierFunction, (void *)data); 89 90 return data->windowCount; 91} 92 93off_t 94WINDOWFS_GetTIFFSizeForWindowAtIndex(CGWindowID index) 95{ 96 CGRect rect; 97 98 CGError err = CGSGetScreenRectForWindow(_CGSDefaultConnection(), index, 99 &rect); 100 if (err) { 101 return (off_t)0; 102 } 103 104 off_t size = ((off_t)rect.size.width * (off_t)rect.size.height * (off_t)4) 105 + (off_t)8192; 106 107 return size; 108} 109 110int 111WINDOWFS_GetTIFFForWindowAtIndex(CGWindowID index, CFMutableDataRef *data) 112{ 113 *data = (CFMutableDataRef)0; 114 115 CGImageRef image = CGWindowListCreateImage( 116 CGRectNull, kCGWindowListOptionIncludingWindow, 117 index, kCGWindowImageBoundsIgnoreFraming); 118 119 if (!image) { 120 return -1; 121 } 122 123 *data = CFDataCreateMutable(kCFAllocatorDefault, 0); 124 if (!*data) { 125 CFRelease(image); 126 return -1; 127 } 128 129 CGImageDestinationRef dest = 130 CGImageDestinationCreateWithData((CFMutableDataRef)*data, kUTTypeTIFF, 131 1, nil); 132 if (!dest) { 133 CFRelease(*data); 134 CFRelease(image); 135 return -1; 136 } 137 138 CGImageDestinationAddImage(dest, image, nil); 139 CGImageDestinationFinalize(dest); 140 141 CFRelease(dest); 142 CGImageRelease(image); 143 144 return 0; 145} 146 147} /* extern "C" */