Subversion Repositories filter_foundry

Rev

Rev 57 | Rev 63 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 toby 1
/*
18 toby 2
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
2 toby 3
    Copyright (C) 2003-5 Toby Thain, toby@telegraphics.com.au
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by  
7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License  
16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
*/
19
 
20
#include <plstringfuncs.h>
21
#include <ASRegistry.h>
13 toby 22
#include <ctype.h>
2 toby 23
 
24
#include "ff.h"
25
 
26
#include "file_compat.h"
27
 
28
// MoreFiles headers
29
#include "FileCopy.h" 
30
#include "MoreFilesExtras.h"
31
 
32
OSErr wrstr(FILEREF rn,char *s);
33
OSErr dopkginfo(FILEREF rn);
34
OSErr make_bundle(StandardFileReply *sfr, short plugvol,long plugdir,StringPtr plugname);
11 toby 35
OSErr doresources(FSSpec *srcplug, FSSpec *rsrccopyfss);
2 toby 36
OSErr make_singlefile(StandardFileReply *sfr, short plugvol,long plugdir,StringPtr plugname);
11 toby 37
OSErr copyplist(FSSpec *fss, short dstvol,long dstdir);
13 toby 38
int copyletters(char *dst,StringPtr src);
2 toby 39
 
13 toby 40
// prototype for a function included in Carbon's stdlib and declared in /usr/include/string.h
41
// but missing from MPW Universal header string.h
42
#ifndef _STRING_H_
43
        char    *strnstr(const char *, const char *, size_t);
44
#endif
45
 
2 toby 46
OSErr wrstr(FILEREF rn,char *s){
47
        long count = strlen(s);
48
        return FSWrite(rn,&count,s);
49
}
50
 
11 toby 51
OSErr doresources(FSSpec *srcplug, FSSpec *rsrccopy){
2 toby 52
        short srcrn,dstrn;
53
        Handle hpipl,h;
54
        long origsize,newsize;
55
        OSErr e = noErr;
56
        Str255 title;
57
 
11 toby 58
#ifdef MACMACHO
62 toby 59
        FSRef inref,outref;
60
        // work with resources in data fork
61
        if( !(e = FSpMakeFSRef(srcplug,&inref))
62
         && !(e = FSOpenResourceFile(&inref,0/*forkNameLength*/,NULL/*forkName*/,fsRdPerm,&srcrn))
63
         && !(e = FSpMakeFSRef(rsrccopy,&outref))
64
         &&  (e = FSOpenResourceFile(&outref,0/*forkNameLength*/,NULL/*forkName*/,fsWrPerm,&dstrn)) )
65
                CloseResFile(srcrn);
11 toby 66
#else
62 toby 67
        // ordinary resource fork files
68
        srcrn = FSpOpenResFile(srcplug,fsRdPerm);
69
        if(srcrn != -1){
70
                dstrn = FSpOpenResFile(rsrccopy,fsWrPerm);
71
                if(dstrn == -1){
72
                        e = ResError();
73
                        CloseResFile(srcrn);
74
                }
75
        }else e = ResError();
11 toby 76
#endif
2 toby 77
 
11 toby 78
        if(!e){
79
                /* create a new PiPL resource for the standalone plugin,
80
                   with updated title and category strings */
81
 
57 toby 82
                if( (hpipl = Get1Resource('DATA',16000))
83
                 && (h = Get1Resource('PiPL',16000)) )
84
                {
11 toby 85
                        RemoveResource(h);
86
 
87
                        DetachResource(hpipl);
2 toby 88
 
11 toby 89
                        PLstrcpy(title,gdata->parm.title);
90
                        if(gdata->parm.popDialog)
91
                                PLstrcat(title,"\pÉ");
2 toby 92
 
11 toby 93
                        origsize = GetHandleSize(hpipl);
94
                        SetHandleSize(hpipl,origsize+0x300); /* some slop for fixup to work with */
95
                        HLock(hpipl);
96
                        newsize = fixpipl((PIPropertyList*) *hpipl,origsize,title);
97
                        HUnlock(hpipl);
98
                        SetHandleSize(hpipl,newsize);
99
 
100
                        AddResource(hpipl,'PiPL',16000,"\p");
101
 
57 toby 102
                        if( !(e = ResError()) ){
103
                                /* do a similar trick with the terminology resource,
104
                                   so the scripting system can distinguish the standalone plugin */
11 toby 105
 
57 toby 106
                                if( (h = Get1Resource(typeAETE,AETE_ID)) ){
107
                                        origsize = GetHandleSize(h);
108
                                        SetHandleSize(h,origsize+0x100); /* slop for fixup to work with */
109
                                        HLock(h);
110
                                        newsize = fixaete((unsigned char*)*h,origsize,gdata->parm.title);
111
                                        HUnlock(h);
112
                                        SetHandleSize(h,newsize);
113
 
114
                                        ChangedResource(h);
115
 
116
                                        if( !(e = ResError()) ){
117
                                                /* add PARM resource */
118
                                                if( !(e = PtrToHand(&gdata->parm,&h,sizeof(PARM_T))) )
119
                                                        AddResource(h,'PARM',PARM_ID,"\p");
120
                                        }
121
                                }
122
 
123
                        }
2 toby 124
 
11 toby 125
                }
57 toby 126
                if(!e)
127
                        e = ResError();
128
 
11 toby 129
                CloseResFile(dstrn);
2 toby 130
                CloseResFile(srcrn);
11 toby 131
        }
2 toby 132
 
133
        return e;
134
}
135
 
11 toby 136
int copyletters(char *dst,StringPtr src){
62 toby 137
        int i,n=0;
138
 
139
        for(i=src[0];i--;)
140
                if(isalpha(*++src)){
141
                        *dst++ = *src;
142
                        ++n;
143
                }
144
        return n;
11 toby 145
}
8 toby 146
 
11 toby 147
// Info.plist in new standalone copy needs to be edited
148
// at least the CFBundleIdentifier property must be unique
149
 
57 toby 150
OSErr copyplist(FSSpec *fss, short dstvol, long dstdir){
62 toby 151
        static char *key = "com.telegraphics.FilterFoundry";
152
        static unsigned char *fname="\pInfo.plist";
153
        char *buf,*save,*p;
154
        short rn,dstrn,i,n,m;
155
        long eof,count;
156
        OSErr e;
157
 
158
        if( !(e = HCreate(dstvol,dstdir,fname,'pled','TEXT')) ){
159
                if( !(e = HOpenDF(dstvol,dstdir,fname,fsWrPerm,&dstrn)) ){
160
                        if( !(e = FSpOpenDF(fss,fsRdPerm,&rn)) ){
161
                                if( !(e = GetEOF(rn,&eof)) && (buf = malloc(eof+1024)) ){
162
                                        if( !(e = FSRead(rn,&eof,buf)) ){
163
                                                buf[eof] = 0;
164
                                                if( (p = strnstr(buf,key,eof)) && (save = malloc(eof-(p-buf)+1)) ){
165
                                                        p += strlen(key);
166
                                                        // store text after matched string
167
                                                        strcpy(save,p);
168
 
169
                                                        *p++ = '.';
170
                                                        n = copyletters(p,gdata->parm.category);
171
                                                        p += n;
172
                                                        if(n) *p++ = '.';
173
                                                        m = copyletters(p,gdata->parm.title);
174
                                                        p += m;
175
                                                        if(!m){
176
                                                                // generate a random ASCII identifier
177
                                                                srand(TICKCOUNT());
178
                                                                for(i=8;i--;) *p++ = 'a' + (rand() % 26);
179
                                                        }
180
                                                        strcpy(p,save);
181
 
182
                                                        count = strlen(buf);
183
                                                        e = FSWrite(dstrn,&count,buf);
184
 
185
                                                        free(save);
186
                                                }else e = paramErr; // not found?? shouldn't happen
187
                                        }
188
                                        free(buf);
189
                                }
190
                                FSClose(rn);
191
                        }
192
                        FSClose(dstrn);
193
                }
194
                if(e) HDelete(dstvol,dstdir,fname);
195
        }
196
        return e;
11 toby 197
}
198
 
57 toby 199
OSErr make_bundle(StandardFileReply *sfr, short plugvol, long plugdir, StringPtr plugname){
2 toby 200
        short dstvol = sfr->sfFile.vRefNum;
11 toby 201
        long bundledir,contentsdir,macosdir,rsrcdir;
2 toby 202
        DInfo fndrInfo;
203
        OSErr e;
11 toby 204
        FSSpec fss,macosfss,rsrcfss,rsrccopyfss;
2 toby 205
 
206
        if( !(e = FSpDirCreate(&sfr->sfFile,sfr->sfScript,&bundledir)) ){
207
                if(!(e = FSpGetDInfo(&sfr->sfFile,&fndrInfo)) ){
208
                        fndrInfo.frFlags |= kHasBundle;
209
                        FSpSetDInfo(&sfr->sfFile,&fndrInfo);
210
                }
211
                if( !(e = DirCreate(dstvol,bundledir,"\pContents",&contentsdir)) ){
212
                        if( !(e = DirCreate(dstvol,contentsdir,"\pMacOS",&macosdir)) ){
11 toby 213
                                if( !(e = DirCreate(dstvol,contentsdir,"\pResources",&rsrcdir)) ){
2 toby 214
 
11 toby 215
                                        /* directories created ; now we need to copy the Info.plist file, resource file, and executable */
2 toby 216
 
11 toby 217
                                        if( !(e = FSMakeFSSpec(plugvol,plugdir,"\p::MacOS:FilterFoundry",&macosfss))
218
                                         && !(e = FileCopy(macosfss.vRefNum,macosfss.parID,macosfss.name, dstvol,macosdir,NULL, NULL,NULL,0,false)) ){
219
                                                /* now we add PARM resources to each binary, and edit PiPLs */
62 toby 220
                                                        if( !(e = FSMakeFSSpec(plugvol,plugdir,"\p::Resources:FilterFoundry.rsrc",&rsrcfss))
221
                                                         && !(e = FileCopy(rsrcfss.vRefNum,rsrcfss.parID,rsrcfss.name, dstvol,rsrcdir,NULL, NULL,NULL,0,false))
222
                                                         && !(e = FSMakeFSSpec(dstvol,rsrcdir,"\pFilterFoundry.rsrc",&rsrccopyfss)) )
223
                                                        {
224
                                                                if( !(e = doresources(&rsrcfss, &rsrccopyfss))
225
                                                                 && !(e = FSMakeFSSpec(plugvol,plugdir,"\p::Info.plist",&fss)) ){
226
                                                                        e = copyplist(&fss,dstvol,contentsdir);
227
 
228
                                                                if(e) FSpDelete(&rsrccopyfss);
229
                                                        }
230
                                                        if(e) HDelete(dstvol,macosdir,"\pFilterFoundry");
11 toby 231
                                                }
232
                                                if(e) HDelete(dstvol,rsrcdir,plugname);
233
                                        }
234
                                        if(e) HDelete(dstvol,contentsdir,"\pResources");
2 toby 235
                                }
11 toby 236
                                if(e) HDelete(dstvol,contentsdir,"\pMacOS");
2 toby 237
                        }
11 toby 238
                        if(e) HDelete(dstvol,bundledir,"\pContents");
2 toby 239
                }
240
                if(e) FSpDelete(&sfr->sfFile);
241
        }
242
 
243
        return e;
244
}
245
 
246
OSErr make_singlefile(StandardFileReply *sfr, short plugvol,long plugdir,StringPtr plugname){
247
        OSErr e;
248
        FSSpec origfss;
249
 
250
        e = FSpDelete(&sfr->sfFile);
251
        if(e && e != fnfErr){
11 toby 252
                alertuser("Can't replace the existing file. Try a different name or location.","");
2 toby 253
                return userCanceledErr;
254
        }
255
 
256
        if( !(e = FileCopy(plugvol,plugdir,plugname, sfr->sfFile.vRefNum,sfr->sfFile.parID,NULL, sfr->sfFile.name,NULL,0,false))
62 toby 257
         && !(e = FSMakeFSSpec(plugvol,plugdir,plugname,&origfss)) )
2 toby 258
                /* now we add PARM resources, and edit PiPL */
11 toby 259
                e = doresources(&origfss, &sfr->sfFile);
2 toby 260
 
261
        return e;
262
}
263
 
264
OSErr make_standalone(StandardFileReply *sfr){
265
        OSErr e;
266
        short plugvol;
267
        long plugdir;
268
        Str255 plugname;
269
 
270
        if(!(e = GetFileLocation(CurResFile(),&plugvol,&plugdir,plugname)))
11 toby 271
#ifdef MACMACHO
62 toby 272
        e = make_bundle(sfr,plugvol,plugdir,plugname);
11 toby 273
#else
62 toby 274
        e = make_singlefile(sfr,plugvol,plugdir,plugname);
11 toby 275
#endif
2 toby 276
 
277
        if(e && e != userCanceledErr)
278
                alertuser("Could not create standalone plugin.","");
279
 
280
        return e;
281
}