1//============================================================================== 2// 3// DO NO MODIFY THE CONTENT OF THIS FILE 4// 5// This file contains the generic CFPlug-in code necessary for your generator 6// To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c 7// 8//============================================================================== 9 10 11 12 13 14 15#include <CoreFoundation/CoreFoundation.h> 16#include <CoreFoundation/CFPlugInCOM.h> 17#include <CoreServices/CoreServices.h> 18#include <QuickLook/QuickLook.h> 19 20// ----------------------------------------------------------------------------- 21// constants 22// ----------------------------------------------------------------------------- 23 24// Don't modify this line 25#define PLUGIN_ID "FDF02409-6B04-4738-973D-1AADB4FC34D8" 26 27// 28// Below is the generic glue code for all plug-ins. 29// 30// You should not have to modify this code aside from changing 31// names if you decide to change the names defined in the Info.plist 32// 33 34 35// ----------------------------------------------------------------------------- 36// typedefs 37// ----------------------------------------------------------------------------- 38 39// The thumbnail generation function to be implemented in GenerateThumbnailForURL.c 40OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); 41void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail); 42 43// The preview generation function to be implemented in GeneratePreviewForURL.c 44OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); 45void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); 46 47// The layout for an instance of QuickLookGeneratorPlugIn 48typedef struct __QuickLookGeneratorPluginType 49{ 50 void *conduitInterface; 51 CFUUIDRef factoryID; 52 UInt32 refCount; 53} QuickLookGeneratorPluginType; 54 55// ----------------------------------------------------------------------------- 56// prototypes 57// ----------------------------------------------------------------------------- 58// Forward declaration for the IUnknown implementation. 59// 60 61QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID); 62void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance); 63HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); 64void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); 65ULONG QuickLookGeneratorPluginAddRef(void *thisInstance); 66ULONG QuickLookGeneratorPluginRelease(void *thisInstance); 67 68// ----------------------------------------------------------------------------- 69// myInterfaceFtbl definition 70// ----------------------------------------------------------------------------- 71// The QLGeneratorInterfaceStruct function table. 72// 73static QLGeneratorInterfaceStruct myInterfaceFtbl = { 74 NULL, 75 QuickLookGeneratorQueryInterface, 76 QuickLookGeneratorPluginAddRef, 77 QuickLookGeneratorPluginRelease, 78 NULL, 79 NULL, 80 NULL, 81 NULL 82}; 83 84 85// ----------------------------------------------------------------------------- 86// AllocQuickLookGeneratorPluginType 87// ----------------------------------------------------------------------------- 88// Utility function that allocates a new instance. 89// You can do some initial setup for the generator here if you wish 90// like allocating globals etc... 91// 92QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID) 93{ 94 QuickLookGeneratorPluginType *theNewInstance; 95 96 theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType)); 97 memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType)); 98 99 /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */ 100 theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct)); 101 memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct)); 102 103 /* Retain and keep an open instance refcount for each factory. */ 104 theNewInstance->factoryID = CFRetain(inFactoryID); 105 CFPlugInAddInstanceForFactory(inFactoryID); 106 107 /* This function returns the IUnknown interface so set the refCount to one. */ 108 theNewInstance->refCount = 1; 109 return theNewInstance; 110} 111 112// ----------------------------------------------------------------------------- 113// DeallocQuickLookGeneratorPluginType 114// ----------------------------------------------------------------------------- 115// Utility function that deallocates the instance when 116// the refCount goes to zero. 117// In the current implementation generator interfaces are never deallocated 118// but implement this as this might change in the future 119// 120void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance) 121{ 122 CFUUIDRef theFactoryID; 123 124 theFactoryID = thisInstance->factoryID; 125 /* Free the conduitInterface table up */ 126 free(thisInstance->conduitInterface); 127 128 /* Free the instance structure */ 129 free(thisInstance); 130 if (theFactoryID){ 131 CFPlugInRemoveInstanceForFactory(theFactoryID); 132 CFRelease(theFactoryID); 133 } 134} 135 136// ----------------------------------------------------------------------------- 137// QuickLookGeneratorQueryInterface 138// ----------------------------------------------------------------------------- 139// Implementation of the IUnknown QueryInterface function. 140// 141HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) 142{ 143 CFUUIDRef interfaceID; 144 145 interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); 146 147 if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){ 148 /* If the Right interface was requested, bump the ref count, 149 * set the ppv parameter equal to the instance, and 150 * return good status. 151 */ 152 ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL; 153 ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration; 154 ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL; 155 ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration; 156 ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance); 157 *ppv = thisInstance; 158 CFRelease(interfaceID); 159 return S_OK; 160 }else{ 161 /* Requested interface unknown, bail with error. */ 162 *ppv = NULL; 163 CFRelease(interfaceID); 164 return E_NOINTERFACE; 165 } 166} 167 168// ----------------------------------------------------------------------------- 169// QuickLookGeneratorPluginAddRef 170// ----------------------------------------------------------------------------- 171// Implementation of reference counting for this type. Whenever an interface 172// is requested, bump the refCount for the instance. NOTE: returning the 173// refcount is a convention but is not required so don't rely on it. 174// 175ULONG QuickLookGeneratorPluginAddRef(void *thisInstance) 176{ 177 ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1; 178 return ((QuickLookGeneratorPluginType*) thisInstance)->refCount; 179} 180 181// ----------------------------------------------------------------------------- 182// QuickLookGeneratorPluginRelease 183// ----------------------------------------------------------------------------- 184// When an interface is released, decrement the refCount. 185// If the refCount goes to zero, deallocate the instance. 186// 187ULONG QuickLookGeneratorPluginRelease(void *thisInstance) 188{ 189 ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1; 190 if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){ 191 DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance ); 192 return 0; 193 }else{ 194 return ((QuickLookGeneratorPluginType*) thisInstance )->refCount; 195 } 196} 197 198// ----------------------------------------------------------------------------- 199// QuickLookGeneratorPluginFactory 200// ----------------------------------------------------------------------------- 201void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) 202{ 203 QuickLookGeneratorPluginType *result; 204 CFUUIDRef uuid; 205 206 /* If correct type is being requested, allocate an 207 * instance of kQLGeneratorTypeID and return the IUnknown interface. 208 */ 209 if (CFEqual(typeID,kQLGeneratorTypeID)){ 210 uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); 211 result = AllocQuickLookGeneratorPluginType(uuid); 212 CFRelease(uuid); 213 return result; 214 } 215 /* If the requested type is incorrect, return NULL. */ 216 return NULL; 217} 218 219