File indexing completed on 2025-11-09 07:56:17

0001 /*
0002  * This file is part of Krita
0003  *
0004  * SPDX-FileCopyrightText: 2015 Algorithmus <angelus.tenebrae@gmail.com>
0005  * SPDX-FileCopyrightText: 2015 beelzy <alvina.lee@innoactive.de>
0006  * SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
0007  *
0008  * SPDX-License-Identifier: GPL-2.0-or-later
0009  *
0010  */
0011 
0012 /* clang-format off */
0013 
0014 //==============================================================================
0015 //
0016 //  DO NO MODIFY THE CONTENT OF THIS FILE
0017 //
0018 //  This file contains the generic CFPlug-in code necessary for your generator
0019 //  To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c
0020 //
0021 //==============================================================================
0022 
0023 
0024 
0025 
0026 
0027 
0028 #include <CoreFoundation/CoreFoundation.h>
0029 #include <CoreFoundation/CFPlugInCOM.h>
0030 #include <CoreServices/CoreServices.h>
0031 #include <QuickLook/QuickLook.h>
0032 
0033 // -----------------------------------------------------------------------------
0034 //  constants
0035 // -----------------------------------------------------------------------------
0036 
0037 // Don't modify this line
0038 #define PLUGIN_ID "292DC9CD-1640-49AE-B0C1-308ED88E6677"
0039 
0040 //
0041 // Below is the generic glue code for all plug-ins.
0042 //
0043 // You should not have to modify this code aside from changing
0044 // names if you decide to change the names defined in the Info.plist
0045 //
0046 
0047 
0048 // -----------------------------------------------------------------------------
0049 //  typedefs
0050 // -----------------------------------------------------------------------------
0051 
0052 // The thumbnail generation function to be implemented in GenerateThumbnailForURL.c
0053 OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize);
0054 void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail);
0055 
0056 // The preview generation function to be implemented in GeneratePreviewForURL.c
0057 OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
0058 void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview);
0059 
0060 // The layout for an instance of QuickLookGeneratorPlugIn
0061 typedef struct __QuickLookGeneratorPluginType
0062 {
0063     void        *conduitInterface;
0064     CFUUIDRef    factoryID;
0065     UInt32       refCount;
0066 } QuickLookGeneratorPluginType;
0067 
0068 // -----------------------------------------------------------------------------
0069 //  prototypes
0070 // -----------------------------------------------------------------------------
0071 //  Forward declaration for the IUnknown implementation.
0072 //
0073 
0074 QuickLookGeneratorPluginType  *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID);
0075 void                         DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance);
0076 HRESULT                      QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
0077 void                        *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
0078 ULONG                        QuickLookGeneratorPluginAddRef(void *thisInstance);
0079 ULONG                        QuickLookGeneratorPluginRelease(void *thisInstance);
0080 
0081 // -----------------------------------------------------------------------------
0082 //  myInterfaceFtbl definition
0083 // -----------------------------------------------------------------------------
0084 //  The QLGeneratorInterfaceStruct function table.
0085 //
0086 static QLGeneratorInterfaceStruct myInterfaceFtbl = {
0087     NULL,
0088     QuickLookGeneratorQueryInterface,
0089     QuickLookGeneratorPluginAddRef,
0090     QuickLookGeneratorPluginRelease,
0091     NULL,
0092     NULL,
0093     NULL,
0094     NULL
0095 };
0096 
0097 
0098 // -----------------------------------------------------------------------------
0099 //  AllocQuickLookGeneratorPluginType
0100 // -----------------------------------------------------------------------------
0101 //  Utility function that allocates a new instance.
0102 //      You can do some initial setup for the generator here if you wish
0103 //      like allocating globals etc...
0104 //
0105 QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID)
0106 {
0107     QuickLookGeneratorPluginType *theNewInstance;
0108 
0109     theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType));
0110     memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType));
0111 
0112         /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */
0113     theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct));
0114     memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct));
0115 
0116         /*  Retain and keep an open instance refcount for each factory. */
0117     theNewInstance->factoryID = CFRetain(inFactoryID);
0118     CFPlugInAddInstanceForFactory(inFactoryID);
0119 
0120         /* This function returns the IUnknown interface so set the refCount to one. */
0121     theNewInstance->refCount = 1;
0122     return theNewInstance;
0123 }
0124 
0125 // -----------------------------------------------------------------------------
0126 //  DeallocQuickLookGeneratorPluginType
0127 // -----------------------------------------------------------------------------
0128 //  Utility function that deallocates the instance when
0129 //  the refCount goes to zero.
0130 //      In the current implementation generator interfaces are never deallocated
0131 //      but implement this as this might change in the future
0132 //
0133 void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance)
0134 {
0135     CFUUIDRef theFactoryID;
0136 
0137     theFactoryID = thisInstance->factoryID;
0138         /* Free the conduitInterface table up */
0139     free(thisInstance->conduitInterface);
0140 
0141         /* Free the instance structure */
0142     free(thisInstance);
0143     if (theFactoryID){
0144         CFPlugInRemoveInstanceForFactory(theFactoryID);
0145         CFRelease(theFactoryID);
0146     }
0147 }
0148 
0149 // -----------------------------------------------------------------------------
0150 //  QuickLookGeneratorQueryInterface
0151 // -----------------------------------------------------------------------------
0152 //  Implementation of the IUnknown QueryInterface function.
0153 //
0154 HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv)
0155 {
0156     CFUUIDRef interfaceID;
0157 
0158     interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
0159 
0160     if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){
0161             /* If the Right interface was requested, bump the ref count,
0162              * set the ppv parameter equal to the instance, and
0163              * return good status.
0164              */
0165         ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL;
0166         ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration;
0167         ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL;
0168         ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration;
0169         ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance);
0170         *ppv = thisInstance;
0171         CFRelease(interfaceID);
0172         return S_OK;
0173     }else{
0174         /* Requested interface unknown, bail with error. */
0175         *ppv = NULL;
0176         CFRelease(interfaceID);
0177         return E_NOINTERFACE;
0178     }
0179 }
0180 
0181 // -----------------------------------------------------------------------------
0182 // QuickLookGeneratorPluginAddRef
0183 // -----------------------------------------------------------------------------
0184 //  Implementation of reference counting for this type. Whenever an interface
0185 //  is requested, bump the refCount for the instance. NOTE: returning the
0186 //  refcount is a convention but is not required so don't rely on it.
0187 //
0188 ULONG QuickLookGeneratorPluginAddRef(void *thisInstance)
0189 {
0190     ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1;
0191     return ((QuickLookGeneratorPluginType*) thisInstance)->refCount;
0192 }
0193 
0194 // -----------------------------------------------------------------------------
0195 // QuickLookGeneratorPluginRelease
0196 // -----------------------------------------------------------------------------
0197 //  When an interface is released, decrement the refCount.
0198 //  If the refCount goes to zero, deallocate the instance.
0199 //
0200 ULONG QuickLookGeneratorPluginRelease(void *thisInstance)
0201 {
0202     ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1;
0203     if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){
0204         DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance );
0205         return 0;
0206     }else{
0207         return ((QuickLookGeneratorPluginType*) thisInstance )->refCount;
0208     }
0209 }
0210 
0211 // -----------------------------------------------------------------------------
0212 //  QuickLookGeneratorPluginFactory
0213 // -----------------------------------------------------------------------------
0214 void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
0215 {
0216     QuickLookGeneratorPluginType *result;
0217     CFUUIDRef                 uuid;
0218 
0219         /* If correct type is being requested, allocate an
0220          * instance of kQLGeneratorTypeID and return the IUnknown interface.
0221          */
0222     if (CFEqual(typeID,kQLGeneratorTypeID)){
0223         uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
0224         result = AllocQuickLookGeneratorPluginType(uuid);
0225         CFRelease(uuid);
0226         return result;
0227     }
0228         /* If the requested type is incorrect, return NULL. */
0229     return NULL;
0230 }
0231