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 "83B337DD-52D3-4070-AB85-6A213B471B69"
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
40 OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize);
41 void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail);
42
43 // The preview generation function to be implemented in GeneratePreviewForURL.c
44 OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
45 void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview);
46
47 // The layout for an instance of QuickLookGeneratorPlugIn
48 typedef 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
61 QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID);
62 void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance);
63 HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
64 void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
65 ULONG QuickLookGeneratorPluginAddRef(void *thisInstance);
66 ULONG QuickLookGeneratorPluginRelease(void *thisInstance);
67
68 // -----------------------------------------------------------------------------
69 // myInterfaceFtbl definition
70 // -----------------------------------------------------------------------------
71 // The QLGeneratorInterfaceStruct function table.
72 //
73 static 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 //
AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID)92 QuickLookGeneratorPluginType *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 //
DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType * thisInstance)120 void 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 //
QuickLookGeneratorQueryInterface(void * thisInstance,REFIID iid,LPVOID * ppv)141 HRESULT 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 //
QuickLookGeneratorPluginAddRef(void * thisInstance)175 ULONG 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 //
QuickLookGeneratorPluginRelease(void * thisInstance)187 ULONG 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 // -----------------------------------------------------------------------------
QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)201 void *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