1 /*
2 * This file is part of Krita
3 *
4 * Copyright (c) 2020 L. E. Segovia <amy@amyspark.me>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 * USA.
20 */
21
22 /* clang-format off */
23
24
25
26
27 //==============================================================================
28 //
29 // DO NO MODIFY THE CONTENT OF THIS FILE
30 //
31 // This file contains the generic CFPlug-in code necessary for your importer
32 // To complete your importer implement the function in GetMetadataForFile.c
33 //
34 //==============================================================================
35
36
37
38
39
40 #import <CoreFoundation/CoreFoundation.h>
41 #import <CoreFoundation/CFPlugInCOM.h>
42 #import <CoreServices/CoreServices.h>
43
44 // -----------------------------------------------------------------------------
45 // constants
46 // -----------------------------------------------------------------------------
47
48
49 #define PLUGIN_ID "23FE92B0-6256-49C0-B1A6-942FB9B86A82"
50
51 //
52 // Below is the generic glue code for all plug-ins.
53 //
54 // You should not have to modify this code aside from changing
55 // names if you decide to change the names defined in the Info.plist
56 //
57
58
59 // -----------------------------------------------------------------------------
60 // typedefs
61 // -----------------------------------------------------------------------------
62
63 // The import function to be implemented in GetMetadataForFile.c
64 Boolean GetMetadataForFile(void *thisInterface,
65 CFMutableDictionaryRef attributes,
66 CFStringRef contentTypeUTI,
67 CFStringRef pathToFile);
68
69 // The layout for an instance of MetaDataImporterPlugIn
70 typedef struct __MetadataImporterPluginType
71 {
72 MDImporterInterfaceStruct *conduitInterface;
73 CFUUIDRef factoryID;
74 UInt32 refCount;
75 } MetadataImporterPluginType;
76
77 // -----------------------------------------------------------------------------
78 // prototypes
79 // -----------------------------------------------------------------------------
80 // Forward declaration for the IUnknown implementation.
81 //
82
83 MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID);
84 void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance);
85 HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
86 void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
87 ULONG MetadataImporterPluginAddRef(void *thisInstance);
88 ULONG MetadataImporterPluginRelease(void *thisInstance);
89 // -----------------------------------------------------------------------------
90 // testInterfaceFtbl definition
91 // -----------------------------------------------------------------------------
92 // The TestInterface function table.
93 //
94
95 static MDImporterInterfaceStruct testInterfaceFtbl = {
96 NULL,
97 MetadataImporterQueryInterface,
98 MetadataImporterPluginAddRef,
99 MetadataImporterPluginRelease,
100 GetMetadataForFile
101 };
102
103
104 // -----------------------------------------------------------------------------
105 // AllocMetadataImporterPluginType
106 // -----------------------------------------------------------------------------
107 // Utility function that allocates a new instance.
108 // You can do some initial setup for the importer here if you wish
109 // like allocating globals etc...
110 //
AllocMetadataImporterPluginType(CFUUIDRef inFactoryID)111 MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID)
112 {
113 MetadataImporterPluginType *theNewInstance;
114
115 theNewInstance = (MetadataImporterPluginType *)malloc(sizeof(MetadataImporterPluginType));
116 memset(theNewInstance,0,sizeof(MetadataImporterPluginType));
117
118 /* Point to the function table */
119 theNewInstance->conduitInterface = &testInterfaceFtbl;
120
121 /* Retain and keep an open instance refcount for each factory. */
122 theNewInstance->factoryID = CFRetain(inFactoryID);
123 CFPlugInAddInstanceForFactory(inFactoryID);
124
125 /* This function returns the IUnknown interface so set the refCount to one. */
126 theNewInstance->refCount = 1;
127 return theNewInstance;
128 }
129
130 // -----------------------------------------------------------------------------
131 // DeallockritaspotlightMDImporterPluginType
132 // -----------------------------------------------------------------------------
133 // Utility function that deallocates the instance when
134 // the refCount goes to zero.
135 // In the current implementation importer interfaces are never deallocated
136 // but implement this as this might change in the future
137 //
DeallocMetadataImporterPluginType(MetadataImporterPluginType * thisInstance)138 void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance)
139 {
140 CFUUIDRef theFactoryID;
141
142 theFactoryID = thisInstance->factoryID;
143 free(thisInstance);
144 if (theFactoryID){
145 CFPlugInRemoveInstanceForFactory(theFactoryID);
146 CFRelease(theFactoryID);
147 }
148 }
149
150 // -----------------------------------------------------------------------------
151 // MetadataImporterQueryInterface
152 // -----------------------------------------------------------------------------
153 // Implementation of the IUnknown QueryInterface function.
154 //
MetadataImporterQueryInterface(void * thisInstance,REFIID iid,LPVOID * ppv)155 HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv)
156 {
157 CFUUIDRef interfaceID;
158
159 interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
160
161 if (CFEqual(interfaceID,kMDImporterInterfaceID)){
162 /* If the Right interface was requested, bump the ref count,
163 * set the ppv parameter equal to the instance, and
164 * return good status.
165 */
166 ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance);
167 *ppv = thisInstance;
168 CFRelease(interfaceID);
169 return S_OK;
170 }else{
171 if (CFEqual(interfaceID,IUnknownUUID)){
172 /* If the IUnknown interface was requested, same as above. */
173 ((MetadataImporterPluginType*)thisInstance )->conduitInterface->AddRef(thisInstance);
174 *ppv = thisInstance;
175 CFRelease(interfaceID);
176 return S_OK;
177 }else{
178 /* Requested interface unknown, bail with error. */
179 *ppv = NULL;
180 CFRelease(interfaceID);
181 return E_NOINTERFACE;
182 }
183 }
184 }
185
186 // -----------------------------------------------------------------------------
187 // MetadataImporterPluginAddRef
188 // -----------------------------------------------------------------------------
189 // Implementation of reference counting for this type. Whenever an interface
190 // is requested, bump the refCount for the instance. NOTE: returning the
191 // refcount is a convention but is not required so don't rely on it.
192 //
MetadataImporterPluginAddRef(void * thisInstance)193 ULONG MetadataImporterPluginAddRef(void *thisInstance)
194 {
195 ((MetadataImporterPluginType *)thisInstance )->refCount += 1;
196 return ((MetadataImporterPluginType*) thisInstance)->refCount;
197 }
198
199 // -----------------------------------------------------------------------------
200 // SampleCMPluginRelease
201 // -----------------------------------------------------------------------------
202 // When an interface is released, decrement the refCount.
203 // If the refCount goes to zero, deallocate the instance.
204 //
MetadataImporterPluginRelease(void * thisInstance)205 ULONG MetadataImporterPluginRelease(void *thisInstance)
206 {
207 ((MetadataImporterPluginType*)thisInstance)->refCount -= 1;
208 if (((MetadataImporterPluginType*)thisInstance)->refCount == 0){
209 DeallocMetadataImporterPluginType((MetadataImporterPluginType*)thisInstance );
210 return 0;
211 }else{
212 return ((MetadataImporterPluginType*) thisInstance )->refCount;
213 }
214 }
215
216 // -----------------------------------------------------------------------------
217 // kritaspotlightMDImporterPluginFactory
218 // -----------------------------------------------------------------------------
219 // Implementation of the factory function for this type.
220 //
MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)221 void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
222 {
223 MetadataImporterPluginType *result;
224 CFUUIDRef uuid;
225
226 /* If correct type is being requested, allocate an
227 * instance of TestType and return the IUnknown interface.
228 */
229 if (CFEqual(typeID,kMDImporterTypeID)){
230 uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
231 result = AllocMetadataImporterPluginType(uuid);
232 CFRelease(uuid);
233 return result;
234 }
235 /* If the requested type is incorrect, return NULL. */
236 return NULL;
237 }
238
239