mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-01-22 21:31:15 +00:00
Merge branch 'master' of https://github.com/cebix/macemu
This commit is contained in:
commit
6fd8f91ae4
@ -97,6 +97,14 @@ void ClipExit(void)
|
||||
FreeIFF(iffw);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application zeroes clipboard
|
||||
*/
|
||||
|
||||
void ZeroScrap()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application reads clipboard
|
||||
|
@ -52,6 +52,14 @@ void ClipExit(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application zeroes clipboard
|
||||
*/
|
||||
|
||||
void ZeroScrap()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application reads clipboard
|
||||
|
@ -159,6 +159,16 @@ void GetScrap(void **handle, uint32 type, int32 offset)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* ZeroScrap() is called before a Mac application writes to the clipboard; clears out the previous contents
|
||||
*/
|
||||
|
||||
void ZeroScrap()
|
||||
{
|
||||
D(bug("ZeroScrap\n"));
|
||||
|
||||
we_put_this_data = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application wrote to clipboard
|
||||
|
@ -1,313 +0,0 @@
|
||||
/*
|
||||
* clip_macosx64.cpp - Clipboard handling, MacOS X (Pasteboard Manager) implementation
|
||||
*
|
||||
* (C) 2012 Jean-Pierre Stierlin
|
||||
* (C) 2012 Alexei Svitkine
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#define _UINT64
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#include "clip.h"
|
||||
#include "main.h"
|
||||
#include "cpu_emulation.h"
|
||||
#include "emul_op.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#ifndef FOURCC
|
||||
#define FOURCC(a,b,c,d) (((uint32)(a) << 24) | ((uint32)(b) << 16) | ((uint32)(c) << 8) | (uint32)(d))
|
||||
#endif
|
||||
|
||||
#define TYPE_PICT FOURCC('P','I','C','T')
|
||||
#define TYPE_TEXT FOURCC('T','E','X','T')
|
||||
|
||||
static PasteboardRef g_pbref;
|
||||
|
||||
// Flag for PutScrap(): the data was put by GetScrap(), don't bounce it back to the MacOS X side
|
||||
static bool we_put_this_data = false;
|
||||
|
||||
static CFStringRef GetUTIFromFlavor(uint32 type)
|
||||
{
|
||||
switch (type) {
|
||||
case TYPE_PICT: return kUTTypePICT;
|
||||
case TYPE_TEXT: return CFSTR("com.apple.traditional-mac-plain-text");
|
||||
//case TYPE_TEXT: return CFSTR("public.utf16-plain-text");
|
||||
//case FOURCC('s','t','y','l'): return CFSTR("????");
|
||||
case FOURCC('m','o','o','v'): return kUTTypeQuickTimeMovie;
|
||||
case FOURCC('s','n','d',' '): return kUTTypeAudio;
|
||||
//case FOURCC('u','t','x','t'): return CFSTR("public.utf16-plain-text");
|
||||
case FOURCC('u','t','1','6'): return CFSTR("public.utf16-plain-text");
|
||||
//case FOURCC('u','s','t','l'): return CFSTR("????");
|
||||
case FOURCC('i','c','n','s'): return kUTTypeAppleICNS;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get current system script encoding on Mac
|
||||
*/
|
||||
|
||||
#define smMacSysScript 18
|
||||
#define smMacRegionCode 40
|
||||
|
||||
static int GetMacScriptManagerVariable(uint16 id)
|
||||
{
|
||||
int ret = -1;
|
||||
M68kRegisters r;
|
||||
static uint8 proc[] = {
|
||||
0x59, 0x4f, // subq.w #4,sp
|
||||
0x3f, 0x3c, 0x00, 0x00, // move.w #id,-(sp)
|
||||
0x2f, 0x3c, 0x84, 0x02, 0x00, 0x08, // move.l #-2080243704,-(sp)
|
||||
0xa8, 0xb5, // ScriptUtil()
|
||||
0x20, 0x1f, // move.l (a7)+,d0
|
||||
M68K_RTS >> 8, M68K_RTS & 0xff
|
||||
};
|
||||
r.d[0] = sizeof(proc);
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
uint32 proc_area = r.a[0];
|
||||
if (proc_area) {
|
||||
Host2Mac_memcpy(proc_area, proc, sizeof(proc));
|
||||
WriteMacInt16(proc_area + 4, id);
|
||||
Execute68k(proc_area, &r);
|
||||
ret = r.d[0];
|
||||
r.a[0] = proc_area;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert utf-16 from/to system script encoding on Mac
|
||||
*/
|
||||
|
||||
CFDataRef ConvertMacTextEncoding(CFDataRef pbData, int from_host)
|
||||
{
|
||||
static TextEncoding g_textEncodingHint = kTextEncodingUnknown;
|
||||
static UnicodeMapping uMapping;
|
||||
static UnicodeToTextInfo utInfo;
|
||||
static TextToUnicodeInfo tuInfo;
|
||||
static int ready;
|
||||
|
||||
// should we check this only once ?
|
||||
if (g_textEncodingHint == kTextEncodingUnknown) {
|
||||
int script = GetMacScriptManagerVariable(smMacSysScript);
|
||||
int region = GetMacScriptManagerVariable(smMacRegionCode);
|
||||
if (UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, region, NULL, &g_textEncodingHint))
|
||||
g_textEncodingHint = kTextEncodingMacRoman;
|
||||
uMapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeV2_0, kTextEncodingDefaultVariant, kUnicode16BitFormat);
|
||||
uMapping.otherEncoding = GetTextEncodingBase(g_textEncodingHint);
|
||||
uMapping.mappingVersion = kUnicodeUseLatestMapping;
|
||||
ready = !CreateUnicodeToTextInfo(&uMapping, &utInfo) && !CreateTextToUnicodeInfo(&uMapping, &tuInfo);
|
||||
}
|
||||
if (!ready)
|
||||
return pbData;
|
||||
|
||||
ByteCount byteCount = CFDataGetLength(pbData);
|
||||
ByteCount outBytesLength = byteCount * 2;
|
||||
LogicalAddress outBytesPtr = malloc(byteCount * 2);
|
||||
if (!outBytesPtr)
|
||||
return pbData;
|
||||
|
||||
ByteCount outBytesConverted;
|
||||
OSStatus err;
|
||||
if (from_host) {
|
||||
err = ConvertFromUnicodeToText(utInfo, byteCount, (UniChar *)CFDataGetBytePtr(pbData),
|
||||
kUnicodeLooseMappingsMask,
|
||||
0, NULL, 0, NULL,
|
||||
outBytesLength,
|
||||
&outBytesConverted, &outBytesLength, outBytesPtr);
|
||||
} else {
|
||||
err = ConvertFromTextToUnicode(tuInfo, byteCount, CFDataGetBytePtr(pbData),
|
||||
kUnicodeLooseMappingsMask,
|
||||
0, NULL, 0, NULL,
|
||||
outBytesLength,
|
||||
&outBytesConverted, &outBytesLength, (UniChar *)outBytesPtr);
|
||||
}
|
||||
|
||||
if (err == noErr && outBytesConverted == byteCount) {
|
||||
CFDataRef pbDataConverted = CFDataCreate(kCFAllocatorDefault, (UInt8*)outBytesPtr, outBytesLength);
|
||||
if (pbDataConverted) {
|
||||
CFRelease(pbData);
|
||||
pbData = pbDataConverted;
|
||||
}
|
||||
}
|
||||
free(outBytesPtr);
|
||||
|
||||
return pbData;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
void ClipInit(void)
|
||||
{
|
||||
OSStatus err = PasteboardCreate(kPasteboardClipboard, &g_pbref);
|
||||
if (err) {
|
||||
D(bug("could not create Pasteboard\n"));
|
||||
g_pbref = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Deinitialization
|
||||
*/
|
||||
|
||||
void ClipExit(void)
|
||||
{
|
||||
if (g_pbref) {
|
||||
CFRelease(g_pbref);
|
||||
g_pbref = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mac application reads clipboard
|
||||
*/
|
||||
|
||||
void GetScrap(void **handle, uint32 type, int32 offset)
|
||||
{
|
||||
D(bug("GetScrap handle %p, type %4.4s, offset %d\n", handle, &type, offset));
|
||||
|
||||
CFStringRef typeStr;
|
||||
PasteboardSyncFlags syncFlags;
|
||||
ItemCount itemCount;
|
||||
|
||||
if (!g_pbref)
|
||||
return;
|
||||
|
||||
syncFlags = PasteboardSynchronize(g_pbref);
|
||||
if (syncFlags & kPasteboardModified)
|
||||
return;
|
||||
|
||||
if (PasteboardGetItemCount(g_pbref, &itemCount))
|
||||
return;
|
||||
|
||||
if (!(typeStr = GetUTIFromFlavor(type)))
|
||||
return;
|
||||
|
||||
for (UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++) {
|
||||
PasteboardItemID itemID;
|
||||
CFDataRef pbData;
|
||||
|
||||
if (PasteboardGetItemIdentifier(g_pbref, itemIndex, &itemID))
|
||||
break;
|
||||
|
||||
if (!PasteboardCopyItemFlavorData(g_pbref, itemID, typeStr, &pbData)) {
|
||||
if (type == TYPE_TEXT)
|
||||
pbData = ConvertMacTextEncoding(pbData, TRUE);
|
||||
if (pbData) {
|
||||
// Allocate space for new scrap in MacOS side
|
||||
M68kRegisters r;
|
||||
r.d[0] = CFDataGetLength(pbData);
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
uint32 scrap_area = r.a[0];
|
||||
|
||||
// Get the native clipboard data
|
||||
if (scrap_area) {
|
||||
uint8 * const data = Mac2HostAddr(scrap_area);
|
||||
|
||||
memcpy(data, CFDataGetBytePtr(pbData), CFDataGetLength(pbData));
|
||||
|
||||
// Add new data to clipboard
|
||||
static uint8 proc[] = {
|
||||
0x59, 0x8f, // subq.l #4,sp
|
||||
0xa9, 0xfc, // ZeroScrap()
|
||||
0x2f, 0x3c, 0, 0, 0, 0, // move.l #length,-(sp)
|
||||
0x2f, 0x3c, 0, 0, 0, 0, // move.l #type,-(sp)
|
||||
0x2f, 0x3c, 0, 0, 0, 0, // move.l #outbuf,-(sp)
|
||||
0xa9, 0xfe, // PutScrap()
|
||||
0x58, 0x8f, // addq.l #4,sp
|
||||
M68K_RTS >> 8, M68K_RTS & 0xff
|
||||
};
|
||||
r.d[0] = sizeof(proc);
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
uint32 proc_area = r.a[0];
|
||||
|
||||
if (proc_area) {
|
||||
Host2Mac_memcpy(proc_area, proc, sizeof(proc));
|
||||
WriteMacInt32(proc_area + 6, CFDataGetLength(pbData));
|
||||
WriteMacInt32(proc_area + 12, type);
|
||||
WriteMacInt32(proc_area + 18, scrap_area);
|
||||
we_put_this_data = true;
|
||||
Execute68k(proc_area, &r);
|
||||
|
||||
r.a[0] = proc_area;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr
|
||||
}
|
||||
|
||||
r.a[0] = scrap_area;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(pbData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mac application wrote to clipboard
|
||||
*/
|
||||
|
||||
void PutScrap(uint32 type, void *scrap, int32 length)
|
||||
{
|
||||
static bool clear = true;
|
||||
D(bug("PutScrap type %4.4s, data %08lx, length %ld\n", &type, scrap, length));
|
||||
|
||||
PasteboardSyncFlags syncFlags;
|
||||
CFStringRef typeStr;
|
||||
|
||||
if (!g_pbref)
|
||||
return;
|
||||
|
||||
if (!(typeStr = GetUTIFromFlavor(type)))
|
||||
return;
|
||||
|
||||
if (we_put_this_data) {
|
||||
we_put_this_data = false;
|
||||
clear = true;
|
||||
return;
|
||||
}
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
if (clear && PasteboardClear(g_pbref))
|
||||
return;
|
||||
syncFlags = PasteboardSynchronize(g_pbref);
|
||||
if ((syncFlags & kPasteboardModified) || !(syncFlags & kPasteboardClientIsOwner))
|
||||
return;
|
||||
|
||||
CFDataRef pbData = CFDataCreate(kCFAllocatorDefault, (UInt8*)scrap, length);
|
||||
if (!pbData)
|
||||
return;
|
||||
|
||||
if (type == TYPE_TEXT)
|
||||
pbData = ConvertMacTextEncoding(pbData, FALSE);
|
||||
|
||||
if (pbData) {
|
||||
PasteboardPutItemFlavor(g_pbref, (PasteboardItemID)1, typeStr, pbData, 0);
|
||||
CFRelease(pbData);
|
||||
}
|
||||
}
|
836
BasiliskII/src/MacOSX/clip_macosx64.mm
Normal file
836
BasiliskII/src/MacOSX/clip_macosx64.mm
Normal file
@ -0,0 +1,836 @@
|
||||
/*
|
||||
* clip_macosx64.mm - Clipboard handling, MacOS X (Pasteboard Manager) implementation
|
||||
*
|
||||
* (C) 2012 Jean-Pierre Stierlin
|
||||
* (C) 2012 Alexei Svitkine
|
||||
* (C) 2012 Charles Srstka
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#define _UINT64
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#include "clip.h"
|
||||
#include "main.h"
|
||||
#include "cpu_emulation.h"
|
||||
#include "emul_op.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#ifndef FOURCC
|
||||
#define FOURCC(a,b,c,d) (((uint32)(a) << 24) | ((uint32)(b) << 16) | ((uint32)(c) << 8) | (uint32)(d))
|
||||
#endif
|
||||
|
||||
#define TYPE_PICT FOURCC('P','I','C','T')
|
||||
#define TYPE_TEXT FOURCC('T','E','X','T')
|
||||
#define TYPE_STYL FOURCC('s','t','y','l')
|
||||
|
||||
static PasteboardRef g_pbref;
|
||||
|
||||
// Flag for PutScrap(): the data was put by GetScrap(), don't bounce it back to the MacOS X side
|
||||
static bool we_put_this_data = false;
|
||||
|
||||
static bool should_clear = false;
|
||||
|
||||
static CFStringRef const UTF16_TEXT_FLAVOR_NAME = CFSTR("public.utf16-plain-text");
|
||||
static CFStringRef const TEXT_FLAVOR_NAME = CFSTR("com.apple.traditional-mac-plain-text");
|
||||
static CFStringRef const STYL_FLAVOR_NAME = CFSTR("net.cebix.basilisk.styl-data");
|
||||
|
||||
enum {
|
||||
FONT_FACE_PLAIN = 0,
|
||||
FONT_FACE_BOLD = 1,
|
||||
FONT_FACE_ITALIC = 2,
|
||||
FONT_FACE_UNDERLINE = 4,
|
||||
FONT_FACE_OUTLINE = 8,
|
||||
FONT_FACE_SHADOW = 16,
|
||||
FONT_FACE_CONDENSED = 32,
|
||||
FONT_FACE_EXTENDED = 64
|
||||
};
|
||||
|
||||
static CFStringRef GetUTIFromFlavor(uint32 type)
|
||||
{
|
||||
switch (type) {
|
||||
case TYPE_PICT: return kUTTypePICT;
|
||||
case TYPE_TEXT: return TEXT_FLAVOR_NAME;
|
||||
//case TYPE_TEXT: return UTF16_TEXT_FLAVOR_NAME;
|
||||
case TYPE_STYL: return STYL_FLAVOR_NAME;
|
||||
case FOURCC('m','o','o','v'): return kUTTypeQuickTimeMovie;
|
||||
case FOURCC('s','n','d',' '): return kUTTypeAudio;
|
||||
//case FOURCC('u','t','x','t'): return UTF16_TEXT_FLAVOR_NAME;
|
||||
case FOURCC('u','t','1','6'): return UTF16_TEXT_FLAVOR_NAME;
|
||||
//case FOURCC('u','s','t','l'): return CFSTR("????");
|
||||
case FOURCC('i','c','n','s'): return kUTTypeAppleICNS;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get current system script encoding on Mac
|
||||
*/
|
||||
|
||||
#define smMacSysScript 18
|
||||
#define smMacRegionCode 40
|
||||
|
||||
static int GetMacScriptManagerVariable(uint16 id)
|
||||
{
|
||||
int ret = -1;
|
||||
M68kRegisters r;
|
||||
static uint8 proc[] = {
|
||||
0x59, 0x4f, // subq.w #4,sp
|
||||
0x3f, 0x3c, 0x00, 0x00, // move.w #id,-(sp)
|
||||
0x2f, 0x3c, 0x84, 0x02, 0x00, 0x08, // move.l #-2080243704,-(sp)
|
||||
0xa8, 0xb5, // ScriptUtil()
|
||||
0x20, 0x1f, // move.l (a7)+,d0
|
||||
M68K_RTS >> 8, M68K_RTS & 0xff
|
||||
};
|
||||
r.d[0] = sizeof(proc);
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
uint32 proc_area = r.a[0];
|
||||
if (proc_area) {
|
||||
Host2Mac_memcpy(proc_area, proc, sizeof(proc));
|
||||
WriteMacInt16(proc_area + 4, id);
|
||||
Execute68k(proc_area, &r);
|
||||
ret = r.d[0];
|
||||
r.a[0] = proc_area;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert utf-16 from/to system script encoding on Mac
|
||||
*/
|
||||
|
||||
static CFDataRef ConvertMacTextEncoding(CFDataRef pbData, int from_host)
|
||||
{
|
||||
static TextEncoding g_textEncodingHint = kTextEncodingUnknown;
|
||||
static UnicodeMapping uMapping;
|
||||
static UnicodeToTextInfo utInfo;
|
||||
static TextToUnicodeInfo tuInfo;
|
||||
static int ready;
|
||||
|
||||
// should we check this only once ?
|
||||
if (g_textEncodingHint == kTextEncodingUnknown) {
|
||||
int script = GetMacScriptManagerVariable(smMacSysScript);
|
||||
int region = GetMacScriptManagerVariable(smMacRegionCode);
|
||||
if (UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, region, NULL, &g_textEncodingHint))
|
||||
g_textEncodingHint = kTextEncodingMacRoman;
|
||||
uMapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeV2_0, kTextEncodingDefaultVariant, kUnicode16BitFormat);
|
||||
uMapping.otherEncoding = GetTextEncodingBase(g_textEncodingHint);
|
||||
uMapping.mappingVersion = kUnicodeUseLatestMapping;
|
||||
ready = !CreateUnicodeToTextInfo(&uMapping, &utInfo) && !CreateTextToUnicodeInfo(&uMapping, &tuInfo);
|
||||
}
|
||||
if (!ready)
|
||||
return pbData;
|
||||
|
||||
ByteCount byteCount = CFDataGetLength(pbData);
|
||||
ByteCount outBytesLength = byteCount * 2;
|
||||
LogicalAddress outBytesPtr = malloc(byteCount * 2);
|
||||
if (!outBytesPtr)
|
||||
return pbData;
|
||||
|
||||
ByteCount outBytesConverted;
|
||||
OSStatus err;
|
||||
if (from_host) {
|
||||
err = ConvertFromUnicodeToText(utInfo, byteCount, (UniChar *)CFDataGetBytePtr(pbData),
|
||||
kUnicodeLooseMappingsMask,
|
||||
0, NULL, 0, NULL,
|
||||
outBytesLength,
|
||||
&outBytesConverted, &outBytesLength, outBytesPtr);
|
||||
} else {
|
||||
err = ConvertFromTextToUnicode(tuInfo, byteCount, CFDataGetBytePtr(pbData),
|
||||
kUnicodeLooseMappingsMask,
|
||||
0, NULL, 0, NULL,
|
||||
outBytesLength,
|
||||
&outBytesConverted, &outBytesLength, (UniChar *)outBytesPtr);
|
||||
}
|
||||
|
||||
if (err == noErr && outBytesConverted == byteCount) {
|
||||
CFDataRef pbDataConverted = CFDataCreate(kCFAllocatorDefault, (UInt8*)outBytesPtr, outBytesLength);
|
||||
if (pbDataConverted) {
|
||||
CFRelease(pbData);
|
||||
pbData = pbDataConverted;
|
||||
}
|
||||
}
|
||||
free(outBytesPtr);
|
||||
|
||||
return pbData;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert Mac font ID to font name
|
||||
*/
|
||||
|
||||
static NSString *FontNameFromFontID(int16_t fontID)
|
||||
{
|
||||
M68kRegisters r;
|
||||
r.d[0] = 256; // Str255: 255 characters + length byte
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
uint32_t name_area = r.a[0];
|
||||
|
||||
if (!name_area)
|
||||
return nil;
|
||||
|
||||
uint8_t proc[] = {
|
||||
0x3f, 0x3c, 0, 0, // move.w #fontID,-(sp)
|
||||
0x2f, 0x0a, // move.l A2,-(sp)
|
||||
0xa8, 0xff, // GetFontName()
|
||||
M68K_RTS >> 8, M68K_RTS & 0xff
|
||||
};
|
||||
|
||||
r.d[0] = sizeof(proc);
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
uint32_t proc_area = r.a[0];
|
||||
|
||||
if (proc_area) {
|
||||
Host2Mac_memcpy(proc_area, proc, sizeof(proc));
|
||||
WriteMacInt16(proc_area + 2, fontID);
|
||||
r.a[2] = name_area;
|
||||
Execute68k(proc_area, &r);
|
||||
|
||||
r.a[0] = proc_area;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr
|
||||
}
|
||||
|
||||
uint8_t * const namePtr = Mac2HostAddr(name_area);
|
||||
|
||||
CFStringRef name = CFStringCreateWithPascalString(kCFAllocatorDefault, namePtr, kCFStringEncodingMacRoman);
|
||||
|
||||
r.a[0] = name_area;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr
|
||||
|
||||
return [(NSString *)name autorelease];
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert font name to Mac font ID
|
||||
*/
|
||||
|
||||
static int16_t FontIDFromFontName(NSString *fontName)
|
||||
{
|
||||
M68kRegisters r;
|
||||
r.d[0] = 256; // Str255: 255 characters + length byte
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
uint32_t name_area = r.a[0];
|
||||
|
||||
if (!name_area)
|
||||
return 0;
|
||||
|
||||
uint8_t * const namePtr = Mac2HostAddr(name_area);
|
||||
|
||||
CFStringGetPascalString((CFStringRef)fontName, namePtr, 256, kCFStringEncodingMacRoman);
|
||||
|
||||
uint8_t proc[] = {
|
||||
0x2f, 0x0a, // move.l A2,-(sp)
|
||||
0x2f, 0x0b, // move.l A3,-(sp)
|
||||
0xa9, 0x00, // GetFNum()
|
||||
M68K_RTS >> 8, M68K_RTS & 0xff,
|
||||
0, 0
|
||||
};
|
||||
|
||||
r.d[0] = sizeof(proc);
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
uint32_t proc_area = r.a[0];
|
||||
int16_t fontID = 0;
|
||||
|
||||
if (proc_area) {
|
||||
Host2Mac_memcpy(proc_area, proc, sizeof(proc));
|
||||
r.a[2] = name_area;
|
||||
r.a[3] = proc_area + 8;
|
||||
|
||||
Execute68k(proc_area, &r);
|
||||
|
||||
fontID = ReadMacInt16(proc_area + 8);
|
||||
|
||||
r.a[0] = proc_area;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr
|
||||
}
|
||||
|
||||
r.a[0] = name_area;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr
|
||||
|
||||
return fontID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert Mac styl to attributed string
|
||||
*/
|
||||
|
||||
static NSAttributedString *ConvertToAttributedString(NSString *string, NSData *stylData)
|
||||
{
|
||||
NSMutableAttributedString *aStr = [[[NSMutableAttributedString alloc] initWithString:string] autorelease];
|
||||
|
||||
if (aStr == nil)
|
||||
return nil;
|
||||
|
||||
const uint8_t *bytes = (const uint8_t *)[stylData bytes];
|
||||
NSUInteger length = [stylData length];
|
||||
|
||||
if (length < 2)
|
||||
return nil;
|
||||
|
||||
uint16_t elements = CFSwapInt16BigToHost(*(uint16_t *)bytes);
|
||||
const NSUInteger elementSize = 20;
|
||||
|
||||
if (length < elements * elementSize)
|
||||
return nil;
|
||||
|
||||
CFIndex pointer = 2;
|
||||
|
||||
for (NSUInteger i = 0; i < elements; i++) {
|
||||
int32_t startChar = CFSwapInt32BigToHost(*(int32_t *)(bytes + pointer)); pointer += 4;
|
||||
int16_t height = CFSwapInt16BigToHost(*(int16_t *)&bytes[pointer]); pointer += 2;
|
||||
int16_t ascent = CFSwapInt16BigToHost(*(int16_t *)&bytes[pointer]); pointer += 2;
|
||||
int16_t fontID = CFSwapInt16BigToHost(*(int16_t *)&bytes[pointer]); pointer += 2;
|
||||
uint8_t face = bytes[pointer]; pointer += 2;
|
||||
int16_t size = CFSwapInt16BigToHost(*(int16_t *)&bytes[pointer]); pointer += 2;
|
||||
uint16_t red = CFSwapInt16BigToHost(*(int16_t *)&bytes[pointer]); pointer += 2;
|
||||
uint16_t green = CFSwapInt16BigToHost(*(int16_t *)&bytes[pointer]); pointer += 2;
|
||||
uint16_t blue = CFSwapInt16BigToHost(*(int16_t *)&bytes[pointer]); pointer += 2;
|
||||
|
||||
int32_t nextChar;
|
||||
|
||||
if (i + 1 == elements)
|
||||
nextChar = [aStr length];
|
||||
else
|
||||
nextChar = CFSwapInt32BigToHost(*(int32_t *)(bytes + pointer));
|
||||
|
||||
NSMutableDictionary *attrs = [[NSMutableDictionary alloc] init];
|
||||
NSColor *color = [NSColor colorWithDeviceRed:(CGFloat)red / 65535.0 green:(CGFloat)green / 65535.0 blue:(CGFloat)blue / 65535.0 alpha:1.0];
|
||||
NSFont *font;
|
||||
|
||||
if (fontID == 0) { // System font
|
||||
CGFloat fontSize = (size == 0) ? [NSFont systemFontSize] : (CGFloat)size;
|
||||
font = [NSFont systemFontOfSize:fontSize];
|
||||
} else if (fontID == 1) { // Application font
|
||||
font = [NSFont userFontOfSize:(CGFloat)size];
|
||||
} else {
|
||||
NSString *fontName = FontNameFromFontID(fontID);
|
||||
font = [NSFont fontWithName:fontName size:(CGFloat)size];
|
||||
}
|
||||
|
||||
if (font == nil)
|
||||
font = [NSFont userFontOfSize:(CGFloat)size];
|
||||
|
||||
NSFontManager *fm = [NSFontManager sharedFontManager];
|
||||
|
||||
if (face & FONT_FACE_BOLD)
|
||||
font = [fm convertFont:font toHaveTrait:NSBoldFontMask];
|
||||
|
||||
if (face & FONT_FACE_ITALIC)
|
||||
font = [fm convertFont:font toHaveTrait:NSItalicFontMask];
|
||||
|
||||
if (face & FONT_FACE_CONDENSED)
|
||||
font = [fm convertFont:font toHaveTrait:NSCondensedFontMask];
|
||||
|
||||
if (face & FONT_FACE_EXTENDED)
|
||||
font = [fm convertFont:font toHaveTrait:NSExpandedFontMask];
|
||||
|
||||
[attrs setObject:font forKey:NSFontAttributeName];
|
||||
|
||||
if (face & FONT_FACE_UNDERLINE)
|
||||
[attrs setObject:[NSNumber numberWithInteger:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName];
|
||||
|
||||
if (face & FONT_FACE_OUTLINE) {
|
||||
[attrs setObject:color forKey:NSStrokeColorAttributeName];
|
||||
[attrs setObject:[NSNumber numberWithInteger:3] forKey:NSStrokeWidthAttributeName];
|
||||
}
|
||||
|
||||
if (face & FONT_FACE_SHADOW) {
|
||||
NSShadow *shadow = [[NSShadow alloc] init];
|
||||
NSColor *shadowColor = [NSColor colorWithDeviceRed:(CGFloat)red / 65535.0 green:(CGFloat)green / 65535.0 blue:(CGFloat)blue / 65535.0 alpha:0.5];
|
||||
|
||||
[shadow setShadowColor:shadowColor];
|
||||
[shadow setShadowOffset:NSMakeSize(2, -2.0)];
|
||||
|
||||
[attrs setObject:shadow forKey:NSShadowAttributeName];
|
||||
|
||||
[shadow release];
|
||||
}
|
||||
|
||||
[attrs setObject:color forKey:NSForegroundColorAttributeName];
|
||||
|
||||
[aStr setAttributes:attrs range:NSMakeRange(startChar, nextChar - startChar)];
|
||||
|
||||
[attrs release];
|
||||
}
|
||||
|
||||
return aStr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert attributed string to TEXT/styl
|
||||
*/
|
||||
|
||||
static NSData *ConvertToMacTEXTAndStyl(NSAttributedString *aStr, NSData **outStylData) {
|
||||
// Limitations imposed by the Mac TextEdit system.
|
||||
// Something to test would be whether using UTF16 causes TextEdit to choke at 16K characters
|
||||
// instead of 32K characters, depending on whether this is a byte limit or a true character limit.
|
||||
// If the former, UTF8 might be a better choice for encoding here.
|
||||
const NSUInteger charLimit = 32 * 1024;
|
||||
const NSUInteger elementLimit = 1601;
|
||||
|
||||
if ([aStr length] > charLimit) {
|
||||
aStr = [aStr attributedSubstringFromRange:NSMakeRange(0, charLimit)];
|
||||
}
|
||||
|
||||
// See comment in CreateRTFDataFromMacTEXTAndStyl regarding encodings; I hope I've interpreted
|
||||
// the existing code correctly in this regard
|
||||
#if __LITTLE_ENDIAN__
|
||||
NSStringEncoding encoding = NSUTF16LittleEndianStringEncoding;
|
||||
#else
|
||||
NSStringEncoding encoding = NSUTF16BigEndianStringEncoding;
|
||||
#endif
|
||||
|
||||
NSData *textData = [[aStr string] dataUsingEncoding:encoding];
|
||||
NSMutableData *stylData = [NSMutableData dataWithLength:2]; // number of styles to be filled in at the end
|
||||
|
||||
NSUInteger length = [aStr length];
|
||||
NSUInteger elements = 0;
|
||||
|
||||
NSFontManager *fontManager = [NSFontManager sharedFontManager];
|
||||
NSLayoutManager *layoutManager = [[[NSLayoutManager alloc] init] autorelease];
|
||||
|
||||
for (NSUInteger index = 0; index < length && elements < elementLimit;) {
|
||||
NSRange attrRange;
|
||||
NSDictionary *attrs = [aStr attributesAtIndex:index effectiveRange:&attrRange];
|
||||
|
||||
NSFont *font = [attrs objectForKey:NSFontAttributeName];
|
||||
NSColor *color = [[attrs objectForKey:NSForegroundColorAttributeName] colorUsingColorSpaceName:NSDeviceRGBColorSpace device:nil];
|
||||
NSFontTraitMask traits = [fontManager traitsOfFont:font];
|
||||
NSNumber *underlineStyle = [attrs objectForKey:NSUnderlineStyleAttributeName];
|
||||
NSNumber *strokeWidth = [attrs objectForKey:NSStrokeWidthAttributeName];
|
||||
NSShadow *shadow = [attrs objectForKey:NSShadowAttributeName];
|
||||
|
||||
int16_t hostFontID = FontIDFromFontName([font familyName]);
|
||||
|
||||
if (hostFontID == 0) {
|
||||
hostFontID = [font isFixedPitch] ? 4 /* Monaco */ : 1 /* Application font */;
|
||||
}
|
||||
|
||||
int32_t startChar = CFSwapInt32HostToBig((int32_t)index);
|
||||
int16_t height = CFSwapInt16HostToBig((int16_t)rint([layoutManager defaultLineHeightForFont:font]));
|
||||
int16_t ascent = CFSwapInt16HostToBig((int16_t)rint([font ascender]));
|
||||
int16_t fontID = CFSwapInt16HostToBig(hostFontID);
|
||||
uint8_t face = 0;
|
||||
int16_t size = CFSwapInt16HostToBig((int16_t)rint([font pointSize]));
|
||||
uint16_t red = CFSwapInt16HostToBig((int16_t)rint([color redComponent] * 65535.0));
|
||||
uint16_t green = CFSwapInt16HostToBig((int16_t)rint([color greenComponent] * 65535.0));
|
||||
uint16_t blue = CFSwapInt16HostToBig((int16_t)rint([color blueComponent] * 65535.0));
|
||||
|
||||
if (traits & NSBoldFontMask) {
|
||||
face |= FONT_FACE_BOLD;
|
||||
}
|
||||
|
||||
if (traits & NSItalicFontMask) {
|
||||
face |= FONT_FACE_ITALIC;
|
||||
}
|
||||
|
||||
if (traits & NSCondensedFontMask) {
|
||||
face |= FONT_FACE_CONDENSED;
|
||||
}
|
||||
|
||||
if (traits & NSExpandedFontMask) {
|
||||
face |= FONT_FACE_EXTENDED;
|
||||
}
|
||||
|
||||
if (underlineStyle && [underlineStyle integerValue] != NSUnderlineStyleNone) {
|
||||
face |= FONT_FACE_UNDERLINE;
|
||||
}
|
||||
|
||||
if (strokeWidth && [strokeWidth doubleValue] > 0.0) {
|
||||
face |= FONT_FACE_OUTLINE;
|
||||
}
|
||||
|
||||
if (shadow) {
|
||||
face |= FONT_FACE_SHADOW;
|
||||
}
|
||||
|
||||
[stylData appendBytes:&startChar length:4];
|
||||
[stylData appendBytes:&height length:2];
|
||||
[stylData appendBytes:&ascent length:2];
|
||||
[stylData appendBytes:&fontID length:2];
|
||||
[stylData appendBytes:&face length:1];
|
||||
[stylData increaseLengthBy:1];
|
||||
[stylData appendBytes:&size length:2];
|
||||
[stylData appendBytes:&red length:2];
|
||||
[stylData appendBytes:&green length:2];
|
||||
[stylData appendBytes:&blue length:2];
|
||||
|
||||
index += attrRange.length;
|
||||
elements++;
|
||||
}
|
||||
|
||||
uint16_t bigEndianElements = CFSwapInt16HostToBig((uint16_t)elements);
|
||||
|
||||
[stylData replaceBytesInRange:NSMakeRange(0, 2) withBytes:&bigEndianElements length:2];
|
||||
|
||||
if (outStylData)
|
||||
*outStylData = stylData;
|
||||
|
||||
textData = (NSData *)ConvertMacTextEncoding((CFDataRef)[textData retain], YES);
|
||||
|
||||
return [textData autorelease];
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert Mac TEXT/styl to RTF
|
||||
*/
|
||||
|
||||
static CFDataRef CreateRTFDataFromMacTEXTAndStyl(CFDataRef textData, CFDataRef stylData)
|
||||
{
|
||||
// Unfortunately, CF does not seem to have any RTF conversion routines, so do this in Cocoa instead.
|
||||
// If we are willing to require OS X 10.6 minimum, we should use the NSPasteboardWriting methods
|
||||
// instead of putting the RTF data up ourselves.
|
||||
|
||||
NSData *rtfData = nil;
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// I think this is what's going on? ConvertMacTextEncoding() converts to Unicode in host endian?
|
||||
// Maybe UTF8 would be a less ambiguous form to store the pasteboard data in?
|
||||
|
||||
#if __LITTLE_ENDIAN__
|
||||
NSStringEncoding encoding = NSUTF16LittleEndianStringEncoding;
|
||||
#else
|
||||
NSStringEncoding encoding = NSUTF16BigEndianStringEncoding;
|
||||
#endif
|
||||
|
||||
NSMutableString *string = [[[NSMutableString alloc] initWithData:(NSData *)textData encoding:encoding] autorelease];
|
||||
|
||||
// fix line endings
|
||||
[string replaceOccurrencesOfString:@"\r" withString:@"\n" options:NSLiteralSearch range:NSMakeRange(0, [string length])];
|
||||
|
||||
if (string != nil) {
|
||||
NSAttributedString *aStr = ConvertToAttributedString(string, (NSData *)stylData);
|
||||
|
||||
rtfData = [[aStr RTFFromRange:NSMakeRange(0, [aStr length]) documentAttributes:nil] retain];
|
||||
}
|
||||
|
||||
[pool drain];
|
||||
|
||||
return (CFDataRef)rtfData;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert RTF to Mac TEXT/styl
|
||||
*/
|
||||
|
||||
static CFDataRef CreateMacTEXTAndStylFromRTFData(CFDataRef rtfData, CFDataRef *outStylData)
|
||||
{
|
||||
// No easy way to do this at the CF layer, so use Cocoa.
|
||||
// Reading RTF should be backward compatible to the early releases of OS X;
|
||||
// if we are willing to require OS X 10.6 or better, we should use NSPasteboardReading
|
||||
// to read an NSAttributedString off of the pasteboard, which will give us the ability
|
||||
// to potentially read more rich-text formats than RTF.
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSMutableAttributedString *aStr = [[[NSMutableAttributedString alloc] initWithRTF:(NSData *)rtfData documentAttributes:nil] autorelease];
|
||||
|
||||
// fix line endings
|
||||
[[aStr mutableString] replaceOccurrencesOfString:@"\n" withString:@"\r" options:NSLiteralSearch range:NSMakeRange(0, [[aStr mutableString] length])];
|
||||
|
||||
NSData *stylData = nil;
|
||||
NSData *textData = ConvertToMacTEXTAndStyl(aStr, &stylData);
|
||||
|
||||
[textData retain];
|
||||
|
||||
if (outStylData)
|
||||
*outStylData = (CFDataRef)[stylData retain];
|
||||
|
||||
[pool drain];
|
||||
|
||||
return (CFDataRef)textData;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
void ClipInit(void)
|
||||
{
|
||||
OSStatus err = PasteboardCreate(kPasteboardClipboard, &g_pbref);
|
||||
if (err) {
|
||||
D(bug("could not create Pasteboard\n"));
|
||||
g_pbref = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Deinitialization
|
||||
*/
|
||||
|
||||
void ClipExit(void)
|
||||
{
|
||||
if (g_pbref) {
|
||||
CFRelease(g_pbref);
|
||||
g_pbref = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy data from the host pasteboard
|
||||
*/
|
||||
|
||||
static CFDataRef CopyPasteboardDataWithFlavor(CFStringRef flavor)
|
||||
{
|
||||
ItemCount itemCount;
|
||||
|
||||
if (PasteboardGetItemCount(g_pbref, &itemCount))
|
||||
return NULL;
|
||||
|
||||
for (UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++) {
|
||||
PasteboardItemID itemID;
|
||||
CFDataRef pbData;
|
||||
|
||||
if (PasteboardGetItemIdentifier(g_pbref, itemIndex, &itemID))
|
||||
break;
|
||||
|
||||
if (!PasteboardCopyItemFlavorData(g_pbref, itemID, flavor, &pbData)) {
|
||||
return pbData;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Zero Mac clipboard
|
||||
*/
|
||||
|
||||
static void ZeroMacClipboard()
|
||||
{
|
||||
D(bug(stderr, "Zeroing Mac clipboard\n"));
|
||||
M68kRegisters r;
|
||||
static uint8 proc[] = {
|
||||
0x59, 0x8f, // subq.l #4,sp
|
||||
0xa9, 0xfc, // ZeroScrap()
|
||||
0x58, 0x8f, // addq.l #4,sp
|
||||
M68K_RTS >> 8, M68K_RTS & 0xff
|
||||
};
|
||||
r.d[0] = sizeof(proc);
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
uint32 proc_area = r.a[0];
|
||||
|
||||
if (proc_area) {
|
||||
Host2Mac_memcpy(proc_area, proc, sizeof(proc));
|
||||
Execute68k(proc_area, &r);
|
||||
|
||||
r.a[0] = proc_area;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to Mac clipboard
|
||||
*/
|
||||
|
||||
static void WriteDataToMacClipboard(CFDataRef pbData, uint32 type)
|
||||
{
|
||||
D(bug(stderr, "Writing data %s to Mac clipboard with type '%c%c%c%c'\n", [[(NSData *)pbData description] UTF8String],
|
||||
(type >> 24) & 0xff, (type >> 16) & 0xff, (type >> 8) & 0xff, type & 0xff));
|
||||
|
||||
// Allocate space for new scrap in MacOS side
|
||||
M68kRegisters r;
|
||||
r.d[0] = CFDataGetLength(pbData);
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
uint32 scrap_area = r.a[0];
|
||||
|
||||
// Get the native clipboard data
|
||||
if (scrap_area) {
|
||||
uint8 * const data = Mac2HostAddr(scrap_area);
|
||||
|
||||
memcpy(data, CFDataGetBytePtr(pbData), CFDataGetLength(pbData));
|
||||
|
||||
// Add new data to clipboard
|
||||
static uint8 proc[] = {
|
||||
0x59, 0x8f, // subq.l #4,sp
|
||||
0x2f, 0x3c, 0, 0, 0, 0, // move.l #length,-(sp)
|
||||
0x2f, 0x3c, 0, 0, 0, 0, // move.l #type,-(sp)
|
||||
0x2f, 0x3c, 0, 0, 0, 0, // move.l #outbuf,-(sp)
|
||||
0xa9, 0xfe, // PutScrap()
|
||||
0x58, 0x8f, // addq.l #4,sp
|
||||
M68K_RTS >> 8, M68K_RTS & 0xff
|
||||
};
|
||||
r.d[0] = sizeof(proc);
|
||||
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
|
||||
uint32 proc_area = r.a[0];
|
||||
|
||||
if (proc_area) {
|
||||
Host2Mac_memcpy(proc_area, proc, sizeof(proc));
|
||||
WriteMacInt32(proc_area + 4, CFDataGetLength(pbData));
|
||||
WriteMacInt32(proc_area + 10, type);
|
||||
WriteMacInt32(proc_area + 16, scrap_area);
|
||||
we_put_this_data = true;
|
||||
Execute68k(proc_area, &r);
|
||||
|
||||
r.a[0] = proc_area;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr
|
||||
}
|
||||
|
||||
r.a[0] = scrap_area;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application reads clipboard
|
||||
*/
|
||||
|
||||
void GetScrap(void **handle, uint32 type, int32 offset)
|
||||
{
|
||||
D(bug("GetScrap handle %p, type %4.4s, offset %d\n", handle, (char *)&type, offset));
|
||||
|
||||
CFStringRef typeStr;
|
||||
PasteboardSyncFlags syncFlags;
|
||||
|
||||
if (!g_pbref)
|
||||
return;
|
||||
|
||||
syncFlags = PasteboardSynchronize(g_pbref);
|
||||
if (syncFlags & kPasteboardModified)
|
||||
return;
|
||||
|
||||
if (!(typeStr = GetUTIFromFlavor(type)))
|
||||
return;
|
||||
|
||||
if (type == TYPE_TEXT || type == TYPE_STYL) {
|
||||
CFDataRef rtfData = CopyPasteboardDataWithFlavor(kUTTypeRTF);
|
||||
|
||||
if (rtfData != NULL) {
|
||||
CFDataRef stylData = NULL;
|
||||
CFDataRef textData = CreateMacTEXTAndStylFromRTFData(rtfData, &stylData);
|
||||
|
||||
ZeroMacClipboard();
|
||||
|
||||
if (stylData)
|
||||
WriteDataToMacClipboard(stylData, TYPE_STYL);
|
||||
|
||||
WriteDataToMacClipboard(textData, TYPE_TEXT);
|
||||
|
||||
CFRelease(textData);
|
||||
CFRelease(stylData);
|
||||
CFRelease(rtfData);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CFDataRef pbData = CopyPasteboardDataWithFlavor(typeStr);
|
||||
|
||||
if (pbData) {
|
||||
if (type == TYPE_TEXT)
|
||||
pbData = ConvertMacTextEncoding(pbData, TRUE);
|
||||
|
||||
ZeroMacClipboard();
|
||||
WriteDataToMacClipboard(pbData, type);
|
||||
|
||||
CFRelease(pbData);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ZeroScrap() is called before a Mac application writes to the clipboard; clears out the previous contents
|
||||
*/
|
||||
|
||||
void ZeroScrap()
|
||||
{
|
||||
D(bug("ZeroScrap\n"));
|
||||
|
||||
we_put_this_data = false;
|
||||
|
||||
// Defer clearing the host pasteboard until the Mac tries to put something on it.
|
||||
// This prevents us from clearing the pasteboard when ZeroScrap() is called during startup.
|
||||
should_clear = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application wrote to clipboard
|
||||
*/
|
||||
|
||||
void PutScrap(uint32 type, void *scrap, int32 length)
|
||||
{
|
||||
D(bug("PutScrap type %4.4s, data %p, length %ld\n", (char *)&type, scrap, (long)length));
|
||||
|
||||
PasteboardSyncFlags syncFlags;
|
||||
CFStringRef typeStr;
|
||||
|
||||
if (!g_pbref)
|
||||
return;
|
||||
|
||||
if (!(typeStr = GetUTIFromFlavor(type)))
|
||||
return;
|
||||
|
||||
if (we_put_this_data) {
|
||||
we_put_this_data = false;
|
||||
return;
|
||||
}
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
if (should_clear) {
|
||||
PasteboardClear(g_pbref);
|
||||
should_clear = false;
|
||||
}
|
||||
|
||||
syncFlags = PasteboardSynchronize(g_pbref);
|
||||
if ((syncFlags & kPasteboardModified) || !(syncFlags & kPasteboardClientIsOwner))
|
||||
return;
|
||||
|
||||
CFDataRef pbData = CFDataCreate(kCFAllocatorDefault, (UInt8*)scrap, length);
|
||||
if (!pbData)
|
||||
return;
|
||||
|
||||
|
||||
if (type == TYPE_TEXT)
|
||||
pbData = ConvertMacTextEncoding(pbData, FALSE);
|
||||
|
||||
if (pbData) {
|
||||
PasteboardPutItemFlavor(g_pbref, (PasteboardItemID)1, typeStr, pbData, 0);
|
||||
CFRelease(pbData);
|
||||
}
|
||||
|
||||
if (type == TYPE_TEXT || type == TYPE_STYL) {
|
||||
CFDataRef textData;
|
||||
CFDataRef stylData;
|
||||
|
||||
if (PasteboardCopyItemFlavorData(g_pbref, (PasteboardItemID)1, TEXT_FLAVOR_NAME, &textData) != noErr)
|
||||
textData = NULL;
|
||||
|
||||
if (PasteboardCopyItemFlavorData(g_pbref, (PasteboardItemID)1, STYL_FLAVOR_NAME, &stylData) != noErr)
|
||||
stylData = NULL;
|
||||
|
||||
if (textData != NULL && stylData != NULL) {
|
||||
CFDataRef rtfData = CreateRTFDataFromMacTEXTAndStyl(textData, stylData);
|
||||
|
||||
if (rtfData) {
|
||||
PasteboardPutItemFlavor(g_pbref, (PasteboardItemID)1, kUTTypeRTF, rtfData, 0);
|
||||
CFRelease(rtfData);
|
||||
}
|
||||
}
|
||||
|
||||
if (textData)
|
||||
CFRelease(textData);
|
||||
|
||||
if (stylData)
|
||||
CFRelease(stylData);
|
||||
}
|
||||
}
|
@ -66,7 +66,7 @@ extern void SysMediaRemoved(const char *path, int type);
|
||||
|
||||
void DarwinSysInit(void)
|
||||
{
|
||||
if (PrefsFindBool("nocdrom")) {
|
||||
if (!PrefsFindBool("nocdrom")) {
|
||||
media_thread_active = (pthread_create(&media_thread, NULL, media_poll_func, NULL) == 0);
|
||||
D(bug("Media poll thread installed (%ld)\n", media_thread));
|
||||
}
|
||||
|
@ -374,6 +374,14 @@ static void do_putscrap(uint32 type, void *scrap, int32 length)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application zeroes clipboard
|
||||
*/
|
||||
|
||||
void ZeroScrap()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application reads clipboard
|
||||
|
@ -713,7 +713,18 @@ if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then
|
||||
VIDEOSRCS="../SDL/video_sdl.cpp"
|
||||
KEYCODES="../SDL/keycodes"
|
||||
if [[ "x$ac_cv_framework_Carbon" = "xyes" ]]; then
|
||||
EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/clip_macosx.cpp"
|
||||
AC_MSG_CHECKING([whether __LP64__ is defined])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#if !defined(__LP64__)
|
||||
# error __LP64__ not defined
|
||||
#endif
|
||||
]])],
|
||||
[AC_MSG_RESULT(yes); LP64_DEFINED=yes],
|
||||
[AC_MSG_RESULT(no)])
|
||||
if [[ "x$LP64_DEFINED" = "xyes" ]]; then
|
||||
EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/clip_macosx64.mm"
|
||||
else
|
||||
EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/clip_macosx.cpp"
|
||||
fi
|
||||
EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/utils_macosx.mm"
|
||||
CPPFLAGS="$CPPFLAGS -I../MacOSX"
|
||||
else
|
||||
@ -1357,10 +1368,11 @@ if [[ "x$HAVE_GCC30" = "xyes" ]]; then
|
||||
CFLAGS="$CFLAGS -fno-strict-aliasing"
|
||||
AC_CACHE_CHECK([whether the compiler supports -fno-strict-aliasing],
|
||||
ac_cv_gcc_no_strict_aliasing, [
|
||||
AC_TRY_COMPILE([],[],
|
||||
[ac_cv_gcc_no_strict_aliasing=yes; AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing")],
|
||||
[ac_cv_gcc_no_strict_aliasing=no])
|
||||
AC_TRY_COMPILE([],[],[ac_cv_gcc_no_strict_aliasing=yes],[ac_cv_gcc_no_strict_aliasing=no])
|
||||
])
|
||||
if [[ "x$ac_cv_gcc_no_strict_aliasing" = "xyes" ]]; then
|
||||
AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing")
|
||||
fi
|
||||
CFLAGS="$SAVED_CFLAGS"
|
||||
fi
|
||||
|
||||
|
@ -616,10 +616,26 @@ void *Sys_open(const char *name, bool read_only)
|
||||
}
|
||||
#endif
|
||||
|
||||
int open_flags = (read_only ? O_RDONLY : O_RDWR);
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__MACOSX__)
|
||||
int fd = open(name, (read_only ? O_RDONLY : O_RDWR) | (is_cdrom ? O_NONBLOCK : 0));
|
||||
#else
|
||||
int fd = open(name, read_only ? O_RDONLY : O_RDWR);
|
||||
open_flags |= (is_cdrom ? O_NONBLOCK : 0);
|
||||
#endif
|
||||
#if defined(__MACOSX__)
|
||||
open_flags |= (is_file ? O_EXLOCK | O_NONBLOCK : 0);
|
||||
#endif
|
||||
int fd = open(name, open_flags);
|
||||
#if defined(__MACOSX__)
|
||||
if (fd < 0 && (open_flags & O_EXLOCK)) {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
// File system does not support locking. Try again without.
|
||||
open_flags &= ~O_EXLOCK;
|
||||
fd = open(name, open_flags);
|
||||
} else if (errno == EAGAIN) {
|
||||
// File is likely already locked by another process.
|
||||
printf("WARNING: Cannot open %s (%s)\n", name, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (fd < 0 && !read_only) {
|
||||
// Read-write failed, try read-only
|
||||
|
@ -179,6 +179,14 @@ static void do_putscrap(uint32 type, void *scrap, int32 length)
|
||||
CloseClipboard();
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application zeroes clipboard
|
||||
*/
|
||||
|
||||
void ZeroScrap()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application reads clipboard
|
||||
|
@ -24,6 +24,7 @@
|
||||
extern void ClipInit(void);
|
||||
extern void ClipExit(void);
|
||||
|
||||
extern void ZeroScrap();
|
||||
extern void PutScrap(uint32 type, void *scrap, int32 length);
|
||||
extern void GetScrap(void **handle, uint32 type, int32 offset);
|
||||
|
||||
|
@ -73,7 +73,7 @@ links:
|
||||
Unix/Darwin/lowmem.c Unix/Darwin/pagezero.c Unix/Darwin/testlmem.sh \
|
||||
dummy/audio_dummy.cpp dummy/clip_dummy.cpp dummy/serial_dummy.cpp \
|
||||
dummy/prefs_editor_dummy.cpp dummy/scsi_dummy.cpp SDL slirp \
|
||||
MacOSX/sys_darwin.cpp MacOSX/clip_macosx.cpp MacOSX/clip_macosx64.cpp \
|
||||
MacOSX/sys_darwin.cpp MacOSX/clip_macosx.cpp MacOSX/clip_macosx64.mm \
|
||||
MacOSX/macos_util_macosx.h Unix/cpr.sh \
|
||||
MacOSX/extfs_macosx.cpp Windows/clip_windows.cpp \
|
||||
MacOSX/MacOSX_sound_if.cpp MacOSX/MacOSX_sound_if.h \
|
||||
|
@ -240,6 +240,14 @@ void PutScrap(uint32 type, void *scrap, int32 length)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application zeroes clipboard
|
||||
*/
|
||||
|
||||
void ZeroScrap()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Mac application reads clipboard
|
||||
|
@ -118,10 +118,10 @@
|
||||
0873A76A14ABD151004F12B7 /* config-macosx-x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 0873A76614ABD151004F12B7 /* config-macosx-x86_64.h */; };
|
||||
0873A76B14ABD151004F12B7 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 0873A76714ABD151004F12B7 /* config.h */; };
|
||||
0873A80214AC515D004F12B7 /* utils_macosx.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0873A80114AC515D004F12B7 /* utils_macosx.mm */; };
|
||||
0885A52F1593E47F005C4F7B /* clip_macosx64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0851E9561593E22B00EE3FAD /* clip_macosx64.cpp */; };
|
||||
08C99DA11593E79F00898E41 /* clip_macosx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE2C14A99EF0000B1711 /* clip_macosx.cpp */; };
|
||||
08CD42DC14B7B85B009CA2A2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08CD42DB14B7B85B009CA2A2 /* Cocoa.framework */; };
|
||||
08CD42E814B7B8AA009CA2A2 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08CD42E714B7B8AA009CA2A2 /* Carbon.framework */; };
|
||||
08D93A16159FE174003B04EC /* clip_macosx64.mm in Sources */ = {isa = PBXBuildFile; fileRef = 08D93A15159FE174003B04EC /* clip_macosx64.mm */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -214,7 +214,6 @@
|
||||
0846E52314B129DA00574779 /* ppc_asm.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = ppc_asm.S; sourceTree = "<group>"; };
|
||||
0846E52814B129EE00574779 /* libppc_asm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libppc_asm.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0846E55214B12B0D00574779 /* paranoia.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = paranoia.cpp; sourceTree = "<group>"; };
|
||||
0851E9561593E22B00EE3FAD /* clip_macosx64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clip_macosx64.cpp; sourceTree = "<group>"; };
|
||||
0856CCC114A99E1C000B1711 /* SheepShaver.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SheepShaver.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0856CD4B14A99EEF000B1711 /* adb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = adb.cpp; path = ../adb.cpp; sourceTree = SOURCE_ROOT; };
|
||||
0856CD4C14A99EEF000B1711 /* audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = audio.cpp; path = ../audio.cpp; sourceTree = SOURCE_ROOT; };
|
||||
@ -432,6 +431,7 @@
|
||||
0885A5341593E47F005C4F7B /* libclip64.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libclip64.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
08CD42DB14B7B85B009CA2A2 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
|
||||
08CD42E714B7B8AA009CA2A2 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
|
||||
08D93A15159FE174003B04EC /* clip_macosx64.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = clip_macosx64.mm; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -801,7 +801,7 @@
|
||||
0873A76514ABD151004F12B7 /* config */,
|
||||
0856D2D614A9A704000B1711 /* Launcher */,
|
||||
0856CE2C14A99EF0000B1711 /* clip_macosx.cpp */,
|
||||
0851E9561593E22B00EE3FAD /* clip_macosx64.cpp */,
|
||||
08D93A15159FE174003B04EC /* clip_macosx64.mm */,
|
||||
0856CE2D14A99EF0000B1711 /* extfs_macosx.cpp */,
|
||||
0856CE6D14A99EF0000B1711 /* macos_util_macosx.h */,
|
||||
0856CE7014A99EF0000B1711 /* prefs_macosx.mm */,
|
||||
@ -1461,7 +1461,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0885A52F1593E47F005C4F7B /* clip_macosx64.cpp in Sources */,
|
||||
08D93A16159FE174003B04EC /* clip_macosx64.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1 +0,0 @@
|
||||
../../../BasiliskII/src/MacOSX/clip_macosx64.cpp
|
1
SheepShaver/src/MacOSX/clip_macosx64.mm
Symbolic link
1
SheepShaver/src/MacOSX/clip_macosx64.mm
Symbolic link
@ -0,0 +1 @@
|
||||
../../../BasiliskII/src/MacOSX/clip_macosx64.mm
|
@ -716,7 +716,7 @@ if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then
|
||||
[AC_MSG_RESULT(yes); LP64_DEFINED=yes],
|
||||
[AC_MSG_RESULT(no)])
|
||||
if [[ "x$LP64_DEFINED" = "xyes" ]]; then
|
||||
EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/clip_macosx64.cpp"
|
||||
EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/clip_macosx64.mm"
|
||||
else
|
||||
EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/clip_macosx.cpp"
|
||||
fi
|
||||
|
@ -227,6 +227,10 @@ void EmulOp(M68kRegisters *r, uint32 pc, int selector)
|
||||
Microseconds(r->a[0], r->d[0]);
|
||||
break;
|
||||
|
||||
case OP_ZERO_SCRAP: // ZeroScrap() patch
|
||||
ZeroScrap();
|
||||
break;
|
||||
|
||||
case OP_PUT_SCRAP: // PutScrap() patch
|
||||
PutScrap(ReadMacInt32(r->a[7] + 8), Mac2HostAddr(ReadMacInt32(r->a[7] + 4)), ReadMacInt32(r->a[7] + 12));
|
||||
break;
|
||||
|
@ -44,7 +44,7 @@ enum { // Selectors for EMUL_OP opcodes
|
||||
OP_DISK_OPEN, OP_DISK_PRIME, OP_DISK_CONTROL, OP_DISK_STATUS,
|
||||
OP_CDROM_OPEN, OP_CDROM_PRIME, OP_CDROM_CONTROL, OP_CDROM_STATUS,
|
||||
OP_AUDIO_DISPATCH, OP_SOUNDIN_OPEN, OP_SOUNDIN_PRIME, OP_SOUNDIN_CONTROL, OP_SOUNDIN_STATUS, OP_SOUNDIN_CLOSE,
|
||||
OP_ADBOP, OP_INSTIME, OP_RMVTIME, OP_PRIMETIME, OP_MICROSECONDS, OP_PUT_SCRAP, OP_GET_SCRAP,
|
||||
OP_ADBOP, OP_INSTIME, OP_RMVTIME, OP_PRIMETIME, OP_MICROSECONDS, OP_ZERO_SCRAP, OP_PUT_SCRAP, OP_GET_SCRAP,
|
||||
OP_DEBUG_STR, OP_INSTALL_DRIVERS, OP_NAME_REGISTRY, OP_RESET, OP_IRQ,
|
||||
OP_SCSI_DISPATCH, OP_SCSI_ATOMIC,
|
||||
OP_CHECK_SYSV, OP_NTRB_17_PATCH, OP_NTRB_17_PATCH2, OP_NTRB_17_PATCH3, OP_NTRB_17_PATCH4, OP_CHECKLOAD,
|
||||
@ -87,6 +87,7 @@ const uint16 M68K_EMUL_OP_INSTIME = M68K_EMUL_BREAK + OP_INSTIME;
|
||||
const uint16 M68K_EMUL_OP_RMVTIME = M68K_EMUL_BREAK + OP_RMVTIME;
|
||||
const uint16 M68K_EMUL_OP_PRIMETIME = M68K_EMUL_BREAK + OP_PRIMETIME;
|
||||
const uint16 M68K_EMUL_OP_MICROSECONDS = M68K_EMUL_BREAK + OP_MICROSECONDS;
|
||||
const uint16 M68K_EMUL_OP_ZERO_SCRAP = M68K_EMUL_BREAK + OP_ZERO_SCRAP;
|
||||
const uint16 M68K_EMUL_OP_PUT_SCRAP = M68K_EMUL_BREAK + OP_PUT_SCRAP;
|
||||
const uint16 M68K_EMUL_OP_GET_SCRAP = M68K_EMUL_BREAK + OP_GET_SCRAP;
|
||||
const uint16 M68K_EMUL_OP_DEBUG_STR = M68K_EMUL_BREAK + OP_DEBUG_STR;
|
||||
|
@ -885,8 +885,10 @@ int load_object(const char *filename, FILE *outfile)
|
||||
char *demangled_name, *func_name;
|
||||
if ((demangled_name = malloc(nd)) == NULL)
|
||||
return -1;
|
||||
if ((func_name = malloc(nf = nd)) == NULL)
|
||||
if ((func_name = malloc(nf = nd)) == NULL) {
|
||||
free(demangled_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
|
||||
const char *name;
|
||||
@ -914,6 +916,9 @@ int load_object(const char *filename, FILE *outfile)
|
||||
fprintf(outfile, "#endif\n");
|
||||
}
|
||||
}
|
||||
|
||||
free(func_name);
|
||||
free(demangled_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2885,8 +2890,10 @@ int gen_file(FILE *outfile, int out_type)
|
||||
char *demangled_name, *func_name;
|
||||
if ((demangled_name = malloc(nd)) == NULL)
|
||||
return -1;
|
||||
if ((func_name = malloc(nf = nd)) == NULL)
|
||||
if ((func_name = malloc(nf = nd)) == NULL) {
|
||||
free(demangled_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(outfile, "#ifndef DEFINE_CST\n");
|
||||
fprintf(outfile, "#define DEFINE_CST(NAME, VALUE)\n");
|
||||
@ -2935,20 +2942,24 @@ int gen_file(FILE *outfile, int out_type)
|
||||
demangled_name = cxx_demangle(name, demangled_name, &nd, &status);
|
||||
if (status == 0 && strstart(demangled_name, OP_PREFIX, NULL)) {
|
||||
/* get real function name */
|
||||
char *p = strchr(demangled_name, '(');
|
||||
if (p && !strstart(p, "()::label", NULL)) {
|
||||
int func_name_length = p - demangled_name;
|
||||
if (nd > nf) {
|
||||
nf = nd;
|
||||
if ((func_name = realloc(func_name, nf)) == NULL)
|
||||
return -1;
|
||||
}
|
||||
strncpy(func_name, demangled_name, func_name_length);
|
||||
func_name[func_name_length] = '\0';
|
||||
/* emit code generator */
|
||||
char *p = strchr(demangled_name, '(');
|
||||
if (p && !strstart(p, "()::label", NULL)) {
|
||||
int func_name_length = p - demangled_name;
|
||||
if (nd > nf) {
|
||||
char *new_func_name;
|
||||
nf = nd;
|
||||
if ((new_func_name = realloc(func_name, nf)) == NULL) {
|
||||
free(func_name);
|
||||
return -1;
|
||||
}
|
||||
func_name = new_func_name;
|
||||
}
|
||||
strncpy(func_name, demangled_name, func_name_length);
|
||||
func_name[func_name_length] = '\0';
|
||||
/* emit code generator */
|
||||
#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF)
|
||||
if (sym->st_shndx != text_shndx)
|
||||
error("invalid section for opcode (%s:0x%x)", name, sym->st_shndx);
|
||||
if (sym->st_shndx != text_shndx)
|
||||
error("invalid section for opcode (%s:0x%x)", name, sym->st_shndx);
|
||||
#endif
|
||||
gen_code(func_name, demangled_name, sym->st_value, sym->st_size, outfile, 3, NULL);
|
||||
}
|
||||
|
@ -60,9 +60,10 @@
|
||||
|
||||
// Other ROM addresses
|
||||
const uint32 CHECK_LOAD_PATCH_SPACE = 0x2fcf00;
|
||||
const uint32 PUT_SCRAP_PATCH_SPACE = 0x2fcf80;
|
||||
const uint32 GET_SCRAP_PATCH_SPACE = 0x2fcfc0;
|
||||
const uint32 ADDR_MAP_PATCH_SPACE = 0x2fd100;
|
||||
const uint32 ZERO_SCRAP_PATCH_SPACE = 0x2fcf80;
|
||||
const uint32 PUT_SCRAP_PATCH_SPACE = 0x2fcfc0;
|
||||
const uint32 GET_SCRAP_PATCH_SPACE = 0x2fd100;
|
||||
const uint32 ADDR_MAP_PATCH_SPACE = 0x2fd140;
|
||||
|
||||
// Global variables
|
||||
int ROMType; // ROM type
|
||||
@ -713,6 +714,8 @@ bool PatchROM(void)
|
||||
// Check that other ROM addresses point to really free regions
|
||||
if (!check_rom_patch_space(CHECK_LOAD_PATCH_SPACE, 0x40))
|
||||
return false;
|
||||
if (!check_rom_patch_space(ZERO_SCRAP_PATCH_SPACE, 0x40))
|
||||
return false;
|
||||
if (!check_rom_patch_space(PUT_SCRAP_PATCH_SPACE, 0x40))
|
||||
return false;
|
||||
if (!check_rom_patch_space(GET_SCRAP_PATCH_SPACE, 0x40))
|
||||
@ -2296,6 +2299,16 @@ static bool patch_68k(void)
|
||||
*wp = htons((level1_int - 12) & 0xffff);
|
||||
}
|
||||
|
||||
// Patch ZeroScrap() for clipboard exchange with host OS
|
||||
uint32 zero_scrap = find_rom_trap(0xa9fc); // ZeroScrap()
|
||||
wp = (uint16 *)(ROMBaseHost + ZERO_SCRAP_PATCH_SPACE);
|
||||
*wp++ = htons(M68K_EMUL_OP_ZERO_SCRAP);
|
||||
*wp++ = htons(M68K_JMP);
|
||||
*wp++ = htons((ROMBase + zero_scrap) >> 16);
|
||||
*wp++ = htons((ROMBase + zero_scrap) & 0xffff);
|
||||
base = ROMBase + ReadMacInt32(ROMBase + 0x22);
|
||||
WriteMacInt32(base + 4 * (0xa9fc & 0x3ff), ZERO_SCRAP_PATCH_SPACE);
|
||||
|
||||
// Patch PutScrap() for clipboard exchange with host OS
|
||||
uint32 put_scrap = find_rom_trap(0xa9fe); // PutScrap()
|
||||
wp = (uint16 *)(ROMBaseHost + PUT_SCRAP_PATCH_SPACE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user