/*****************************************************************************\ 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; }