/* |
|
File: main.c |
|
Abstract: This is the CFPlug-in boilerplate code for a Quick Look preview generator |
|
Version: 1.0 |
|
Disclaimer: IMPORTANT: This Apple software is supplied to you by |
Apple Inc. ("Apple") in consideration of your agreement to the |
following terms, and your use, installation, modification or |
redistribution of this Apple software constitutes acceptance of these |
terms. If you do not agree with these terms, please do not use, |
install, modify or redistribute this Apple software. |
|
In consideration of your agreement to abide by the following terms, and |
subject to these terms, Apple grants you a personal, non-exclusive |
license, under Apple's copyrights in this original Apple software (the |
"Apple Software"), to use, reproduce, modify and redistribute the Apple |
Software, with or without modifications, in source and/or binary forms; |
provided that if you redistribute the Apple Software in its entirety and |
without modifications, you must retain this notice and the following |
text and disclaimers in all such redistributions of the Apple Software. |
Neither the name, trademarks, service marks or logos of Apple Inc. |
may be used to endorse or promote products derived from the Apple |
Software without specific prior written permission from Apple. Except |
as expressly stated in this notice, no other rights or licenses, express |
or implied, are granted by Apple herein, including but not limited to |
any patent rights that may be infringed by your derivative works or by |
other works in which the Apple Software may be incorporated. |
|
The Apple Software is provided by Apple on an "AS IS" basis. APPLE |
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION |
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS |
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND |
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. |
|
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL |
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, |
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED |
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), |
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGE. |
|
Copyright (C) 2007 Apple Inc. All Rights Reserved. |
*/ |
|
//============================================================================== |
// |
// DO NO MODIFY THE CONTENT OF THIS FILE |
// |
// This file contains the generic CFPlug-in code necessary for your generator |
// To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c |
// |
//============================================================================== |
|
|
|
|
|
|
#include <CoreFoundation/CoreFoundation.h> |
#include <CoreFoundation/CFPlugInCOM.h> |
#include <CoreServices/CoreServices.h> |
#include <QuickLook/QuickLook.h> |
|
// ----------------------------------------------------------------------------- |
// constants |
// ----------------------------------------------------------------------------- |
|
// Don't modify this line |
#define PLUGIN_ID "660EBE04-BCB7-46E1-B107-88FBB16EE5AF" |
|
// |
// Below is the generic glue code for all plug-ins. |
// |
// You should not have to modify this code aside from changing |
// names if you decide to change the names defined in the Info.plist |
// |
|
|
// ----------------------------------------------------------------------------- |
// typedefs |
// ----------------------------------------------------------------------------- |
|
// The thumbnail generation function to be implemented in GenerateThumbnailForURL.c |
OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); |
void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail); |
|
// The preview generation function to be implemented in GeneratePreviewForURL.c |
OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); |
void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); |
|
// The layout for an instance of QuickLookGeneratorPlugIn |
typedef struct __QuickLookGeneratorPluginType |
{ |
void *conduitInterface; |
CFUUIDRef factoryID; |
UInt32 refCount; |
} QuickLookGeneratorPluginType; |
|
// ----------------------------------------------------------------------------- |
// prototypes |
// ----------------------------------------------------------------------------- |
// Forward declaration for the IUnknown implementation. |
// |
|
QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID); |
void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance); |
HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); |
void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); |
ULONG QuickLookGeneratorPluginAddRef(void *thisInstance); |
ULONG QuickLookGeneratorPluginRelease(void *thisInstance); |
|
// ----------------------------------------------------------------------------- |
// myInterfaceFtbl definition |
// ----------------------------------------------------------------------------- |
// The QLGeneratorInterfaceStruct function table. |
// |
static QLGeneratorInterfaceStruct myInterfaceFtbl = { |
NULL, |
QuickLookGeneratorQueryInterface, |
QuickLookGeneratorPluginAddRef, |
QuickLookGeneratorPluginRelease, |
NULL, |
NULL, |
NULL, |
NULL |
}; |
|
|
// ----------------------------------------------------------------------------- |
// AllocQuickLookGeneratorPluginType |
// ----------------------------------------------------------------------------- |
// Utility function that allocates a new instance. |
// You can do some initial setup for the generator here if you wish |
// like allocating globals etc... |
// |
QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID) |
{ |
QuickLookGeneratorPluginType *theNewInstance; |
|
theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType)); |
memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType)); |
|
/* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */ |
theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct)); |
memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct)); |
|
/* Retain and keep an open instance refcount for each factory. */ |
theNewInstance->factoryID = CFRetain(inFactoryID); |
CFPlugInAddInstanceForFactory(inFactoryID); |
|
/* This function returns the IUnknown interface so set the refCount to one. */ |
theNewInstance->refCount = 1; |
return theNewInstance; |
} |
|
// ----------------------------------------------------------------------------- |
// DeallocQuickLookGeneratorPluginType |
// ----------------------------------------------------------------------------- |
// Utility function that deallocates the instance when |
// the refCount goes to zero. |
// In the current implementation generator interfaces are never deallocated |
// but implement this as this might change in the future |
// |
void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance) |
{ |
CFUUIDRef theFactoryID; |
|
theFactoryID = thisInstance->factoryID; |
/* Free the conduitInterface table up */ |
free(thisInstance->conduitInterface); |
|
/* Free the instance structure */ |
free(thisInstance); |
if (theFactoryID){ |
CFPlugInRemoveInstanceForFactory(theFactoryID); |
CFRelease(theFactoryID); |
} |
} |
|
// ----------------------------------------------------------------------------- |
// QuickLookGeneratorQueryInterface |
// ----------------------------------------------------------------------------- |
// Implementation of the IUnknown QueryInterface function. |
// |
HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) |
{ |
CFUUIDRef interfaceID; |
|
interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); |
|
if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){ |
/* If the Right interface was requested, bump the ref count, |
* set the ppv parameter equal to the instance, and |
* return good status. |
*/ |
((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL; |
((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration; |
((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL; |
((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration; |
((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance); |
*ppv = thisInstance; |
CFRelease(interfaceID); |
return S_OK; |
}else{ |
/* Requested interface unknown, bail with error. */ |
*ppv = NULL; |
CFRelease(interfaceID); |
return E_NOINTERFACE; |
} |
} |
|
// ----------------------------------------------------------------------------- |
// QuickLookGeneratorPluginAddRef |
// ----------------------------------------------------------------------------- |
// Implementation of reference counting for this type. Whenever an interface |
// is requested, bump the refCount for the instance. NOTE: returning the |
// refcount is a convention but is not required so don't rely on it. |
// |
ULONG QuickLookGeneratorPluginAddRef(void *thisInstance) |
{ |
((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1; |
return ((QuickLookGeneratorPluginType*) thisInstance)->refCount; |
} |
|
// ----------------------------------------------------------------------------- |
// QuickLookGeneratorPluginRelease |
// ----------------------------------------------------------------------------- |
// When an interface is released, decrement the refCount. |
// If the refCount goes to zero, deallocate the instance. |
// |
ULONG QuickLookGeneratorPluginRelease(void *thisInstance) |
{ |
((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1; |
if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){ |
DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance ); |
return 0; |
}else{ |
return ((QuickLookGeneratorPluginType*) thisInstance )->refCount; |
} |
} |
|
// ----------------------------------------------------------------------------- |
// QuickLookGeneratorPluginFactory |
// ----------------------------------------------------------------------------- |
void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) |
{ |
QuickLookGeneratorPluginType *result; |
CFUUIDRef uuid; |
|
/* If correct type is being requested, allocate an |
* instance of kQLGeneratorTypeID and return the IUnknown interface. |
*/ |
if (CFEqual(typeID,kQLGeneratorTypeID)){ |
uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); |
result = AllocQuickLookGeneratorPluginType(uuid); |
CFRelease(uuid); |
return result; |
} |
/* If the requested type is incorrect, return NULL. */ |
return NULL; |
} |