Subversion Repositories filter_foundry

Compare Revisions

Ignore whitespace Rev 216 → Rev 217

/trunk/scripting.c
1,21 → 1,21
/*
This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
 
/* Portions Copyright 1996 - 1999 Adobe Systems Incorporated */
33,154 → 33,164
 
//extern FilterRecordPtr gpb;
 
OSErr put_cstring(PIWriteDescriptor token,DescriptorKeyID key,char *s){
size_t n = strlen(s);
Ptr p;
Handle h = PINEWHANDLE((int32)n);
p = PILOCKHANDLE(h,false);
memcpy(p,s,n);
PIUNLOCKHANDLE(h);
return PIPutText(token,key,h);
/* FIXME: not sure if we are supposed to dispose of handle */
OSErr put_cstring(PIWriteDescriptor token, DescriptorKeyID key, char* s) {
OSErr e;
size_t n = strlen(s);
Ptr p;
Handle h = PINEWHANDLE((int32)n);
p = PILOCKHANDLE(h, false);
memcpy(p, s, n);
PIUNLOCKHANDLE(h);
e = PIPutText(token, key, h);
PIDISPOSEHANDLE(h); /* Not 100% sure if we are supposed to dispose of handle. It doesn't crash though */
return e;
}
 
char *get_cstring(PIReadDescriptor token){
int n;
Ptr p;
char *str = NULL;
Handle h;
OSErr e = PIGetText(token,&h);
char* get_cstring(PIReadDescriptor token) {
int n;
Ptr p;
char* str = NULL;
Handle h;
OSErr e = PIGetText(token, &h);
 
if(!e && h){
n = PIGETHANDLESIZE(h);
p = PILOCKHANDLE(h,false);
//sprintf(str,"get_cstring: token=%#x s=%#x h=%#x p=%#x n=%d",token,s,h,p,n); dbg(str);
if( (str = (char*)malloc(n+1)) ){
memcpy(str,p,n);
str[n] = 0;
}
PIUNLOCKHANDLE(h);
/* FIXME: not sure if we are supposed to dispose of handle */
}
return str;
if (!e && h) {
n = PIGETHANDLESIZE(h);
p = PILOCKHANDLE(h, false);
if ((str = (char*)malloc(n + 1))) {
memcpy(str, p, n);
str[n] = 0;
}
PIUNLOCKHANDLE(h);
PIDISPOSEHANDLE(h); /* Not 100% sure if we are supposed to dispose of handle. It doesn't crash though */
}
return str;
}
 
// If parm is NULL, then it is standalone, otherwise it is the main plugin
OSType getAeteKey(char c, PARM_T* parm) {
// To make our plugin compatible with AppleScript, each key must
// be unique, since the namespace is global!
// Furthermore, the "uniqueID/scope" hstm-field in the PIPL must be empty.
// To make our plugin compatible with AppleScript, each key must
// be unique, since the namespace is global!
// Furthermore, the "uniqueID/scope" hstm-field in the PIPL must be empty.
 
if (parm != NULL) {
unsigned long hash;
char *data;
// char* debug = malloc(2000);
// sprintf(debug, "getAeteKey %c with title %s/%s in STANDALONE PLUGIN", c, INPLACEP2CSTR(parm->title), INPLACEP2CSTR(parm->category));
// simplealert(debug);
if (parm != NULL) {
unsigned long hash;
char* data;
// char* debug = malloc(2000);
// sprintf(debug, "getAeteKey %c with title %s/%s in STANDALONE PLUGIN", c, INPLACEP2CSTR(parm->title), INPLACEP2CSTR(parm->category));
// simplealert(debug);
 
// Use random AETE keys, because AppleScript has a global namespace
// and therefore requires unique AETE keys
data = (char*)malloc(0x300);
if (!data) return 0;
sprintf(data, "%s %s %c",
INPLACEP2CSTR(parm->category),
INPLACEP2CSTR(parm->title),
c);
hash = printablehash(djb2(data));
free(data);
return hash;
} else {
// char* debug = malloc(2000);
// sprintf(debug, "getAeteKey %c in MAIN PLUGIN", c);
// simplealert(debug);
// Use random AETE keys, because AppleScript has a global namespace
// and therefore requires unique AETE keys
data = (char*)malloc(0x300);
if (!data) return 0;
sprintf(data, "%s %s %c",
INPLACEP2CSTR(parm->category),
INPLACEP2CSTR(parm->title),
c);
hash = printablehash(djb2(data));
free(data);
return hash;
}
else {
// char* debug = malloc(2000);
// sprintf(debug, "getAeteKey %c in MAIN PLUGIN", c);
// simplealert(debug);
 
// Attention: AETE keys (xpr#, cTl#) must be equal in scripting.r, scripting.rc and scripting.c(getAeteKey)!
if (c == 'R') return 'xprR';
if (c == 'G') return 'xprG';
if (c == 'B') return 'xprB';
if (c == 'A') return 'xprA';
if ((c >= '0') && (c <= '9')) return 'cTl0' + (c - '0');
return 0;
}
// Attention: AETE keys (xpr#, cTl#) must be equal in scripting.r, scripting.rc and scripting.c(getAeteKey)!
if (c == 'R') return 'xprR';
if (c == 'G') return 'xprG';
if (c == 'B') return 'xprB';
if (c == 'A') return 'xprA';
if ((c >= '0') && (c <= '9')) return 'cTl0' + (c - '0');
return 0;
}
}
 
/* return true if dialog should be shown */
enum ScriptingShowDialog ReadScriptParamsOnRead(void)
{
PIReadDescriptor token;
DescriptorKeyID key;
DescriptorTypeID type;
DescriptorKeyIDArray array = { NULLID };
int32 flags;
//OSErr stickyError;
int32 v;
PIReadDescriptor token;
DescriptorKeyID key;
DescriptorTypeID type;
DescriptorKeyIDArray array = { NULLID };
int32 flags;
//OSErr stickyError;
int32 v;
 
if (DescriptorAvailable(NULL)){ /* playing back. Do our thing. */
token = OpenReader(array);
if (token) {
while (PIGetKey(token, &key, &type, &flags)) {
if (key == getAeteKey('R', gdata->standalone ? &gdata->parm : NULL)) {
expr[0] = get_cstring(token);
} else if (key == getAeteKey('G', gdata->standalone ? &gdata->parm : NULL)) {
expr[1] = get_cstring(token);
} else if (key == getAeteKey('B', gdata->standalone ? &gdata->parm : NULL)) {
expr[2] = get_cstring(token);
} else if (key == getAeteKey('A', gdata->standalone ? &gdata->parm : NULL)) {
expr[3] = get_cstring(token);
} else {
int i;
for (i=0; i<=7; ++i) {
if (key == getAeteKey('0'+i, gdata->standalone ? &gdata->parm : NULL)) {
PIGetInt(token, &v);
slider[i] = v;
}
}
}
}
if (DescriptorAvailable(NULL)) { /* playing back. Do our thing. */
token = OpenReader(array);
if (token) {
while (PIGetKey(token, &key, &type, &flags)) {
if (key == getAeteKey('R', gdata->standalone ? &gdata->parm : NULL)) {
expr[0] = get_cstring(token);
}
else if (key == getAeteKey('G', gdata->standalone ? &gdata->parm : NULL)) {
expr[1] = get_cstring(token);
}
else if (key == getAeteKey('B', gdata->standalone ? &gdata->parm : NULL)) {
expr[2] = get_cstring(token);
}
else if (key == getAeteKey('A', gdata->standalone ? &gdata->parm : NULL)) {
expr[3] = get_cstring(token);
}
else {
int i;
for (i = 0; i <= 7; ++i) {
if (key == getAeteKey('0' + i, gdata->standalone ? &gdata->parm : NULL)) {
PIGetInt(token, &v);
slider[i] = v;
}
}
}
}
 
/*stickyError =*/ CloseReader(&token); // closes & disposes.
/*stickyError =*/ CloseReader(&token); // closes & disposes.
 
// all Filter Foundry parameters are optional,
// so we needn't worry if any are missing
}
// all Filter Foundry parameters are optional,
// so we needn't worry if any are missing
}
 
return gpb->descriptorParameters->playInfo == plugInDialogDisplay ? SCR_SHOW_DIALOG : SCR_HIDE_DIALOG;
} else {
return SCR_NO_SCRIPT;
}
return gpb->descriptorParameters->playInfo == plugInDialogDisplay ? SCR_SHOW_DIALOG : SCR_HIDE_DIALOG;
}
else {
return SCR_NO_SCRIPT;
}
}
 
OSErr WriteScriptParamsOnRead(void)
{
PIWriteDescriptor token;
OSErr gotErr = noErr;
extern int ctls[],maps[],nplanes;
int i,allctls;
PIWriteDescriptor token;
OSErr gotErr = noErr;
extern int ctls[], maps[], nplanes;
int i, allctls;
 
if (DescriptorAvailable(NULL)){ /* recording. Do our thing. */
token = OpenWriter();
if (token){
// write keys here
if(!gdata->standalone){
if (nplanes > 0) put_cstring(token, getAeteKey('R', gdata->standalone ? &gdata->parm : NULL), expr[0]);
if (nplanes > 1) put_cstring(token, getAeteKey('G', gdata->standalone ? &gdata->parm : NULL), expr[1]);
if (nplanes > 2) put_cstring(token, getAeteKey('B', gdata->standalone ? &gdata->parm : NULL), expr[2]);
if (nplanes > 3) put_cstring(token, getAeteKey('A', gdata->standalone ? &gdata->parm : NULL), expr[3]);
}
if (DescriptorAvailable(NULL)) { /* recording. Do our thing. */
// 1. Call openWriteDescriptorProc which will return a PIWriteDescriptor token, such as writeToken.
token = OpenWriter();
if (token) {
// 2. Call various Put routines such as PutIntegerProc, PutFloatProc, etc., to add key/value pairs to writeToken. The keys and value types must correspond to those in your terminology resource.
 
/* only write values for the sliders that are actually used! */
allctls = checksliders(4,ctls,maps);
for (i=0; i<=7; ++i) {
if (allctls || ctls[i]) {
PIPutInt(token, getAeteKey('0'+i, gdata->standalone ? &gdata->parm : NULL), slider[i]);
}
}
// write keys here
if (!gdata->standalone) {
if (nplanes > 0) put_cstring(token, getAeteKey('R', gdata->standalone ? &gdata->parm : NULL), expr[0]);
if (nplanes > 1) put_cstring(token, getAeteKey('G', gdata->standalone ? &gdata->parm : NULL), expr[1]);
if (nplanes > 2) put_cstring(token, getAeteKey('B', gdata->standalone ? &gdata->parm : NULL), expr[2]);
if (nplanes > 3) put_cstring(token, getAeteKey('A', gdata->standalone ? &gdata->parm : NULL), expr[3]);
}
 
gotErr = CloseWriter(&token); /* closes and sets dialog optional */
/* done. Now pass handle on to Photoshop */
}
}
return gotErr;
/* only write values for the sliders that are actually used! */
allctls = checksliders(4, ctls, maps);
for (i = 0; i <= 7; ++i) {
if (allctls || ctls[i]) {
PIPutInt(token, getAeteKey('0' + i, gdata->standalone ? &gdata->parm : NULL), slider[i]);
}
}
 
gotErr = CloseWriter(&token); /* closes and sets dialog optional */
/* done. Now pass handle on to Photoshop */
}
}
return gotErr;
}
 
 
195,33 → 205,33
//
//-------------------------------------------------------------------------------
 
Boolean HostDescriptorAvailable (PIDescriptorParameters *procs,
Boolean *outNewerVersion)
Boolean HostDescriptorAvailable(PIDescriptorParameters* procs,
Boolean* outNewerVersion)
{
if(outNewerVersion)
*outNewerVersion = procs->descriptorParametersVersion > kCurrentDescriptorParametersVersion
|| procs->readDescriptorProcs->readDescriptorProcsVersion > kCurrentReadDescriptorProcsVersion
|| procs->writeDescriptorProcs->writeDescriptorProcsVersion > kCurrentWriteDescriptorProcsVersion ;
if (outNewerVersion)
*outNewerVersion = procs->descriptorParametersVersion > kCurrentDescriptorParametersVersion
|| procs->readDescriptorProcs->readDescriptorProcsVersion > kCurrentReadDescriptorProcsVersion
|| procs->writeDescriptorProcs->writeDescriptorProcsVersion > kCurrentWriteDescriptorProcsVersion;
 
return procs != NULL
&& procs->descriptorParametersVersion == kCurrentDescriptorParametersVersion
return procs != NULL
&& procs->descriptorParametersVersion == kCurrentDescriptorParametersVersion
 
&& procs->readDescriptorProcs != NULL
&& procs->readDescriptorProcs->readDescriptorProcsVersion == kCurrentReadDescriptorProcsVersion
&& (unsigned int)(procs->readDescriptorProcs->numReadDescriptorProcs) >= kCurrentReadDescriptorProcsCount
&& procs->readDescriptorProcs->openReadDescriptorProc != NULL
&& procs->readDescriptorProcs->closeReadDescriptorProc != NULL
&& procs->readDescriptorProcs->getKeyProc != NULL
&& procs->readDescriptorProcs->getTextProc != NULL
&& procs->readDescriptorProcs->getIntegerProc != NULL
&& procs->readDescriptorProcs != NULL
&& procs->readDescriptorProcs->readDescriptorProcsVersion == kCurrentReadDescriptorProcsVersion
&& (unsigned int)(procs->readDescriptorProcs->numReadDescriptorProcs) >= kCurrentReadDescriptorProcsCount
&& procs->readDescriptorProcs->openReadDescriptorProc != NULL
&& procs->readDescriptorProcs->closeReadDescriptorProc != NULL
&& procs->readDescriptorProcs->getKeyProc != NULL
&& procs->readDescriptorProcs->getTextProc != NULL
&& procs->readDescriptorProcs->getIntegerProc != NULL
 
&& procs->writeDescriptorProcs != NULL
&& procs->writeDescriptorProcs->writeDescriptorProcsVersion == kCurrentWriteDescriptorProcsVersion
&& (unsigned int)(procs->writeDescriptorProcs->numWriteDescriptorProcs) >= kCurrentWriteDescriptorProcsCount
&& procs->writeDescriptorProcs->openWriteDescriptorProc != NULL
&& procs->writeDescriptorProcs->closeWriteDescriptorProc != NULL
&& procs->writeDescriptorProcs->putTextProc != NULL
&& procs->writeDescriptorProcs->putIntegerProc != NULL ;
&& procs->writeDescriptorProcs != NULL
&& procs->writeDescriptorProcs->writeDescriptorProcsVersion == kCurrentWriteDescriptorProcsVersion
&& (unsigned int)(procs->writeDescriptorProcs->numWriteDescriptorProcs) >= kCurrentWriteDescriptorProcsCount
&& procs->writeDescriptorProcs->openWriteDescriptorProc != NULL
&& procs->writeDescriptorProcs->closeWriteDescriptorProc != NULL
&& procs->writeDescriptorProcs->putTextProc != NULL
&& procs->writeDescriptorProcs->putIntegerProc != NULL;
}
 
 
253,21 → 263,21
//
//-------------------------------------------------------------------------------
 
OSErr HostCloseReader (PIDescriptorParameters *procs,
HandleProcs *hProcs,
PIReadDescriptor *token)
OSErr HostCloseReader(PIDescriptorParameters* procs,
HandleProcs* hProcs,
PIReadDescriptor* token)
{
// Close token:
OSErr err = procs->readDescriptorProcs->closeReadDescriptorProc(*token);
// Close token:
OSErr err = procs->readDescriptorProcs->closeReadDescriptorProc(*token);
 
// Dispose the parameter block descriptor:
hProcs->disposeProc(procs->descriptor);
// Dispose the parameter block descriptor:
hProcs->disposeProc(procs->descriptor);
 
// Set the descriptor and the read token to NULL:
procs->descriptor = NULL;
*token = NULL;
// Set the descriptor and the read token to NULL:
procs->descriptor = NULL;
*token = NULL;
 
return err;
return err;
 
} // end HostCloseReader
 
301,24 → 311,28
//
//-------------------------------------------------------------------------------
 
OSErr HostCloseWriter(PIDescriptorParameters *procs,
HandleProcs *hProcs,
PIWriteDescriptor *token)
OSErr HostCloseWriter(PIDescriptorParameters* procs,
HandleProcs* hProcs,
PIWriteDescriptor* token)
{
OSErr err = noErr; // assume no error
PIDescriptorHandle h = NULL;
OSErr err = noErr; // assume no error
PIDescriptorHandle h = NULL;
 
if (procs->descriptor != NULL) // don't need descriptor passed to us
hProcs->disposeProc(procs->descriptor); // dispose.
procs->writeDescriptorProcs->closeWriteDescriptorProc(*token, &h);
procs->descriptor = h;
if (procs->descriptor != NULL) // don't need descriptor passed to us
hProcs->disposeProc(procs->descriptor); // dispose.
 
// Set recordInfo to default. Options are: plugInDialogOptional,
// plugInDialogRequire, plugInDialogNone:
procs->recordInfo = plugInDialogOptional;
// 3. Call CloseWriteDescriptorProc with writeToken, which will create a PIDescriptorHandle.
procs->writeDescriptorProcs->closeWriteDescriptorProc(*token, &h);
 
*token = NULL;
// 4. Place the PIDescriptorHandle into the descriptor field. The host will dispose of it when finished.
procs->descriptor = h;
 
return err;
// 5. Set recordInfo. Options are: plugInDialogOptional,
// plugInDialogRequire, plugInDialogNone:
procs->recordInfo = plugInDialogOptional;
 
*token = NULL;
 
return err;
 
} // end HostCloseWriter