mirror of
https://github.com/ctm/executor.git
synced 2024-10-01 00:57:10 +00:00
770 lines
16 KiB
C
770 lines
16 KiB
C
|
/* Copyright 1987, 1989, 1990, 1999 by Abacus Research and
|
||
|
* Development, Inc. All rights reserved.
|
||
|
*/
|
||
|
|
||
|
#if !defined (OMIT_RCSID_STRINGS)
|
||
|
char ROMlib_rcsid_scrap[] =
|
||
|
"$Id: scrap.c 63 2004-12-24 18:19:43Z ctm $";
|
||
|
#endif
|
||
|
|
||
|
/* Forward declarations in ScrapMgr.h (DO NOT DELETE THIS LINE) */
|
||
|
|
||
|
#include "rsys/common.h"
|
||
|
#include "FileMgr.h"
|
||
|
#include "ScrapMgr.h"
|
||
|
#include "MemoryMgr.h"
|
||
|
#include "ResourceMgr.h"
|
||
|
#include "OSUtil.h"
|
||
|
#include "CQuickDraw.h"
|
||
|
|
||
|
#include "rsys/notmac.h"
|
||
|
#include "rsys/file.h"
|
||
|
#include "rsys/scrap.h"
|
||
|
#include "rsys/executor.h"
|
||
|
#include "rsys/cquick.h"
|
||
|
|
||
|
#if defined (CYGWIN32) && defined (SDL)
|
||
|
#include "sdlscrap.h"
|
||
|
#include "win_clip.h"
|
||
|
#endif
|
||
|
|
||
|
P0(PUBLIC pascal trap, PScrapStuff, InfoScrap)
|
||
|
{
|
||
|
if (Cx(ScrapState) < 0)
|
||
|
ZeroScrap();
|
||
|
return((PScrapStuff)&ScrapSize);
|
||
|
}
|
||
|
|
||
|
A1(PRIVATE, OSErr, cropen, INTEGER *, fp)
|
||
|
{
|
||
|
OSErr retval;
|
||
|
|
||
|
retval = FSOpen(MR(ScrapName), CW (BootDrive), fp);
|
||
|
if (retval == fnfErr) {
|
||
|
retval = Create(MR(ScrapName), CW (BootDrive), TICK("MACS"), TICK("CLIP"));
|
||
|
if (retval != noErr)
|
||
|
return(retval);
|
||
|
return(FSOpen(MR(ScrapName), CW (BootDrive), fp));
|
||
|
}
|
||
|
return(retval);
|
||
|
}
|
||
|
|
||
|
P0(PUBLIC pascal trap, LONGINT, UnloadScrap)
|
||
|
{
|
||
|
OSErr retval;
|
||
|
INTEGER f;
|
||
|
LONGINT l = Cx(ScrapSize);
|
||
|
|
||
|
if (Cx(ScrapState) > 0) {
|
||
|
retval = cropen(&f);
|
||
|
if (retval != noErr)
|
||
|
/*-->*/ return(retval);
|
||
|
HLock(MR(ScrapHandle));
|
||
|
retval = FSWriteAll(f, &l, STARH(MR(ScrapHandle)));
|
||
|
HUnlock(MR(ScrapHandle));
|
||
|
if (retval != noErr)
|
||
|
/*-->*/ return(retval);
|
||
|
retval = FSClose(f);
|
||
|
if (retval != noErr)
|
||
|
/*-->*/ return(retval);
|
||
|
ScrapState = 0;
|
||
|
}
|
||
|
return noErr;
|
||
|
}
|
||
|
|
||
|
P0(PUBLIC pascal trap, LONGINT, LoadScrap)
|
||
|
{
|
||
|
OSErr retval;
|
||
|
INTEGER f;
|
||
|
LONGINT l = Cx(ScrapSize);
|
||
|
|
||
|
if (ScrapState == 0) {
|
||
|
retval = FSOpen(MR(ScrapName), CW (BootDrive), &f);
|
||
|
if (retval != noErr)
|
||
|
return(retval);
|
||
|
|
||
|
HUnlock(MR(ScrapHandle));
|
||
|
ReallocHandle(MR(ScrapHandle), (Size)Cx(ScrapSize));
|
||
|
if (MemErr != noErr)
|
||
|
/*-->*/ return Cx(MemErr);
|
||
|
HLock(MR(ScrapHandle));
|
||
|
retval = FSReadAll(f, &l, STARH(MR(ScrapHandle)));
|
||
|
HUnlock(MR(ScrapHandle));
|
||
|
if (retval != noErr)
|
||
|
return(retval);
|
||
|
SetEOF(f, (LONGINT) 0);
|
||
|
FSClose(f);
|
||
|
ScrapState = CWC (1);
|
||
|
}
|
||
|
return(Cx(ScrapState) > 0 ? noErr : noScrapErr);
|
||
|
}
|
||
|
|
||
|
A0(PUBLIC, LONGINT, ROMlib_ZeroScrap)
|
||
|
{
|
||
|
OSErr retval;
|
||
|
INTEGER f;
|
||
|
THz saveZone;
|
||
|
|
||
|
if (Cx(ScrapState) < 0) {
|
||
|
ScrapCount = 0;
|
||
|
saveZone = TheZone;
|
||
|
TheZone = SysZone;
|
||
|
ScrapHandle = RM(NewHandle((Size)0));
|
||
|
TheZone = saveZone;
|
||
|
ScrapState = CWC (1);
|
||
|
ScrapName = RM((StringPtr) "\016Clipboard File");
|
||
|
} else if (Cx(ScrapState) == 0) {
|
||
|
retval = cropen(&f);
|
||
|
if (retval != noErr)
|
||
|
return retval;
|
||
|
retval = SetEOF(f, (LONGINT)0);
|
||
|
if (retval != noErr)
|
||
|
return retval;
|
||
|
FSClose(f);
|
||
|
} else if (Cx(ScrapState) > 0)
|
||
|
SetHandleSize(MR(ScrapHandle), (Size)0);
|
||
|
ScrapSize = 0;
|
||
|
ScrapCount = CW(CW(ScrapCount) + 1);
|
||
|
return noErr;
|
||
|
}
|
||
|
|
||
|
P0(PUBLIC pascal trap, LONGINT, ZeroScrap)
|
||
|
{
|
||
|
return ROMlib_ZeroScrap();
|
||
|
}
|
||
|
|
||
|
P3(PUBLIC pascal trap, LONGINT, PutScrap, LONGINT, len, ResType, rest, Ptr, p)
|
||
|
{
|
||
|
OSErr retval;
|
||
|
LONGINT l, swappedlen;
|
||
|
INTEGER f;
|
||
|
|
||
|
LONGINT *lp;
|
||
|
|
||
|
if (Cx(ScrapState) < 0) {
|
||
|
retval = ZeroScrap();
|
||
|
if (retval != noErr)
|
||
|
/*-->*/ return(retval);
|
||
|
}
|
||
|
#if defined(X) || defined(NEXTSTEP) || defined (SDL)
|
||
|
PutScrapX(rest, len, (char *) p, CW (ScrapCount));
|
||
|
#endif /* defined(X) */
|
||
|
if (Cx(ScrapState) == 0) {
|
||
|
retval = FSOpen(MR(ScrapName), CW (BootDrive), &f);
|
||
|
if (retval != noErr)
|
||
|
/*-->*/ return(retval);
|
||
|
SetFPos(f, fsFromStart, (LONGINT)Cx(ScrapSize));
|
||
|
l = 4;
|
||
|
rest = CL(rest);
|
||
|
FSWriteAll(f, &l, (Ptr) &rest);
|
||
|
l = 4;
|
||
|
swappedlen = CL(len);
|
||
|
FSWriteAll(f, &l, (Ptr) &swappedlen);
|
||
|
l = len = (len + 1) & -2L;
|
||
|
FSWriteAll(f, &len, p);
|
||
|
FSClose(f);
|
||
|
} else {
|
||
|
SetHandleSize(MR(ScrapHandle), (Size)Cx(ScrapSize) + 8);
|
||
|
if (MemErr != noErr)
|
||
|
/*-->*/ return CW(MemErr);
|
||
|
/* alignment stuff */
|
||
|
lp = (LONGINT *)((char *)STARH(MR(ScrapHandle)) + Cx(ScrapSize));
|
||
|
*lp++ = CL(rest);
|
||
|
*lp++ = CL(len);
|
||
|
len = (len + 1) & -2L;
|
||
|
PtrAndHand(p, MR(ScrapHandle), (Size)len);
|
||
|
}
|
||
|
ScrapSize = CL(CL(ScrapSize) + 8 + len);
|
||
|
return noErr;
|
||
|
}
|
||
|
|
||
|
#if defined (CYGWIN32)
|
||
|
PUBLIC int
|
||
|
count_char (const char *p, int len, char c)
|
||
|
{
|
||
|
int retval;
|
||
|
|
||
|
retval = 0;
|
||
|
while (--len >= 0)
|
||
|
if (*p++ == c)
|
||
|
++retval;
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PRIVATE void
|
||
|
memcpy_but_delete_char (char *destp, const char *srcp, int len, char to_del)
|
||
|
{
|
||
|
while (--len >= 0)
|
||
|
{
|
||
|
char c;
|
||
|
|
||
|
c = *srcp++;
|
||
|
if (c != to_del)
|
||
|
*destp++ = c;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PUBLIC int
|
||
|
get_scrap_helper (void *vh, void *lp, int len, boolean_t convert_text)
|
||
|
{
|
||
|
int retval;
|
||
|
int new_len;
|
||
|
Handle h;
|
||
|
|
||
|
if (convert_text)
|
||
|
new_len = len - count_char (lp, len, '\n'); /* won't copy linefeeds */
|
||
|
else
|
||
|
new_len = len;
|
||
|
h = (Handle) vh;
|
||
|
ReallocHandle (h, new_len);
|
||
|
if (MemErr != noErr)
|
||
|
retval = -1;
|
||
|
else
|
||
|
{
|
||
|
if (convert_text)
|
||
|
memcpy_but_delete_char (STARH (h), lp, len, '\n');
|
||
|
else
|
||
|
memcpy (STARH (h), lp, len);
|
||
|
retval = new_len;
|
||
|
}
|
||
|
return retval;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#define RETURN(x) return (temph ? (DisposHandle(temph), 0) : 0), x
|
||
|
|
||
|
P3(PUBLIC pascal trap, LONGINT, GetScrap, Handle, h, ResType, rest,
|
||
|
LONGINT *, off)
|
||
|
{
|
||
|
OSErr retval;
|
||
|
LONGINT l = 0, incr, s, ltoread, restlen[2];
|
||
|
unsigned char *p;
|
||
|
int found;
|
||
|
INTEGER f;
|
||
|
Handle temph;
|
||
|
|
||
|
#if !defined (LETGCCWAIL)
|
||
|
s = 0;
|
||
|
#endif /* LETGCCWAIL */
|
||
|
if (h)
|
||
|
temph = 0;
|
||
|
else {
|
||
|
temph = NewHandle((Size) 0);
|
||
|
h = temph;
|
||
|
}
|
||
|
|
||
|
#if defined(X) || defined(NEXTSTEP) || defined (SDL)
|
||
|
s = GetScrapX(rest, (char **) h);
|
||
|
if (s >= 0) {
|
||
|
*off = 0; /* ack... could mess people up */
|
||
|
/*-->*/ RETURN(s);
|
||
|
}
|
||
|
#endif /* defined(X) */
|
||
|
if (Cx(ScrapState) < 0) {
|
||
|
retval = ZeroScrap();
|
||
|
if (retval != noErr)
|
||
|
/*-->*/ RETURN(retval);
|
||
|
}
|
||
|
if (ScrapState == 0) {
|
||
|
retval = FSOpen(MR(ScrapName), CW (BootDrive), &f);
|
||
|
if (retval != noErr)
|
||
|
/*-->*/ RETURN(retval);
|
||
|
found = FALSE;
|
||
|
while (l < Cx(ScrapSize) && !found) {
|
||
|
ltoread = 8;
|
||
|
FSReadAll(f, <oread, (Ptr) restlen);
|
||
|
s = CL(restlen[1]);
|
||
|
if (rest == CL(restlen[0]))
|
||
|
found = TRUE;
|
||
|
else {
|
||
|
incr = (8 + s + 1) & ~1L;
|
||
|
l += incr;
|
||
|
SetFPos(f, fsFromMark, incr);
|
||
|
}
|
||
|
}
|
||
|
if (l >= Cx(ScrapSize)) {
|
||
|
FSClose(f);
|
||
|
/*-->*/ RETURN(noTypeErr);
|
||
|
}
|
||
|
ReallocHandle(h, s);
|
||
|
if (MemErr != noErr)
|
||
|
/*-->*/ RETURN(CW(MemErr));
|
||
|
HLock(h);
|
||
|
ltoread = s;
|
||
|
FSReadAll(f, <oread, STARH(h));
|
||
|
HUnlock(h);
|
||
|
FSClose(f);
|
||
|
} else {
|
||
|
HLock(MR(ScrapHandle));
|
||
|
p = MR(*(unsigned char **)MR(ScrapHandle));
|
||
|
#if 1 || !defined(QUADALIGN)
|
||
|
while (l < Cx(ScrapSize) && rest != CL(*(LONGINT *)p))
|
||
|
{
|
||
|
s = CL (*((LONGINT *) p + 1));
|
||
|
incr = (8 + s + 1) & ~1L;
|
||
|
l += incr;
|
||
|
p += incr;
|
||
|
}
|
||
|
if (l >= Cx(ScrapSize))
|
||
|
{
|
||
|
HUnlock(MR(ScrapHandle));
|
||
|
/*-->*/ RETURN(noTypeErr);
|
||
|
}
|
||
|
s = CL (*((LONGINT *)p + 1));
|
||
|
#else /* QUADALIGN */
|
||
|
while (l < Cx(ScrapSize) && rest != SNAGLONG(p)) {
|
||
|
incr = 8 + ((s = SNAGLONG(p + sizeof(LONGINT))) + 1) & -2L;
|
||
|
l += incr;
|
||
|
p += incr;
|
||
|
}
|
||
|
if (l >= Cx(ScrapSize))
|
||
|
{
|
||
|
HUnlock(MR(ScrapHandle));
|
||
|
/*-->*/ RETURN(noTypeErr);
|
||
|
}
|
||
|
s = *((LONGINT *)p + 1);
|
||
|
#endif /* QUADALIGN */
|
||
|
PtrToXHand((Ptr) (p+8), h, s);
|
||
|
HUnlock(MR(ScrapHandle));
|
||
|
}
|
||
|
*off = CL(l+8);
|
||
|
RETURN(s);
|
||
|
}
|
||
|
|
||
|
#if defined (CYGWIN32) && defined (SDL)
|
||
|
|
||
|
#include "SDL/SDL.h"
|
||
|
|
||
|
PRIVATE int
|
||
|
SDL_Surface_depth (const SDL_Surface *surfp)
|
||
|
{
|
||
|
int retval;
|
||
|
retval = surfp->format->BitsPerPixel;
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PRIVATE int
|
||
|
SDL_Surface_width (const SDL_Surface *surfp)
|
||
|
{
|
||
|
int retval;
|
||
|
retval = surfp->w;
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PRIVATE int
|
||
|
SDL_Surface_height (const SDL_Surface *surfp)
|
||
|
{
|
||
|
int retval;
|
||
|
retval = surfp->h;
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PUBLIC void *
|
||
|
SDL_Surface_pixels (const SDL_Surface *surfp)
|
||
|
{
|
||
|
void *retval;
|
||
|
retval = surfp->pixels;
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PUBLIC int
|
||
|
SDL_Surface_pitch (const SDL_Surface *surfp)
|
||
|
{
|
||
|
int retval;
|
||
|
retval = surfp->pitch;
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PUBLIC int
|
||
|
SDL_n_colors (const SDL_Surface *surfp)
|
||
|
{
|
||
|
int retval;
|
||
|
retval = surfp->format->palette->ncolors;
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PUBLIC SDL_Color *
|
||
|
SDL_colors (const SDL_Surface *surfp)
|
||
|
{
|
||
|
SDL_Color *retval;
|
||
|
retval = surfp->format->palette->colors;
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8 blue PACKED;
|
||
|
uint8 red PACKED;
|
||
|
uint8 green PACKED;
|
||
|
}
|
||
|
sdl_pixel24;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint8 zero PACKED;
|
||
|
uint8 red PACKED;
|
||
|
uint8 green PACKED;
|
||
|
uint8 blue PACKED;
|
||
|
}
|
||
|
mac_pixel32;
|
||
|
|
||
|
#define advance_n_bytes(ptrp, n_bytes) \
|
||
|
({ \
|
||
|
typeof (ptrp) _ptrp; \
|
||
|
\
|
||
|
_ptrp = (ptrp); \
|
||
|
*(_ptrp) = (typeof (*_ptrp))((char *)*(_ptrp) + n_bytes); \
|
||
|
})
|
||
|
|
||
|
#define MAC_COLOR_COMPONENT_FROM_SDL_CC(x) \
|
||
|
({ \
|
||
|
typeof (x) _x; \
|
||
|
\
|
||
|
_x = (x); \
|
||
|
(_x << 8)|(uint8)_x; \
|
||
|
})
|
||
|
|
||
|
PRIVATE CTabHandle
|
||
|
ctab_from_surface (SDL_Surface *surfp)
|
||
|
{
|
||
|
CTabHandle retval;
|
||
|
int n_colors;
|
||
|
SDL_Color *ip;
|
||
|
ColorSpec *op;
|
||
|
int i;
|
||
|
|
||
|
retval = NULL;
|
||
|
|
||
|
n_colors = SDL_n_colors (surfp);
|
||
|
retval = (CTabHandle) NewHandle (CTAB_STORAGE_FOR_SIZE (n_colors-1));
|
||
|
CTAB_SIZE_X (retval) = CW (n_colors - 1);
|
||
|
CTAB_SEED_X (retval) = CL (GetCTSeed ());
|
||
|
CTAB_FLAGS_X (retval) = CTAB_GDEVICE_BIT_X;
|
||
|
|
||
|
for (i = 0, ip = SDL_colors (surfp), op = CTAB_TABLE (retval);
|
||
|
i < n_colors;
|
||
|
++i, ++ip, ++op)
|
||
|
{
|
||
|
op->value = CWC (0);
|
||
|
op->rgb.red = MAC_COLOR_COMPONENT_FROM_SDL_CC (ip->r);
|
||
|
op->rgb.green = MAC_COLOR_COMPONENT_FROM_SDL_CC (ip->g);
|
||
|
op->rgb.blue = MAC_COLOR_COMPONENT_FROM_SDL_CC (ip->b);
|
||
|
}
|
||
|
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PRIVATE GWorldPtr
|
||
|
gworld_from_surface (SDL_Surface *surfp)
|
||
|
{
|
||
|
GWorldPtr retval;
|
||
|
|
||
|
retval = NULL;
|
||
|
|
||
|
if (surfp)
|
||
|
{
|
||
|
QDErr err;
|
||
|
int surf_depth;
|
||
|
CTabHandle ctab;
|
||
|
|
||
|
ctab = NULL;
|
||
|
|
||
|
surf_depth = SDL_Surface_depth (surfp);
|
||
|
switch (surf_depth)
|
||
|
{
|
||
|
case 8:
|
||
|
ctab = ctab_from_surface (surfp);
|
||
|
break;
|
||
|
case 32:
|
||
|
break;
|
||
|
default:
|
||
|
warning_unexpected ("surf_depth = %d", surf_depth);
|
||
|
surf_depth = 0;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (surf_depth)
|
||
|
{
|
||
|
int n_lines;
|
||
|
int pixels_per_line;
|
||
|
Rect r;
|
||
|
|
||
|
n_lines = SDL_Surface_height (surfp);
|
||
|
pixels_per_line = SDL_Surface_width (surfp);
|
||
|
|
||
|
r.top = CWC (0);
|
||
|
r.left = CWC (0);
|
||
|
r.bottom = CW (n_lines);
|
||
|
r.right = CW (pixels_per_line);
|
||
|
{
|
||
|
CGrafPtr save_port;
|
||
|
GDHandle save_device;
|
||
|
|
||
|
GetGWorld (&save_port, &save_device);
|
||
|
save_port = MR (save_port);
|
||
|
save_device = MR (save_device);
|
||
|
err = NewGWorld (&retval, surf_depth, &r, ctab, NULL, keepLocal);
|
||
|
SetGWorld (save_port, save_device);
|
||
|
}
|
||
|
if (retval)
|
||
|
{
|
||
|
PixMapHandle pm;
|
||
|
|
||
|
retval = MR (retval);
|
||
|
pm = GetGWorldPixMap (retval);
|
||
|
LockPixels (pm);
|
||
|
SDL_LockSurface (surfp);
|
||
|
|
||
|
switch (surf_depth)
|
||
|
{
|
||
|
case 8:
|
||
|
{
|
||
|
uint8 *ip, *eip;
|
||
|
uint8 *op;
|
||
|
int rowbytes;
|
||
|
int pitch;
|
||
|
|
||
|
pitch = SDL_Surface_pitch (surfp);
|
||
|
rowbytes = PIXMAP_ROWBYTES (pm);
|
||
|
|
||
|
ip = SDL_Surface_pixels (surfp);
|
||
|
op = (typeof (op)) GetPixBaseAddr (pm);
|
||
|
eip = ip + n_lines * pitch;
|
||
|
for (; ip != eip; ip += pitch, op += rowbytes)
|
||
|
memcpy (op, ip, rowbytes);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 32:
|
||
|
{
|
||
|
sdl_pixel24 *ip;
|
||
|
mac_pixel32 *op;
|
||
|
|
||
|
op = (typeof (op)) GetPixBaseAddr (pm);
|
||
|
ip = SDL_Surface_pixels (surfp);
|
||
|
|
||
|
memcpy (op, ip, n_lines * pixels_per_line * sizeof *op);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
warning_unexpected ("surf_depth = %d", surf_depth);
|
||
|
break;
|
||
|
}
|
||
|
SDL_UnlockSurface (surfp);
|
||
|
UnlockPixels (pm);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PRIVATE PicHandle
|
||
|
pict_from_gworld (GWorldPtr gp, int *lenp)
|
||
|
{
|
||
|
PicHandle retval;
|
||
|
|
||
|
if (!gp)
|
||
|
retval = NULL;
|
||
|
else
|
||
|
{
|
||
|
Rect pict_frame;
|
||
|
PixMapHandle pm;
|
||
|
|
||
|
pm = GetGWorldPixMap (gp);
|
||
|
pict_frame = PIXMAP_BOUNDS (pm);
|
||
|
retval = OpenPicture (&pict_frame);
|
||
|
if (retval)
|
||
|
{
|
||
|
ClipRect (&pict_frame);
|
||
|
HLock ((Handle) pm);
|
||
|
CopyBits ((BitMap *) STARH (pm), PORT_BITS_FOR_COPY (thePort),
|
||
|
&pict_frame, &pict_frame, srcCopy, NULL);
|
||
|
HUnlock ((Handle) pm);
|
||
|
ClosePicture ();
|
||
|
}
|
||
|
}
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PUBLIC int
|
||
|
get_scrap_helper_dib (void *vh, void *lp)
|
||
|
{
|
||
|
SDL_Surface *surfp;
|
||
|
GWorldPtr gp;
|
||
|
PicHandle pich;
|
||
|
Handle h;
|
||
|
int retval;
|
||
|
int len;
|
||
|
|
||
|
surfp = surface_from_dib (lp);
|
||
|
gp = gworld_from_surface (surfp);
|
||
|
SDL_FreeSurface (surfp);
|
||
|
pich = pict_from_gworld (gp, &len);
|
||
|
DisposeGWorld (gp);
|
||
|
h = (Handle) vh;
|
||
|
len = GetHandleSize ((Handle) pich);
|
||
|
ReallocHandle (h, len);
|
||
|
if (MemErr != noErr)
|
||
|
retval = -1;
|
||
|
else
|
||
|
{
|
||
|
memcpy (STARH (h), STARH (pich), len);
|
||
|
retval = len;
|
||
|
}
|
||
|
DisposHandle ((Handle) pich);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PRIVATE PicHandle
|
||
|
pict_from_lp (const void *lp)
|
||
|
{
|
||
|
PicHandle retval;
|
||
|
|
||
|
if (!lp)
|
||
|
retval = NULL;
|
||
|
else
|
||
|
{
|
||
|
int len;
|
||
|
|
||
|
len = *(int *)lp;
|
||
|
retval = (PicHandle) NewHandle (len);
|
||
|
if (retval)
|
||
|
{
|
||
|
char *p;
|
||
|
|
||
|
p = (char *) STARH (retval);
|
||
|
if (p)
|
||
|
memcpy (p, (char *)lp+sizeof(int), len);
|
||
|
else
|
||
|
{
|
||
|
warning_unexpected (NULL_STRING);
|
||
|
DisposHandle ((Handle) retval);
|
||
|
retval = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PRIVATE GWorldPtr
|
||
|
gworld_from_pict (PicHandle ph)
|
||
|
{
|
||
|
GWorldPtr retval;
|
||
|
|
||
|
retval = NULL;
|
||
|
if (ph)
|
||
|
{
|
||
|
CGrafPtr save_port;
|
||
|
GDHandle save_device;
|
||
|
Rect r;
|
||
|
OSErr err;
|
||
|
|
||
|
GetGWorld (&save_port, &save_device);
|
||
|
save_port = MR (save_port);
|
||
|
save_device = MR (save_device);
|
||
|
r = HxX (ph, picFrame);
|
||
|
err = NewGWorld (&retval, 32, &r, NULL, NULL, keepLocal);
|
||
|
if (retval)
|
||
|
{
|
||
|
PixMapHandle pm;
|
||
|
|
||
|
retval = MR (retval);
|
||
|
SetGWorld (retval, NULL);
|
||
|
pm = GetGWorldPixMap (retval);
|
||
|
LockPixels (pm);
|
||
|
DrawPicture (ph, &r);
|
||
|
#if 0
|
||
|
#warning THIS INTERFERES WITH PICT PASTING
|
||
|
{
|
||
|
char *p;
|
||
|
|
||
|
EraseRect (&r);
|
||
|
p = GetPixBaseAddr (pm);
|
||
|
memset (p, 0x00, 4 * RECT_HEIGHT(&r) * RECT_WIDTH (&r));
|
||
|
memset (p, 0xFF, 4 * RECT_HEIGHT(&r) * RECT_WIDTH (&r) / 2);
|
||
|
}
|
||
|
#endif
|
||
|
UnlockPixels (pm);
|
||
|
}
|
||
|
SetGWorld (save_port, save_device);
|
||
|
}
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
PRIVATE SDL_Surface *
|
||
|
surface_from_gworld (GWorldPtr gp)
|
||
|
{
|
||
|
SDL_Surface *retval;
|
||
|
|
||
|
if (!gp)
|
||
|
retval = NULL;
|
||
|
else
|
||
|
{
|
||
|
int pixels_per_line;
|
||
|
int n_lines;
|
||
|
PixMapHandle pm;
|
||
|
enum { A = 0x00000000,
|
||
|
R = 0x0000FF00,
|
||
|
G = 0x00FF0000,
|
||
|
B = 0xFF000000 };
|
||
|
mac_pixel32 *ip;
|
||
|
sdl_pixel24 *op;
|
||
|
Rect r;
|
||
|
|
||
|
pm = GetGWorldPixMap (gp);
|
||
|
LockPixels (pm);
|
||
|
|
||
|
r = PIXMAP_BOUNDS (pm);
|
||
|
n_lines = RECT_HEIGHT (&r);
|
||
|
pixels_per_line = RECT_WIDTH (&r);
|
||
|
retval = SDL_AllocSurface (SDL_SWSURFACE, pixels_per_line, n_lines, 32,
|
||
|
R, G, B, A);
|
||
|
SDL_LockSurface (retval);
|
||
|
op = SDL_Surface_pixels (retval);
|
||
|
ip = (typeof (ip)) GetPixBaseAddr (pm);
|
||
|
memcpy (op, ip, n_lines * pixels_per_line * sizeof *ip);
|
||
|
#if 0
|
||
|
#warning THIS IS BROKEN
|
||
|
memset (op, 0x00, 4 * n_lines * pixels_per_line);
|
||
|
memset (op, 0xFF, 4 * n_lines * pixels_per_line / 2);
|
||
|
#endif
|
||
|
SDL_UnlockSurface (retval);
|
||
|
UnlockPixels (pm);
|
||
|
}
|
||
|
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
/* write_surfp_to_clipboard */
|
||
|
|
||
|
PUBLIC void
|
||
|
put_scrap_helper_dib (void *lp)
|
||
|
{
|
||
|
PicHandle pich;
|
||
|
|
||
|
pich = pict_from_lp (lp);
|
||
|
if (pich)
|
||
|
{
|
||
|
GWorldPtr gp;
|
||
|
|
||
|
gp = gworld_from_pict (pich);
|
||
|
if (gp)
|
||
|
{
|
||
|
SDL_Surface *surfp;
|
||
|
|
||
|
surfp = surface_from_gworld (gp);
|
||
|
if (surfp)
|
||
|
{
|
||
|
write_surfp_to_clipboard (surfp);
|
||
|
SDL_FreeSurface (surfp);
|
||
|
}
|
||
|
DisposeGWorld (gp);
|
||
|
}
|
||
|
DisposHandle ((Handle) pich);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|