mirror of https://github.com/snes9xgit/snes9x.git
541 lines
23 KiB
Plaintext
541 lines
23 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
|
|
***********************************************************************************/
|
|
|
|
|
|
#include "port.h"
|
|
|
|
#include "mac-prefix.h"
|
|
#include "mac-cart.h"
|
|
#include "mac-dialog.h"
|
|
#include "mac-os.h"
|
|
#include "mac-multicart.h"
|
|
|
|
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
|
#define truncEnd 0
|
|
#endif
|
|
|
|
static OSStatus MultiCartEventHandler (EventHandlerCallRef, EventRef, void *);
|
|
static OSStatus MultiCartPaneEventHandler (EventHandlerCallRef, EventRef, void *);
|
|
|
|
static int multiCartDragHilite;
|
|
static Boolean multiCartDialogResult;
|
|
|
|
void InitMultiCart (void)
|
|
{
|
|
CFStringRef keyRef, pathRef;
|
|
char key[32];
|
|
|
|
multiCartPath[0] = multiCartPath[1] = NULL;
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
sprintf(key, "MultiCartPath_%02d", i);
|
|
keyRef = CFStringCreateWithCString(kCFAllocatorDefault, key, CFStringGetSystemEncoding());
|
|
if (keyRef)
|
|
{
|
|
pathRef = (CFStringRef) CFPreferencesCopyAppValue(keyRef, kCFPreferencesCurrentApplication);
|
|
if (pathRef)
|
|
multiCartPath[i] = pathRef;
|
|
|
|
CFRelease(keyRef);
|
|
}
|
|
}
|
|
}
|
|
|
|
void DeinitMultiCart (void)
|
|
{
|
|
CFStringRef keyRef;
|
|
char key[32];
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
sprintf(key, "MultiCartPath_%02d", i);
|
|
keyRef = CFStringCreateWithCString(kCFAllocatorDefault, key, CFStringGetSystemEncoding());
|
|
if (keyRef)
|
|
{
|
|
if (multiCartPath[i])
|
|
{
|
|
CFPreferencesSetAppValue(keyRef, multiCartPath[i], kCFPreferencesCurrentApplication);
|
|
CFRelease(multiCartPath[i]);
|
|
}
|
|
else
|
|
CFPreferencesSetAppValue(keyRef, NULL, kCFPreferencesCurrentApplication);
|
|
|
|
CFRelease(keyRef);
|
|
}
|
|
}
|
|
|
|
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
|
|
}
|
|
|
|
Boolean MultiCartDialog (void)
|
|
{
|
|
// OSStatus err;
|
|
// IBNibRef nibRef;
|
|
//
|
|
// multiCartDragHilite = -1;
|
|
// multiCartDialogResult = false;
|
|
//
|
|
// err = CreateNibReference(kMacS9XCFString, &nibRef);
|
|
// if (err == noErr)
|
|
// {
|
|
// WindowRef window;
|
|
//
|
|
// err = CreateWindowFromNib(nibRef, CFSTR("MultiCart"), &window);
|
|
// if (err == noErr)
|
|
// {
|
|
// static int index[2] = { 0, 1 };
|
|
//
|
|
// EventHandlerRef wRef, cRef[2];
|
|
// EventHandlerUPP wUPP, cUPP[2];
|
|
// EventTypeSpec wEvent[] = { { kEventClassCommand, kEventCommandProcess },
|
|
// { kEventClassCommand, kEventCommandUpdateStatus } },
|
|
// cEvent[] = { { kEventClassControl, kEventControlDraw },
|
|
// { kEventClassControl, kEventControlDragEnter },
|
|
// { kEventClassControl, kEventControlDragWithin },
|
|
// { kEventClassControl, kEventControlDragLeave },
|
|
// { kEventClassControl, kEventControlDragReceive } };
|
|
// HIViewRef ctl, root, pane[2];
|
|
// HIViewID cid;
|
|
//
|
|
// root = HIViewGetRoot(window);
|
|
//
|
|
// wUPP = NewEventHandlerUPP(MultiCartEventHandler);
|
|
// err = InstallWindowEventHandler(window, wUPP, GetEventTypeCount(wEvent), wEvent, (void *) window, &wRef);
|
|
// err = SetAutomaticControlDragTrackingEnabledForWindow(window, true);
|
|
//
|
|
// for (int i = 0; i < 2; i++)
|
|
// {
|
|
// cid.id = i;
|
|
//
|
|
// cid.signature = 'MPan';
|
|
// HIViewFindByID(root, cid, &pane[i]);
|
|
// cUPP[i] = NewEventHandlerUPP(MultiCartPaneEventHandler);
|
|
// err = InstallControlEventHandler(pane[i], cUPP[i], GetEventTypeCount(cEvent), cEvent, (void *) &index[i], &cRef[i]);
|
|
// err = SetControlDragTrackingEnabled(pane[i], true);
|
|
//
|
|
// cid.signature = 'MNAM';
|
|
// HIViewFindByID(root, cid, &ctl);
|
|
// SetStaticTextTrunc(ctl, truncEnd, false);
|
|
// if (multiCartPath[i])
|
|
// {
|
|
// CFStringRef str;
|
|
// CFURLRef url;
|
|
//
|
|
// url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, multiCartPath[i], kCFURLPOSIXPathStyle, false);
|
|
// str = CFURLCopyLastPathComponent(url);
|
|
// SetStaticTextCFString(ctl, str, false);
|
|
// CFRelease(str);
|
|
// CFRelease(url);
|
|
// }
|
|
// else
|
|
// SetStaticTextCFString(ctl, CFSTR(""), false);
|
|
// }
|
|
//
|
|
// MoveWindowPosition(window, kWindowMultiCart, false);
|
|
// ShowWindow(window);
|
|
// err = RunAppModalLoopForWindow(window);
|
|
// HideWindow(window);
|
|
// SaveWindowPosition(window, kWindowMultiCart);
|
|
//
|
|
// for (int i = 0; i < 2; i++)
|
|
// {
|
|
// err = RemoveEventHandler(cRef[i]);
|
|
// DisposeEventHandlerUPP(cUPP[i]);
|
|
// }
|
|
//
|
|
// err = RemoveEventHandler(wRef);
|
|
// DisposeEventHandlerUPP(wUPP);
|
|
//
|
|
// CFRelease(window);
|
|
// }
|
|
//
|
|
// DisposeNibReference(nibRef);
|
|
// }
|
|
//
|
|
// return (multiCartDialogResult);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static OSStatus MultiCartEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
|
|
{
|
|
// OSStatus err, result = eventNotHandledErr;
|
|
// WindowRef window = (WindowRef) inUserData;
|
|
// static int index = -1;
|
|
//
|
|
// switch (GetEventClass(inEvent))
|
|
// {
|
|
// case kEventClassCommand:
|
|
// {
|
|
// switch (GetEventKind(inEvent))
|
|
// {
|
|
// HICommand tHICommand;
|
|
//
|
|
// case kEventCommandUpdateStatus:
|
|
// {
|
|
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
|
|
// if (err == noErr && tHICommand.commandID == 'clos')
|
|
// {
|
|
// UpdateMenuCommandStatus(false);
|
|
// result = noErr;
|
|
// }
|
|
//
|
|
// break;
|
|
// }
|
|
//
|
|
// case kEventCommandProcess:
|
|
// {
|
|
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
|
|
// if (err == noErr)
|
|
// {
|
|
// HIViewRef ctl, root;
|
|
// HIViewID cid;
|
|
// FSRef ref;
|
|
// bool8 r;
|
|
//
|
|
// root = HIViewGetRoot(window);
|
|
//
|
|
// switch (tHICommand.commandID)
|
|
// {
|
|
// case 'Cho0':
|
|
// case 'Cho1':
|
|
// {
|
|
// index = (tHICommand.commandID & 0xFF) - '0';
|
|
// // r = NavBeginOpenROMImageSheet(window, NULL);
|
|
// result = noErr;
|
|
// break;
|
|
// }
|
|
//
|
|
// case 'NvDn':
|
|
// {
|
|
// r = NavEndOpenROMImageSheet(&ref);
|
|
// if (r)
|
|
// {
|
|
// CFStringRef str;
|
|
// CFURLRef url;
|
|
//
|
|
// url = CFURLCreateFromFSRef(kCFAllocatorDefault, &ref);
|
|
// str = CFURLCopyLastPathComponent(url);
|
|
// cid.signature = 'MNAM';
|
|
// cid.id = index;
|
|
// HIViewFindByID(root, cid, &ctl);
|
|
// SetStaticTextCFString(ctl, str, true);
|
|
// CFRelease(str);
|
|
// str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
|
|
// if (multiCartPath[index])
|
|
// CFRelease(multiCartPath[index]);
|
|
// multiCartPath[index] = str;
|
|
// CFRelease(url);
|
|
// }
|
|
//
|
|
// index = -1;
|
|
// result = noErr;
|
|
// break;
|
|
// }
|
|
//
|
|
// case 'Cle0':
|
|
// case 'Cle1':
|
|
// {
|
|
// index = (tHICommand.commandID & 0xFF) - '0';
|
|
// cid.signature = 'MNAM';
|
|
// cid.id = index;
|
|
// HIViewFindByID(root, cid, &ctl);
|
|
// SetStaticTextCFString(ctl, CFSTR(""), true);
|
|
// if (multiCartPath[index])
|
|
// {
|
|
// CFRelease(multiCartPath[index]);
|
|
// multiCartPath[index] = NULL;
|
|
// }
|
|
//
|
|
// index = -1;
|
|
// result = noErr;
|
|
// break;
|
|
// }
|
|
//
|
|
// case 'SWAP':
|
|
// {
|
|
// CFStringRef str;
|
|
// CFURLRef url;
|
|
//
|
|
// str = multiCartPath[0];
|
|
// multiCartPath[0] = multiCartPath[1];
|
|
// multiCartPath[1] = str;
|
|
//
|
|
// cid.signature = 'MNAM';
|
|
//
|
|
// for (int i = 0; i < 2; i++)
|
|
// {
|
|
// cid.id = i;
|
|
// HIViewFindByID(root, cid, &ctl);
|
|
//
|
|
// if (multiCartPath[i])
|
|
// {
|
|
// url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, multiCartPath[i], kCFURLPOSIXPathStyle, false);
|
|
// str = CFURLCopyLastPathComponent(url);
|
|
// SetStaticTextCFString(ctl, str, true);
|
|
// CFRelease(str);
|
|
// CFRelease(url);
|
|
// }
|
|
// else
|
|
// SetStaticTextCFString(ctl, CFSTR(""), true);
|
|
// }
|
|
//
|
|
// result = noErr;
|
|
// break;
|
|
// }
|
|
//
|
|
// case 'ok ':
|
|
// {
|
|
// QuitAppModalLoopForWindow(window);
|
|
// multiCartDialogResult = true;
|
|
// result = noErr;
|
|
// break;
|
|
// }
|
|
//
|
|
// case 'not!':
|
|
// {
|
|
// QuitAppModalLoopForWindow(window);
|
|
// multiCartDialogResult = false;
|
|
// result = noErr;
|
|
// break;
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// return (result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static OSStatus MultiCartPaneEventHandler (EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
|
|
{
|
|
// OSStatus err, result = eventNotHandledErr;
|
|
// HIViewRef view;
|
|
// DragRef drag;
|
|
// PasteboardRef pasteboard;
|
|
// PasteboardItemID itemID;
|
|
// CFArrayRef array;
|
|
// CFStringRef flavorType;
|
|
// CFIndex numFlavors;
|
|
// ItemCount numItems;
|
|
// int index = *((int *) inUserData);
|
|
//
|
|
// switch (GetEventClass(inEvent))
|
|
// {
|
|
// case kEventClassControl:
|
|
// {
|
|
// switch (GetEventKind(inEvent))
|
|
// {
|
|
// case kEventControlDraw:
|
|
// {
|
|
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
|
|
// if (err == noErr)
|
|
// {
|
|
// CGContextRef ctx;
|
|
//
|
|
// err = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(CGContextRef), NULL, &ctx);
|
|
// if (err == noErr)
|
|
// {
|
|
// HIThemeFrameDrawInfo info;
|
|
// HIRect bounds, frame;
|
|
//
|
|
// HIViewGetBounds(view, &bounds);
|
|
//
|
|
// CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f);
|
|
// CGContextFillRect(ctx, bounds);
|
|
//
|
|
// info.version = 0;
|
|
// info.kind = kHIThemeFrameTextFieldSquare;
|
|
// info.state = kThemeStateInactive;
|
|
// info.isFocused = false;
|
|
// err = HIThemeDrawFrame(&bounds, &info, ctx, kHIThemeOrientationNormal);
|
|
//
|
|
// if (multiCartDragHilite == index && systemVersion >= 0x1040)
|
|
// {
|
|
// err = HIThemeSetStroke(kThemeBrushDragHilite, NULL, ctx, kHIThemeOrientationNormal);
|
|
// frame = CGRectInset(bounds, 1, 1);
|
|
// CGContextBeginPath(ctx);
|
|
// CGContextAddRect(ctx, frame);
|
|
// CGContextStrokePath(ctx);
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// result = noErr;
|
|
// break;
|
|
// }
|
|
//
|
|
// case kEventControlDragEnter:
|
|
// {
|
|
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
|
|
// if (err == noErr)
|
|
// {
|
|
// err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag);
|
|
// if (err == noErr)
|
|
// {
|
|
// err = GetDragPasteboard(drag, &pasteboard);
|
|
// if (err == noErr)
|
|
// {
|
|
// err = PasteboardGetItemCount(pasteboard, &numItems);
|
|
// if (err == noErr && numItems == 1)
|
|
// {
|
|
// err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID);
|
|
// if (err == noErr)
|
|
// {
|
|
// err = PasteboardCopyItemFlavors(pasteboard, itemID, &array);
|
|
// if (err == noErr)
|
|
// {
|
|
// numFlavors = CFArrayGetCount(array);
|
|
// for (CFIndex i = 0; i < numFlavors; i++)
|
|
// {
|
|
// flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i);
|
|
// if (UTTypeConformsTo(flavorType, CFSTR("public.file-url")))
|
|
// {
|
|
// Boolean accept = true;
|
|
//
|
|
// err = SetEventParameter(inEvent, kEventParamControlWouldAcceptDrop, typeBoolean, sizeof(Boolean), &accept);
|
|
// if (err == noErr)
|
|
// {
|
|
// multiCartDragHilite = index;
|
|
// HIViewSetNeedsDisplay(view, true);
|
|
// result = noErr;
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// CFRelease(array);
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// break;
|
|
// }
|
|
//
|
|
// case kEventControlDragWithin:
|
|
// {
|
|
// result = noErr;
|
|
// break;
|
|
// }
|
|
//
|
|
// case kEventControlDragLeave:
|
|
// {
|
|
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
|
|
// if (err == noErr)
|
|
// {
|
|
// multiCartDragHilite = -1;
|
|
// HIViewSetNeedsDisplay(view, true);
|
|
// }
|
|
//
|
|
// result = noErr;
|
|
// break;
|
|
// }
|
|
//
|
|
// case kEventControlDragReceive:
|
|
// {
|
|
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &view);
|
|
// if (err == noErr)
|
|
// {
|
|
// err = GetEventParameter(inEvent, kEventParamDragRef, typeDragRef, NULL, sizeof(DragRef), NULL, &drag);
|
|
// if (err == noErr)
|
|
// {
|
|
// multiCartDragHilite = -1;
|
|
// HIViewSetNeedsDisplay(view, true);
|
|
//
|
|
// err = GetDragPasteboard(drag, &pasteboard);
|
|
// if (err == noErr)
|
|
// {
|
|
// err = PasteboardGetItemIdentifier(pasteboard, 1, &itemID);
|
|
// if (err == noErr)
|
|
// {
|
|
// err = PasteboardCopyItemFlavors(pasteboard, itemID, &array);
|
|
// if (err == noErr)
|
|
// {
|
|
// numFlavors = CFArrayGetCount(array);
|
|
// for (CFIndex i = 0; i < numFlavors; i++)
|
|
// {
|
|
// flavorType = (CFStringRef) CFArrayGetValueAtIndex(array, i);
|
|
// if (UTTypeConformsTo(flavorType, CFSTR("public.file-url")))
|
|
// {
|
|
// CFDataRef flavorData;
|
|
//
|
|
// err = PasteboardCopyItemFlavorData(pasteboard, itemID, flavorType, &flavorData);
|
|
// if (err == noErr)
|
|
// {
|
|
// CFIndex dataSize;
|
|
// UInt8 *data;
|
|
//
|
|
// dataSize = CFDataGetLength(flavorData);
|
|
// data = (UInt8 *) malloc(dataSize);
|
|
// if (data)
|
|
// {
|
|
// CFDataGetBytes(flavorData, CFRangeMake(0, dataSize), data);
|
|
//
|
|
// HIViewRef ctl;
|
|
// HIViewID cid;
|
|
// CFStringRef str;
|
|
// CFURLRef url;
|
|
//
|
|
// GetControlID(view, &cid);
|
|
// cid.signature = 'MNAM';
|
|
// HIViewFindByID(view, cid, &ctl);
|
|
//
|
|
// url = CFURLCreateWithBytes(kCFAllocatorDefault, data, dataSize, kCFStringEncodingUTF8, NULL);
|
|
// str = CFURLCopyLastPathComponent(url);
|
|
// SetStaticTextCFString(ctl, str, true);
|
|
// CFRelease(str);
|
|
// str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
|
|
// if (multiCartPath[cid.id])
|
|
// CFRelease(multiCartPath[cid.id]);
|
|
// multiCartPath[cid.id] = str;
|
|
// CFRelease(url);
|
|
//
|
|
// result = noErr;
|
|
//
|
|
// free(data);
|
|
// }
|
|
//
|
|
// CFRelease(flavorData);
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// CFRelease(array);
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// return (result);
|
|
return 0;
|
|
}
|