mirror of https://github.com/snes9xgit/snes9x.git
817 lines
26 KiB
Plaintext
817 lines
26 KiB
Plaintext
/*****************************************************************************\
|
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
This file is licensed under the Snes9x License.
|
|
For further information, consult the LICENSE file in the root directory.
|
|
\*****************************************************************************/
|
|
|
|
/***********************************************************************************
|
|
SNES9X for Mac OS (c) Copyright John Stiles
|
|
|
|
Snes9x for Mac OS X
|
|
|
|
(c) Copyright 2001 - 2011 zones
|
|
(c) Copyright 2002 - 2005 107
|
|
(c) Copyright 2002 PB1400c
|
|
(c) Copyright 2004 Alexander and Sander
|
|
(c) Copyright 2004 - 2005 Steven Seeger
|
|
(c) Copyright 2005 Ryan Vogt
|
|
(c) Copyright 2019 Michael Donald Buckley
|
|
***********************************************************************************/
|
|
|
|
|
|
#import "port.h"
|
|
|
|
#import <Foundation/Foundation.h>
|
|
#import <QuartzCore/QuartzCore.h>
|
|
#import <OpenGL/OpenGL.h>
|
|
|
|
#import "mac-prefix.h"
|
|
#import "mac-dialog.h"
|
|
#import "mac-os.h"
|
|
#import "mac-coreimage.h"
|
|
|
|
enum
|
|
{
|
|
kCITypeNone = 0,
|
|
kCITypeBoolean = 1000,
|
|
kCITypeScalar,
|
|
kCITypeColor
|
|
};
|
|
|
|
#define mCoreImageFilter 501
|
|
#define FIXEDRANGE 0x10000
|
|
#define kCommandFilterMenuBase 0x41000000
|
|
#define kCommandCheckBoxBase 0x49000000
|
|
#define kCommandSliderBase 0x51000000
|
|
#define kCommandColorButtonBase 0x59000000
|
|
#define kCIFilterNamePrefKey CFSTR("CoreImageFilterName")
|
|
|
|
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
|
#define truncEnd 0
|
|
#endif
|
|
|
|
typedef struct {
|
|
char name[256];
|
|
char displayName[256];
|
|
int type;
|
|
union {
|
|
struct {
|
|
bool8 cur;
|
|
} b;
|
|
|
|
struct {
|
|
float max, min, cur;
|
|
} s;
|
|
|
|
struct {
|
|
float r, g, b, a;
|
|
} c;
|
|
} u;
|
|
} FilterParam;
|
|
|
|
static NSMutableArray *ciFilterNameList = NULL;
|
|
static NSMutableArray *ciFilterLocalizedNameList = NULL;
|
|
static NSArray *ciFilterInputKeys = NULL;
|
|
static CIFilter *ciFilter = NULL;
|
|
static CIContext *ciContext = NULL;
|
|
static FilterParam *ciFilterParam = NULL;
|
|
static CFStringRef ciFilterName = NULL;
|
|
static HIViewRef ciFilterUIPane = NULL;
|
|
static MenuRef ciFilterMenu = NULL;
|
|
static CGColorSpaceRef cgColor = NULL;
|
|
static dispatch_semaphore_t cisem = NULL;
|
|
static bool8 ciFilterHasInputCenter = false;
|
|
static bool8 ciFilterHasInputImage = false;
|
|
static int ciFilterInputKeysCount = 0;
|
|
|
|
static void LoadFilterPrefs (void);
|
|
static void SaveFilterPrefs (void);
|
|
static void FilterParamToFilter (void);
|
|
static void FilterToFilterParam (void);
|
|
static void BuildCoreImageFilterListAndMenu (void);
|
|
static void ReleaseCoreImageFilterListAndMenu (void);
|
|
static void ReplaceFilterUI (WindowRef);
|
|
static void FilterUIAddSubviews (WindowRef, HIViewRef);
|
|
static void FilterUISetValues (HIViewRef);
|
|
static bool8 IsCoreImageFilterSupported (CIFilter *);
|
|
static OSStatus CoreImageFilterEventHandler (EventHandlerCallRef, EventRef, void *);
|
|
|
|
|
|
void InitCoreImage (void)
|
|
{
|
|
@autoreleasepool
|
|
{
|
|
ciFilterName = (CFStringRef) CFPreferencesCopyAppValue(kCIFilterNamePrefKey, kCFPreferencesCurrentApplication);
|
|
if (!ciFilterName)
|
|
ciFilterName = CFStringCreateCopy(kCFAllocatorDefault, CFSTR("CIGammaAdjust"));
|
|
|
|
BuildCoreImageFilterListAndMenu();
|
|
|
|
cisem = dispatch_semaphore_create(0);
|
|
}
|
|
}
|
|
|
|
void DeinitCoreImage (void)
|
|
{
|
|
ReleaseCoreImageFilterListAndMenu();
|
|
|
|
CFPreferencesSetAppValue(kCIFilterNamePrefKey, ciFilterName, kCFPreferencesCurrentApplication);
|
|
|
|
CFRelease(ciFilterName);
|
|
}
|
|
|
|
void InitCoreImageFilter (void)
|
|
{
|
|
@autoreleasepool
|
|
{
|
|
ciFilter = [CIFilter filterWithName: (__bridge NSString *) ciFilterName];
|
|
[ciFilter setDefaults];
|
|
|
|
ciFilterInputKeys = [ciFilter inputKeys];
|
|
ciFilterInputKeysCount = [ciFilterInputKeys count];
|
|
|
|
ciFilterParam = new FilterParam [ciFilterInputKeysCount];
|
|
memset(ciFilterParam, 0, sizeof(FilterParam) * ciFilterInputKeysCount);
|
|
|
|
ciFilterHasInputCenter = false;
|
|
ciFilterHasInputImage = false;
|
|
|
|
LoadFilterPrefs();
|
|
}
|
|
}
|
|
|
|
void DeinitCoreImageFilter (void)
|
|
{
|
|
@autoreleasepool
|
|
{
|
|
SaveFilterPrefs();
|
|
|
|
ciFilterHasInputCenter = false;
|
|
ciFilterHasInputImage = false;
|
|
|
|
delete [] ciFilterParam;
|
|
|
|
ciFilterInputKeys = nil;
|
|
ciFilterInputKeysCount = 0;
|
|
|
|
ciFilter = nil;
|
|
}
|
|
}
|
|
|
|
static void LoadFilterPrefs (void)
|
|
{
|
|
CFDataRef data;
|
|
int n = sizeof(FilterParam) * ciFilterInputKeysCount;
|
|
|
|
data = (CFDataRef) CFPreferencesCopyAppValue(ciFilterName, kCFPreferencesCurrentApplication);
|
|
if (data)
|
|
{
|
|
if (CFDataGetLength(data) == n)
|
|
{
|
|
CFDataGetBytes(data, CFRangeMake(0, n), (UInt8 *) ciFilterParam);
|
|
FilterParamToFilter();
|
|
}
|
|
|
|
CFRelease(data);
|
|
}
|
|
|
|
FilterToFilterParam();
|
|
}
|
|
|
|
static void SaveFilterPrefs (void)
|
|
{
|
|
CFDataRef data;
|
|
int n = sizeof(FilterParam) * ciFilterInputKeysCount;
|
|
|
|
data = CFDataCreate(kCFAllocatorDefault, (UInt8 *) ciFilterParam, n);
|
|
if (data)
|
|
{
|
|
CFPreferencesSetAppValue(ciFilterName, data, kCFPreferencesCurrentApplication);
|
|
CFRelease(data);
|
|
}
|
|
}
|
|
|
|
static void FilterParamToFilter (void)
|
|
{
|
|
NSString *key;
|
|
NSNumber *num;
|
|
CIColor *color;
|
|
|
|
for (int i = 0; i < ciFilterInputKeysCount; i++)
|
|
{
|
|
key = [NSString stringWithUTF8String: ciFilterParam[i].name];
|
|
if (key)
|
|
{
|
|
switch (ciFilterParam[i].type)
|
|
{
|
|
case kCITypeBoolean:
|
|
num = [NSNumber numberWithBool: ciFilterParam[i].u.b.cur];
|
|
[ciFilter setValue: num forKey: key];
|
|
break;
|
|
|
|
case kCITypeScalar:
|
|
num = [NSNumber numberWithFloat: ciFilterParam[i].u.s.cur];
|
|
[ciFilter setValue: num forKey: key];
|
|
break;
|
|
|
|
case kCITypeColor:
|
|
color = [CIColor colorWithRed: ciFilterParam[i].u.c.r green: ciFilterParam[i].u.c.g
|
|
blue: ciFilterParam[i].u.c.b alpha: ciFilterParam[i].u.c.a];
|
|
[ciFilter setValue: color forKey: key];
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void FilterToFilterParam (void)
|
|
{
|
|
NSDictionary *attr;
|
|
NSString *key, *label, *className, *typeName;
|
|
NSNumber *num;
|
|
CIColor *color;
|
|
id param;
|
|
|
|
attr = [ciFilter attributes];
|
|
ciFilterHasInputCenter = false;
|
|
ciFilterHasInputImage = false;
|
|
|
|
for (int i = 0; i < ciFilterInputKeysCount; i++)
|
|
{
|
|
key = [ciFilterInputKeys objectAtIndex: i];
|
|
param = [attr objectForKey: key];
|
|
|
|
strncpy(ciFilterParam[i].name, [key UTF8String], sizeof(ciFilterParam[i].name));
|
|
ciFilterParam[i].displayName[0] = 0;
|
|
|
|
if ([param isKindOfClass: [NSDictionary class]])
|
|
{
|
|
label = [(NSDictionary *) param objectForKey: kCIAttributeDisplayName];
|
|
if (!label)
|
|
label = [NSString stringWithString: key];
|
|
strncpy(ciFilterParam[i].displayName, [label UTF8String], sizeof(ciFilterParam[i].displayName));
|
|
|
|
className = [(NSDictionary *) param objectForKey: kCIAttributeClass];
|
|
|
|
if ([className isEqualToString: @"NSNumber"])
|
|
{
|
|
typeName = [(NSDictionary *) param objectForKey: kCIAttributeType];
|
|
|
|
if ([typeName isEqualToString: kCIAttributeTypeBoolean])
|
|
{
|
|
ciFilterParam[i].type = kCITypeBoolean;
|
|
|
|
num = [ciFilter valueForKey: key];
|
|
ciFilterParam[i].u.b.cur = [num boolValue];
|
|
}
|
|
else
|
|
{
|
|
ciFilterParam[i].type = kCITypeScalar;
|
|
|
|
num = [ciFilter valueForKey: key];
|
|
ciFilterParam[i].u.s.cur = [num floatValue];
|
|
|
|
num = [(NSDictionary *) param objectForKey: kCIAttributeSliderMax];
|
|
if (!num)
|
|
num = [(NSDictionary *) param objectForKey: kCIAttributeMax];
|
|
ciFilterParam[i].u.s.max = [num floatValue];
|
|
|
|
num = [(NSDictionary *) param objectForKey: kCIAttributeSliderMin];
|
|
if (!num)
|
|
num = [(NSDictionary *) param objectForKey: kCIAttributeMin];
|
|
ciFilterParam[i].u.s.min = [num floatValue];
|
|
}
|
|
}
|
|
else
|
|
if ([className isEqualToString: @"CIColor"])
|
|
{
|
|
ciFilterParam[i].type = kCITypeColor;
|
|
|
|
color = [ciFilter valueForKey: key];
|
|
ciFilterParam[i].u.c.r = [color red];
|
|
ciFilterParam[i].u.c.g = [color green];
|
|
ciFilterParam[i].u.c.b = [color blue];
|
|
ciFilterParam[i].u.c.a = [color alpha];
|
|
}
|
|
else
|
|
{
|
|
ciFilterParam[i].type = kCITypeNone;
|
|
|
|
if ([className isEqualToString: @"CIVector"] && [key isEqualToString: @"inputCenter"])
|
|
ciFilterHasInputCenter = true;
|
|
|
|
if ([className isEqualToString: @"CIImage" ] && [key isEqualToString: @"inputImage" ])
|
|
ciFilterHasInputImage = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void BuildCoreImageFilterListAndMenu (void)
|
|
{
|
|
// NSArray *categories, *filterNames;
|
|
// OSStatus err;
|
|
//
|
|
// categories = [NSArray arrayWithObject: kCICategoryStillImage];
|
|
// filterNames = [CIFilter filterNamesInCategories: categories];
|
|
//
|
|
// ciFilterNameList = [[NSMutableArray alloc] initWithCapacity: 1];
|
|
// ciFilterLocalizedNameList = [[NSMutableArray alloc] initWithCapacity: 1];
|
|
// err = CreateNewMenu(mCoreImageFilter, 0, &ciFilterMenu);
|
|
//
|
|
// int n = [filterNames count], m = 0;
|
|
// for (int i = 0; i < n; i++)
|
|
// {
|
|
// CIFilter *filter;
|
|
// NSString *name, *localName;
|
|
//
|
|
// name = [filterNames objectAtIndex: i];
|
|
// filter = [CIFilter filterWithName: name];
|
|
//
|
|
// if (IsCoreImageFilterSupported(filter))
|
|
// {
|
|
// [ciFilterNameList addObject: name];
|
|
//
|
|
// localName = [CIFilter localizedNameForFilterName: name];
|
|
// if (!localName)
|
|
// localName = [NSString stringWithString: name];
|
|
//
|
|
// [ciFilterLocalizedNameList addObject: localName];
|
|
//
|
|
// err = AppendMenuItemTextWithCFString(ciFilterMenu, (CFStringRef) localName, 0, kCommandFilterMenuBase + m, NULL);
|
|
// m++;
|
|
// }
|
|
// }
|
|
}
|
|
|
|
static void ReleaseCoreImageFilterListAndMenu (void)
|
|
{
|
|
CFRelease(ciFilterMenu);
|
|
ciFilterLocalizedNameList = nil;
|
|
ciFilterNameList = nil;
|
|
}
|
|
|
|
static bool8 IsCoreImageFilterSupported (CIFilter *filter)
|
|
{
|
|
NSDictionary *attr;
|
|
NSArray *inputKeys;
|
|
NSString *key, *className;
|
|
id param;
|
|
bool8 result = true, hasInputImage = false;
|
|
|
|
attr = [filter attributes];
|
|
inputKeys = [filter inputKeys];
|
|
|
|
int n = [inputKeys count];
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
key = [inputKeys objectAtIndex: i];
|
|
param = [attr objectForKey: key];
|
|
|
|
if ([param isKindOfClass: [NSDictionary class]])
|
|
{
|
|
className = [(NSDictionary *) param objectForKey: kCIAttributeClass];
|
|
|
|
if ([className isEqualToString: @"CIImage"])
|
|
{
|
|
if (![key isEqualToString: @"inputImage"])
|
|
result = false;
|
|
else
|
|
hasInputImage = true;
|
|
}
|
|
else
|
|
if ([className isEqualToString: @"CIVector"])
|
|
{
|
|
if (![key isEqualToString: @"inputCenter"])
|
|
result = false;
|
|
}
|
|
else
|
|
if (![className isEqualToString: @"NSNumber"] && ![className isEqualToString: @"CIColor"])
|
|
result = false;
|
|
}
|
|
}
|
|
|
|
if (hasInputImage == false)
|
|
result = false;
|
|
|
|
return (result);
|
|
}
|
|
|
|
void ConfigureCoreImageFilter (void)
|
|
{
|
|
// NSAutoreleasePool *pool;
|
|
// OSStatus err;
|
|
// IBNibRef nibRef;
|
|
//
|
|
// pool = [[NSAutoreleasePool alloc] init];
|
|
//
|
|
// err = CreateNibReference(kMacS9XCFString, &nibRef);
|
|
// if (err == noErr)
|
|
// {
|
|
// WindowRef window;
|
|
//
|
|
// err = CreateWindowFromNib(nibRef, CFSTR("CIFilter"), &window);
|
|
// if (err == noErr)
|
|
// {
|
|
// EventHandlerRef eref;
|
|
// EventHandlerUPP eUPP;
|
|
// EventTypeSpec event[] = { { kEventClassWindow, kEventWindowClose },
|
|
// { kEventClassCommand, kEventCommandProcess },
|
|
// { kEventClassCommand, kEventCommandUpdateStatus } };
|
|
// HIViewRef ctl, root;
|
|
// HIViewID cid;
|
|
// Rect rct;
|
|
// int value;
|
|
//
|
|
// ciFilterUIPane = NULL;
|
|
//
|
|
// FilterToFilterParam();
|
|
//
|
|
// root = HIViewGetRoot(window);
|
|
//
|
|
// SetHIViewID(&cid, 'FILT', 0);
|
|
// rct.left = 74;
|
|
// rct.top = 20;
|
|
// rct.right = 74 + 279;
|
|
// rct.bottom = 20 + 20;
|
|
// err = CreatePopupButtonControl(window, &rct, NULL, -12345, false, 0, 0, 0, &ctl);
|
|
// HIViewSetID(ctl, cid);
|
|
// int n = CountMenuItems(ciFilterMenu);
|
|
// SetControlPopupMenuHandle(ctl, ciFilterMenu);
|
|
// HIViewSetMaximum(ctl, n);
|
|
// value = [ciFilterNameList indexOfObject: (NSString *) ciFilterName];
|
|
// HIViewSetValue(ctl, value + 1);
|
|
//
|
|
// ReplaceFilterUI(window);
|
|
//
|
|
// eUPP = NewEventHandlerUPP(CoreImageFilterEventHandler);
|
|
// err = InstallWindowEventHandler(window, eUPP, GetEventTypeCount(event), event, (void *) window, &eref);
|
|
//
|
|
// MoveWindowPosition(window, kWindowCoreImageFilter, false);
|
|
// ShowWindow(window);
|
|
// err = RunAppModalLoopForWindow(window);
|
|
// HideWindow(window);
|
|
// SaveWindowPosition(window, kWindowCoreImageFilter);
|
|
//
|
|
// err = RemoveEventHandler(eref);
|
|
// DisposeEventHandlerUPP(eUPP);
|
|
//
|
|
// FilterParamToFilter();
|
|
//
|
|
// CFRelease(window);
|
|
// }
|
|
//
|
|
// DisposeNibReference(nibRef);
|
|
// }
|
|
//
|
|
// [pool release];
|
|
}
|
|
|
|
static void ReplaceFilterUI (WindowRef window)
|
|
{
|
|
// OSStatus err;
|
|
// HIRect frame;
|
|
// Rect bounds, rct;
|
|
//
|
|
// if (ciFilterUIPane)
|
|
// {
|
|
// HIViewSetVisible(ciFilterUIPane, false);
|
|
// DisposeControl(ciFilterUIPane);
|
|
// ciFilterUIPane = NULL;
|
|
// }
|
|
//
|
|
// GetWindowBounds(window, kWindowStructureRgn, &bounds);
|
|
//
|
|
// rct.left = 15;
|
|
// rct.right = bounds.right - bounds.left - 15;
|
|
// rct.top = 81;
|
|
// rct.bottom = rct.top + 40;
|
|
// err = CreateUserPaneControl(window, &rct, kControlSupportsEmbedding, &ciFilterUIPane);
|
|
// HIViewSetVisible(ciFilterUIPane, false);
|
|
// FilterUIAddSubviews(window, ciFilterUIPane);
|
|
//
|
|
// HIViewGetFrame(ciFilterUIPane, &frame);
|
|
// bounds.bottom = bounds.top + (short) (frame.origin.y + frame.size.height + 30);
|
|
//
|
|
// err = TransitionWindow(window, kWindowSlideTransitionEffect, kWindowResizeTransitionAction, &bounds);
|
|
// HIViewSetVisible(ciFilterUIPane, true);
|
|
}
|
|
|
|
static void FilterUIAddSubviews (WindowRef window, HIViewRef parent)
|
|
{
|
|
// OSStatus err;
|
|
// CFMutableStringRef label;
|
|
// CFStringRef str;
|
|
// HIViewRef ctl;
|
|
// HIViewID cid;
|
|
// HIRect bounds, frame;
|
|
// Rect rct;
|
|
// SInt32 value;
|
|
//
|
|
// HIViewGetFrame(parent, &bounds);
|
|
// rct.left = 0;
|
|
// rct.top = 0;
|
|
// rct.right = 200;
|
|
// rct.bottom = 20;
|
|
//
|
|
// int m = 0;
|
|
// for (int i = 0; i < ciFilterInputKeysCount; i++)
|
|
// {
|
|
// str = CFStringCreateWithCString(kCFAllocatorDefault, ciFilterParam[i].displayName, kCFStringEncodingUTF8);
|
|
// if (!str)
|
|
// str = CFStringCreateCopy(kCFAllocatorDefault, CFSTR("Parameter"));
|
|
// label = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, str);
|
|
// CFRelease(str);
|
|
//
|
|
// switch (ciFilterParam[i].type)
|
|
// {
|
|
// case kCITypeBoolean:
|
|
// {
|
|
// err = CreateCheckBoxControl(window, &rct, label, ciFilterParam[i].u.b.cur, true, &ctl);
|
|
// SetHIViewID(&cid, kCommandCheckBoxBase + i, i);
|
|
// HIViewSetID(ctl, cid);
|
|
// HIViewSetCommandID(ctl, cid.signature);
|
|
// err = HIViewAddSubview(parent, ctl);
|
|
// frame.origin.x = 5.0f;
|
|
// frame.origin.y = (float) (m * 28);
|
|
// frame.size.width = bounds.size.width - 10.0f;
|
|
// frame.size.height = 20.0f;
|
|
// err = HIViewSetFrame(ctl, &frame);
|
|
// m++;
|
|
//
|
|
// break;
|
|
// }
|
|
//
|
|
// case kCITypeScalar:
|
|
// {
|
|
// CFStringAppend(label, CFSTR(" :"));
|
|
// err = CreateStaticTextControl(window, &rct, label, NULL, &ctl);
|
|
// SetStaticTextTrunc(ctl, truncEnd, true);
|
|
// err = HIViewAddSubview(parent, ctl);
|
|
// frame.origin.x = 5.0f;
|
|
// frame.origin.y = (float) (m * 28);
|
|
// frame.size.width = 120.0f;
|
|
// frame.size.height = 20.0f;
|
|
// err = HIViewSetFrame(ctl, &frame);
|
|
//
|
|
// value = (SInt32) ((ciFilterParam[i].u.s.cur - ciFilterParam[i].u.s.min) / (ciFilterParam[i].u.s.max - ciFilterParam[i].u.s.min) * (float) FIXEDRANGE);
|
|
// err = CreateSliderControl(window, &rct, value, 0, FIXEDRANGE, kControlSliderDoesNotPoint, 0, false, NULL, &ctl);
|
|
// SetHIViewID(&cid, kCommandSliderBase + i, i);
|
|
// HIViewSetID(ctl, cid);
|
|
// HIViewSetCommandID(ctl, cid.signature);
|
|
// err = HIViewAddSubview(parent, ctl);
|
|
// frame.origin.x = 135.0f;
|
|
// frame.origin.y = (float) (m * 28) - 1.0f;
|
|
// frame.size.width = bounds.size.width - 140.0f;
|
|
// frame.size.height = 20.0f;
|
|
// err = HIViewSetFrame(ctl, &frame);
|
|
// m++;
|
|
//
|
|
// break;
|
|
// }
|
|
//
|
|
// case kCITypeColor:
|
|
// {
|
|
// CFStringAppend(label, CFSTR("..."));
|
|
// err = CreatePushButtonControl(window, &rct, label, &ctl);
|
|
// SetHIViewID(&cid, kCommandColorButtonBase + i, i);
|
|
// HIViewSetID(ctl, cid);
|
|
// HIViewSetCommandID(ctl, cid.signature);
|
|
// err = HIViewAddSubview(parent, ctl);
|
|
// frame.origin.x = bounds.size.width - 180.0f;
|
|
// frame.origin.y = (float) (m * 28);
|
|
// frame.size.width = 175.0f;
|
|
// frame.size.height = 20.0f;
|
|
// err = HIViewSetFrame(ctl, &frame);
|
|
// m++;
|
|
//
|
|
// break;
|
|
// }
|
|
//
|
|
// default:
|
|
// break;
|
|
// }
|
|
//
|
|
// CFRelease(label);
|
|
// }
|
|
//
|
|
// if (m)
|
|
// {
|
|
// str = CFCopyLocalizedString(CFSTR("ResetCIFilter"), "Reset");
|
|
// err = CreatePushButtonControl(window, &rct, str, &ctl);
|
|
// SetHIViewID(&cid, 'rSET', 0);
|
|
// HIViewSetID(ctl, cid);
|
|
// HIViewSetCommandID(ctl, cid.signature);
|
|
// err = HIViewAddSubview(parent, ctl);
|
|
// frame.origin.x = bounds.size.width - 180.0f;
|
|
// frame.origin.y = (float) (m * 28 + 12);
|
|
// frame.size.width = 175.0f;
|
|
// frame.size.height = 20.0f;
|
|
// err = HIViewSetFrame(ctl, &frame);
|
|
// CFRelease(str);
|
|
// bounds.size.height = frame.origin.y + 32.0f;
|
|
// }
|
|
// else
|
|
// bounds.size.height = 4.0f;
|
|
//
|
|
// err = HIViewSetFrame(parent, &bounds);
|
|
}
|
|
|
|
static void FilterUISetValues (HIViewRef parent)
|
|
{
|
|
// HIViewRef ctl;
|
|
// HIViewID cid;
|
|
// SInt32 value;
|
|
//
|
|
// for (int i = 0; i < ciFilterInputKeysCount; i++)
|
|
// {
|
|
// switch (ciFilterParam[i].type)
|
|
// {
|
|
// case kCITypeBoolean:
|
|
// SetHIViewID(&cid, kCommandCheckBoxBase + i, i);
|
|
// HIViewFindByID(parent, cid, &ctl);
|
|
// HIViewSetValue(ctl, ciFilterParam[i].u.b.cur);
|
|
// break;
|
|
//
|
|
// case kCITypeScalar:
|
|
// value = (SInt32) ((ciFilterParam[i].u.s.cur - ciFilterParam[i].u.s.min) / (ciFilterParam[i].u.s.max - ciFilterParam[i].u.s.min) * (float) FIXEDRANGE);
|
|
// SetHIViewID(&cid, kCommandSliderBase + i, i);
|
|
// HIViewFindByID(parent, cid, &ctl);
|
|
// HIViewSetValue(ctl, value);
|
|
// break;
|
|
//
|
|
// default:
|
|
// break;
|
|
// }
|
|
// }
|
|
}
|
|
|
|
static OSStatus CoreImageFilterEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
|
|
{
|
|
// OSStatus err, result = eventNotHandledErr;
|
|
// WindowRef window = (WindowRef) inUserData;
|
|
//
|
|
// switch (GetEventClass(inEvent))
|
|
// {
|
|
// case kEventClassWindow:
|
|
// switch (GetEventKind(inEvent))
|
|
// {
|
|
// case kEventWindowClose:
|
|
// QuitAppModalLoopForWindow(window);
|
|
// result = noErr;
|
|
// }
|
|
//
|
|
// break;
|
|
//
|
|
// case kEventClassCommand:
|
|
// switch (GetEventKind(inEvent))
|
|
// {
|
|
// HICommandExtended tHICommand;
|
|
//
|
|
// case kEventCommandUpdateStatus:
|
|
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommandExtended), NULL, &tHICommand);
|
|
// if (err == noErr && tHICommand.commandID == 'clos')
|
|
// {
|
|
// UpdateMenuCommandStatus(true);
|
|
// result = noErr;
|
|
// }
|
|
//
|
|
// break;
|
|
//
|
|
// case kEventCommandProcess:
|
|
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommandExtended), NULL, &tHICommand);
|
|
// if (err == noErr)
|
|
// {
|
|
// err = MPWaitOnSemaphore(cisem, kDurationForever);
|
|
//
|
|
// if (tHICommand.commandID == 'rSET')
|
|
// {
|
|
// [ciFilter setDefaults];
|
|
// FilterToFilterParam();
|
|
// FilterUISetValues(ciFilterUIPane);
|
|
//
|
|
// result = noErr;
|
|
// }
|
|
// else
|
|
// {
|
|
// unsigned long i = tHICommand.commandID & 0x00FFFFFF;
|
|
//
|
|
// switch (tHICommand.commandID & 0xFF000000)
|
|
// {
|
|
// case kCommandFilterMenuBase:
|
|
// DeinitCoreImageFilter();
|
|
//
|
|
// CFRelease(ciFilterName);
|
|
// ciFilterName = CFStringCreateCopy(kCFAllocatorDefault, (CFStringRef) [ciFilterNameList objectAtIndex: i]);
|
|
//
|
|
// InitCoreImageFilter();
|
|
//
|
|
// ReplaceFilterUI(window);
|
|
//
|
|
// break;
|
|
//
|
|
// case kCommandCheckBoxBase:
|
|
// ciFilterParam[i].u.b.cur = !(ciFilterParam[i].u.b.cur);
|
|
// FilterParamToFilter();
|
|
// result = noErr;
|
|
//
|
|
// break;
|
|
//
|
|
// case kCommandSliderBase:
|
|
// SInt32 value;
|
|
//
|
|
// value = HIViewGetValue(tHICommand.source.control);
|
|
// ciFilterParam[i].u.s.cur = ciFilterParam[i].u.s.min + (ciFilterParam[i].u.s.max - ciFilterParam[i].u.s.min) * (float) value / (float) FIXEDRANGE;
|
|
// FilterParamToFilter();
|
|
// result = noErr;
|
|
//
|
|
// break;
|
|
//
|
|
// case kCommandColorButtonBase:
|
|
// NColorPickerInfo info;
|
|
//
|
|
// memset(&info, 0, sizeof(NColorPickerInfo));
|
|
// info.placeWhere = kCenterOnMainScreen;
|
|
// info.flags = kColorPickerDialogIsMoveable | kColorPickerDialogIsModal;
|
|
// info.theColor.color.rgb.red = (int) (65535.0 * ciFilterParam[i].u.c.r);
|
|
// info.theColor.color.rgb.green = (int) (65535.0 * ciFilterParam[i].u.c.g);
|
|
// info.theColor.color.rgb.blue = (int) (65535.0 * ciFilterParam[i].u.c.b);
|
|
//
|
|
// err = NPickColor(&info);
|
|
//
|
|
// if ((err == noErr) && info.newColorChosen)
|
|
// {
|
|
// ciFilterParam[i].u.c.r = (float) info.theColor.color.rgb.red / 65535.0f;
|
|
// ciFilterParam[i].u.c.g = (float) info.theColor.color.rgb.green / 65535.0f;
|
|
// ciFilterParam[i].u.c.b = (float) info.theColor.color.rgb.blue / 65535.0f;
|
|
// }
|
|
//
|
|
// FilterParamToFilter();
|
|
// result = noErr;
|
|
//
|
|
// break;
|
|
// }
|
|
// }
|
|
//
|
|
// err = MPSignalSemaphore(cisem);
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// return (result);
|
|
return 0;
|
|
}
|
|
|
|
void InitCoreImageContext (CGLContextObj cglctx, CGLPixelFormatObj cglpix)
|
|
{
|
|
@autoreleasepool
|
|
{
|
|
FilterToFilterParam();
|
|
|
|
cgColor = CGColorSpaceCreateDeviceRGB();
|
|
|
|
#ifdef MAC_LEOPARD_TIGER_PANTHER_SUPPORT
|
|
ciContext = [[CIContext contextWithCGLContext: cglctx pixelFormat: cglpix options: NULL] retain];
|
|
#else
|
|
ciContext = [CIContext contextWithCGLContext: cglctx pixelFormat: cglpix colorSpace: cgColor options: NULL];
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void DeinitCoreImageContext (void)
|
|
{
|
|
ciContext = nil;
|
|
CGColorSpaceRelease(cgColor);
|
|
}
|
|
|
|
void DrawWithCoreImageFilter (CGRect src, CGImageRef img)
|
|
{
|
|
@autoreleasepool
|
|
{
|
|
dispatch_semaphore_wait(cisem, DISPATCH_TIME_FOREVER);
|
|
|
|
if (ciFilterHasInputImage)
|
|
{
|
|
CIImage *image;
|
|
|
|
image = [CIImage imageWithCGImage: img];
|
|
[ciFilter setValue: image forKey: @"inputImage" ];
|
|
}
|
|
|
|
if (ciFilterHasInputCenter)
|
|
{
|
|
CIVector *vector;
|
|
|
|
vector = [CIVector vectorWithX: (src.origin.x + src.size.width / 2) Y: (src.origin.y + src.size.height / 2)];
|
|
[ciFilter setValue: vector forKey: @"inputCenter"];
|
|
}
|
|
|
|
[ciContext drawImage: [ciFilter valueForKey: @"outputImage"] atPoint: CGPointZero fromRect: src];
|
|
|
|
dispatch_semaphore_signal(cisem);
|
|
}
|
|
}
|