Subversion Repositories filter_foundry

Rev

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