Subversion Repositories filter_foundry

Rev

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

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