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