/* Copyright 1994, 1995 by Abacus Research and * Development, Inc. All rights reserved. */ #if !defined (OMIT_RCSID_STRINGS) char ROMlib_rcsid_qCGrafport[] = "$Id: qCGrafPort.c 63 2004-12-24 18:19:43Z ctm $"; #endif #include "rsys/common.h" #include "QuickDraw.h" #include "CQuickDraw.h" #include "MemoryMgr.h" #include "ResourceMgr.h" #include "rsys/quick.h" #include "rsys/cquick.h" #include "rsys/mman.h" #include "rsys/myabort.h" #include "rsys/assert.h" #include "rsys/xdata.h" #include "rsys/evil.h" P1 (PUBLIC pascal trap, void, OpenCPort, CGrafPtr, port) { PixPatHandle temp_pixpat; /* set up port version before using any other macros */ port->portVersion = CWC ((3 << 14) | /* color quickdraw version */ 0); /* allocate storage for new CGrafPtr members, including portPixMap, pnPixPat, fillPixPat, bkPixPat, and grafVar */ CPORT_PIXMAP_X (port) = RM (NewPixMap ()); /* Free up the empty color table, since we're not going to use it. */ DisposHandle ((Handle) PIXMAP_TABLE (CPORT_PIXMAP (port))); temp_pixpat = NewPixPat (); PIXPAT_TYPE_X (temp_pixpat) = CWC (pixpat_type_orig); CPORT_PEN_PIXPAT_X (port) = RM (temp_pixpat); temp_pixpat = NewPixPat (); PIXPAT_TYPE_X (temp_pixpat) = CWC (pixpat_type_orig); CPORT_FILL_PIXPAT_X (port) = RM (temp_pixpat); temp_pixpat = NewPixPat (); PIXPAT_TYPE_X (temp_pixpat) = CWC (pixpat_type_orig); CPORT_BK_PIXPAT_X (port) = RM (temp_pixpat); CPORT_GRAFVARS_X (port) = RM (NewHandleClear (sizeof (GrafVars))); /* allocate storage for members also present in GrafPort */ PORT_VIS_REGION_X (port) = RM (NewRgn ()); PORT_CLIP_REGION_X (port) = RM (NewRgn ()); InitCPort (port); } P1 (PUBLIC pascal trap, void, CloseCPort, CGrafPtr, port) { ClosePort ((GrafPtr) port); } /* FIXME: do these belong here */ P1 (PUBLIC pascal trap, void, InitCPort, CGrafPtr, p) { GDHandle gd; RgnHandle rh; if (!p || !CGrafPort_p (p)) return; /* set the port early so we can call convenience functions that operate on thePort */ SetPort ((GrafPtr) p); CPORT_VERSION_X (p) = (CPORT_FLAG_BITS_X | CWC (/* color quickdraw version */ 0)); gd = MR (TheGDevice); *STARH (CPORT_PIXMAP (p)) = *STARH (GD_PMAP (gd)); PORT_DEVICE_X (p) = CWC (0); PORT_RECT (p) = GD_RECT (gd); PORT_PEN_LOC (p).h = PORT_PEN_LOC (p).v = CWC (0); PORT_PEN_SIZE (p).h = PORT_PEN_SIZE (p).v = CWC (1); PORT_PEN_MODE_X (p) = CWC (patCopy); PORT_PEN_VIS_X (p) = CWC (0); PORT_TX_FONT_X (p) = CWC (0); PORT_TX_FACE_X (p) = 0; *((char *)&p->txFace + 1) = 0; /* Excel & tests show we need to do this. */ PORT_TX_MODE_X (p) = CWC (srcOr); PORT_TX_SIZE_X (p) = CWC (0); PORT_SP_EXTRA_X (p) = CWC (0); RGBForeColor (&ROMlib_black_rgb_color); RGBBackColor (&ROMlib_white_rgb_color); PORT_COLR_BIT_X (p) = CWC (0); PORT_PAT_STRETCH_X (p) = CWC (0); PORT_PIC_SAVE_X (p) = CLC_NULL; PORT_REGION_SAVE_X (p) = CLC_NULL; PORT_POLY_SAVE_X (p) = CLC_NULL; PORT_GRAF_PROCS_X (p) = CLC_NULL; PenPat (black); BackPat (white); /* hack */ ROMlib_fill_pat (black); /* initialize default values for newly allocated CGrafPtr */ PORT_DEVICE_X (p) = CWC (0); /* rgbOpColor of GrafVars field is set to black, rgbHiliteColor is set to the default value (where does this come from) and all other fields are zero'd */ /* A test case shows that grafVars is allocated only if it was NULL. */ if (CPORT_GRAFVARS_X (p) == CLC_NULL) CPORT_GRAFVARS_X (p) = RM (NewHandleClear (sizeof (GrafVars))); /* #warning "p->grafVars not initialized" */ CPORT_OP_COLOR (p) = ROMlib_black_rgb_color; CPORT_HILITE_COLOR (p) = HiliteRGB; CPORT_CH_EXTRA_X (p) = CWC (0); /* represents the low word of a Fixed number whose value is 0.5 */ CPORT_PENLOC_HFRAC_X (p) = CWC (0x8000); rh = PORT_VIS_REGION (p); SetEmptyRgn (rh); RectRgn (rh, &GD_RECT (gd)); rh = PORT_CLIP_REGION (p); SetEmptyRgn (rh); SetRectRgn (rh, -32767, -32767, 32767, 32767); } P1 (PUBLIC pascal trap, void, SetPortPix, PixMapHandle, pixmap) { CPORT_PIXMAP_X (theCPort) = RM (pixmap); } static const LONGINT high_bits_to_colors[2][2][2] = { { { blackColor, blueColor, }, { greenColor, cyanColor }, }, { { redColor, magentaColor, }, { yellowColor, whiteColor }, }, }; P1 (PUBLIC pascal trap, void, RGBForeColor, RGBColor *, color) { if (CGrafPort_p (thePort)) { CPORT_RGB_FG_COLOR (theCPort) = *color; /* pick the best color and store it into `theCPort->fgColor' */ PORT_FG_COLOR_X (theCPort) = CL (Color2Index (color)); } else { /* GrafPort */ int basic_qd_color; basic_qd_color = high_bits_to_colors [CW (color->red) >> 15] [CW (color->green) >> 15] [CW (color->blue) >> 15]; ForeColor (basic_qd_color); } } P1 (PUBLIC pascal trap, void, RGBBackColor, RGBColor *, color) { #if defined (EVIL_ILLUSTRATOR_7_HACK) if (ROMlib_evil_illustrator_7_hack) { color = alloca (sizeof (RGBColor)); color->red = 65535; color->green = 65535; color->blue = 65535; } #endif if (CGrafPort_p (thePort)) { CPORT_RGB_BK_COLOR (theCPort) = *color; /* pick the best color and store it into `theCPort->bkColor' */ PORT_BK_COLOR_X (theCPort) = CL (Color2Index (color)); } else { /* GrafPort */ int basic_qd_color; basic_qd_color = high_bits_to_colors [CW (color->red) >> 15] [CW (color->green) >> 15] [CW (color->blue) >> 15]; BackColor (basic_qd_color); } } P1 (PUBLIC pascal trap, void, GetForeColor, RGBColor *, color) { if (CGrafPort_p (thePort)) *color = CPORT_RGB_FG_COLOR (theCPort); else *color = *(ROMlib_qd_color_to_rgb (PORT_FG_COLOR (thePort))); } P1 (PUBLIC pascal trap, void, GetBackColor, RGBColor *, color) { if (CGrafPort_p (thePort)) *color = CPORT_RGB_BK_COLOR (theCPort); else *color = *(ROMlib_qd_color_to_rgb (PORT_BK_COLOR (thePort))); } P1 (PUBLIC pascal trap, void, PenPixPat, PixPatHandle, new_pen) { if (CGrafPort_p (thePort)) { PixPatHandle old_pen; old_pen = CPORT_PEN_PIXPAT (theCPort); if (old_pen == new_pen) return; if (old_pen && (PIXPAT_TYPE_X (old_pen) == CWC (pixpat_type_orig))) DisposPixPat (old_pen); CPORT_PEN_PIXPAT_X (theCPort) = RM (new_pen); } else PATASSIGN (PORT_PEN_PAT (thePort), PIXPAT_1DATA (new_pen)); } P1 (PUBLIC pascal trap, void, BackPixPat, PixPatHandle, new_bk) { if (CGrafPort_p (thePort)) { PixPatHandle old_bk; old_bk = CPORT_BK_PIXPAT (theCPort); if (old_bk == new_bk) return; if (old_bk && PIXPAT_TYPE_X (old_bk) == CWC (pixpat_type_orig)) DisposPixPat (old_bk); CPORT_BK_PIXPAT_X (theCPort) = RM (new_bk); } else PATASSIGN (PORT_BK_PAT (thePort), PIXPAT_1DATA (new_bk)); } void ROMlib_fill_pixpat (PixPatHandle new_fill) { if (CGrafPort_p (thePort)) { PixPatHandle old_fill; old_fill = CPORT_FILL_PIXPAT (theCPort); if (old_fill == new_fill) return; #if 0 if (PIXPAT_TYPE_X (old_fill) == CWC (pixpat_type_orig)) DisposPixPat (old_fill); #endif CPORT_FILL_PIXPAT_X (theCPort) = RM (new_fill); } else PATASSIGN (PORT_BK_PAT (thePort), PIXPAT_1DATA (new_fill)); } /* where is FillPixPat */ P1 (PUBLIC pascal trap, void, OpColor, RGBColor *, color) { if (! CGrafPort_p (thePort)) return; HxX (CPORT_GRAFVARS (theCPort), rgbOpColor) = *color; } P1 (PUBLIC pascal trap, void, HiliteColor, RGBColor *, color) { if (! CGrafPort_p (thePort)) return; HxX (CPORT_GRAFVARS (theCPort), rgbHiliteColor) = *color; } /* PixMap operations */ P0 (PUBLIC pascal trap, PixMapHandle, NewPixMap) { PixMapHandle pixmap; pixmap = (PixMapHandle) NewHandle (sizeof (PixMap)); if (pixmap == NULL) { #if defined (FLAG_ALLOCATION_FAILURES) gui_fatal ("allocation failure"); #endif return NULL; } HLock ((Handle) pixmap); /* so we can use accessor macros even when we're calling routines that move memory */ /* All PixMap fields except the ColorTable come from TheGDevice. * The ColorTable is allocated but not initialized. (IMV-70) */ if (TheGDevice) { *STARH(pixmap) = *STARH(GD_PMAP(MR(TheGDevice))); } else { /* If TheGDevice is NULL, we fill in some useful default values. * This is a hack to make Executor bootstrap properly. */ memset (STARH (pixmap), 0, sizeof (PixMap)); HxX (pixmap, rowBytes) = PIXMAP_DEFAULT_ROWBYTES_X; PIXMAP_HRES_X (pixmap) = PIXMAP_VRES_X (pixmap) = CWC (72); PIXMAP_PIXEL_TYPE_X (pixmap) = CWC (chunky_pixel_type); PIXMAP_CMP_COUNT_X (pixmap) = CWC (1); } /* The ColorTable is set to an empty ColorTable (IMV-70). */ PIXMAP_TABLE_X (pixmap) = (CTabHandle) RM (NewHandleClear (sizeof (ColorTable))); HUnlock ((Handle) pixmap); return pixmap; } P1 (PUBLIC pascal trap, void, DisposPixMap, PixMapHandle, pixmap) { if (pixmap) { DisposCTable (PIXMAP_TABLE (pixmap)); DisposHandle ((Handle) pixmap); } } P2 (PUBLIC pascal trap, void, CopyPixMap, PixMapHandle, src, PixMapHandle, dst) { CTabHandle dst_ctab; /* save away the destination ctab; it is going to get clobbered. */ dst_ctab = PIXMAP_TABLE (dst); /* #warning "determine actual CopyPixMap behavior" */ *(STARH (dst)) = *(STARH (src)); PIXMAP_TABLE_X (dst) = RM (dst_ctab); ROMlib_copy_ctab (PIXMAP_TABLE (src), dst_ctab); } /* PixPat operations */ P0 (PUBLIC pascal trap, PixPatHandle, NewPixPat) { PixPatHandle pixpat; Handle xdata; pixpat = (PixPatHandle) NewHandle (sizeof (PixPat)); xdata = NewHandleClear (sizeof (xdata_t)); HASSIGN_6 (pixpat, patMap, RM (NewPixMap ()), patData, RM (NewHandle (0)), patType, CWC (pixpat_type_color), patXMap, CLC_NULL, patXData, RM (xdata), patXValid, CWC (-1)); return pixpat; } struct pixpat_res { PixPat pixpat; PixMap patmap; }; typedef struct pixpat_res *pixpat_res_ptr; typedef struct { pixpat_res_ptr p PACKED_P; } HIDDEN_pixpat_res_ptr; typedef HIDDEN_pixpat_res_ptr *pixpat_res_handle; P1 (PUBLIC pascal trap, PixPatHandle, GetPixPat, INTEGER, pixpat_id) { pixpat_res_handle pixpat_res; PixPatHandle pixpat; PixMapHandle patmap; int pixpat_data_offset, pixpat_data_size; CTabPtr ctab_ptr; int ctab_size; Handle xdata; pixpat_res = (pixpat_res_handle) GetResource (TICK ("ppat"), pixpat_id); if (pixpat_res == NULL) return (PixPatHandle) NULL; if (pixpat_res->p == NULL) LoadResource ((Handle) pixpat_res); pixpat = (PixPatHandle) NewHandle (sizeof (PixPat)); patmap = (PixMapHandle) NewHandle (sizeof (PixMap)); *STARH (pixpat) = HxX (pixpat_res, pixpat); *STARH (patmap) = HxX (pixpat_res, patmap); { int pixpat_type; pixpat_type = PIXPAT_TYPE (pixpat); /* ### are `rgb' (and `old_style'?) valid pattern types for pixpat resources */ if (pixpat_type != pixpat_old_style_pattern && pixpat_type != pixpat_color_pattern && pixpat_type != pixpat_rgb_pattern) { warning_unexpected ("unknown pixpat type `%d'", PIXPAT_TYPE (pixpat)); PIXPAT_TYPE_X (pixpat) = CWC (pixpat_color_pattern); } } gui_assert ((int) PIXPAT_MAP_X (pixpat) == CLC (sizeof (PixPat))); PIXPAT_MAP_X (pixpat) = RM (patmap); PIXPAT_XVALID_X (pixpat) = CWC (-1); xdata = NewHandle (sizeof (xdata_t)); memset (STARH (xdata), 0, sizeof (xdata_t)); PIXPAT_XDATA_X (pixpat) = RM (xdata); PIXPAT_XMAP_X (pixpat) = CLC_NULL; pixpat_data_offset = PIXPAT_DATA_AS_OFFSET (pixpat); pixpat_data_size = (PIXMAP_TABLE_AS_OFFSET (patmap) - pixpat_data_offset); HLock((Handle) pixpat); PIXPAT_DATA_X (pixpat) = RM (NewHandle (pixpat_data_size)); HUnlock((Handle) pixpat); BlockMove ((Ptr) ((char *) STARH (pixpat_res) + pixpat_data_offset), STARH (PIXPAT_DATA (pixpat)), pixpat_data_size); LOCK_HANDLE_EXCURSION_1 (pixpat_res, { /* ctab_ptr is a pointer into the pixpat_res_handle; make sure no allocations are done while it is in use */ ctab_ptr = (CTabPtr) ((char *) STARH (pixpat_res) + (int) PIXMAP_TABLE_AS_OFFSET (patmap)); ctab_size = (sizeof (ColorTable) + (sizeof (ColorSpec) * CW (ctab_ptr->ctSize))); /* SetHandleSize ((Handle) PIXMAP_TABLE (patmap), ctab_size); */ HLock ((Handle) patmap); PIXMAP_TABLE_X (patmap) = (CTabHandle) RM (NewHandle (ctab_size)); HUnlock ((Handle) patmap); BlockMove ((Ptr) ctab_ptr, (Ptr) STARH (PIXMAP_TABLE (patmap)), ctab_size); /* ctab_ptr->ctSeed = CL (GetCTSeed ()); */ CTAB_SEED_X (PIXMAP_TABLE (patmap)) = CL (GetCTSeed ()); }); #if 0 gui_assert (GetHandleSize (pixpat_res) == (sizeof (struct pixpat_res) + pixpat_data_size + ctab_size)); #endif /* 0 */ return pixpat; } P1 (PUBLIC pascal trap, void, DisposPixPat, PixPatHandle, pixpat_h) { if (pixpat_h) { /* ##### determine which of these checks are necessary, and which should be asserts that the handles are non-NULL */ if (PIXPAT_MAP_X (pixpat_h)) DisposPixMap (PIXPAT_MAP (pixpat_h)); if (PIXPAT_DATA_X (pixpat_h)) DisposHandle (PIXPAT_DATA (pixpat_h)); /* We ignore the xmap field, so no need to free it. */ if (PIXPAT_XDATA_X (pixpat_h)) xdata_free ((xdata_handle_t) PIXPAT_XDATA (pixpat_h)); DisposHandle ((Handle) pixpat_h); } } P2 (PUBLIC pascal trap, void, CopyPixPat, PixPatHandle, src, PixPatHandle, dst) { int data_size; PIXPAT_TYPE_X (dst) = PIXPAT_TYPE_X (src); CopyPixMap (PIXPAT_MAP (src), PIXPAT_MAP (dst)); data_size = GetHandleSize (PIXPAT_DATA (src)); SetHandleSize (PIXPAT_DATA (dst), data_size); memcpy (STARH (PIXPAT_DATA (dst)), STARH (PIXPAT_DATA (src)), data_size); PIXPAT_XVALID_X (dst) = CWC (-1); PATASSIGN (PIXPAT_1DATA (dst), PIXPAT_1DATA (src)); } P2 (PUBLIC pascal trap, void, MakeRGBPat, PixPatHandle, pixpat, RGBColor *, color) { PixMapHandle patmap; PIXPAT_TYPE_X (pixpat) = CWC (pixpat_rgb_pattern); PIXPAT_XVALID_X (pixpat) = CWC (-1); /* ##### resolve the meaning of the actual PixPat fields */ patmap = PIXPAT_MAP (pixpat); PIXMAP_SET_ROWBYTES_X (patmap, CWC (2)); PIXMAP_BOUNDS (patmap) = ROMlib_pattern_bounds; /* create a table with 5 entries, the last of which will be the desired rgb color */ SetHandleSize ((Handle) PIXMAP_TABLE (patmap), (Size) (sizeof (ColorTable) + (4 * sizeof (ColorSpec)))); CTAB_SEED_X (PIXMAP_TABLE (patmap)) = CL (GetCTSeed ()); CTAB_SIZE_X (PIXMAP_TABLE (patmap)) = CWC (5); CTAB_TABLE (PIXMAP_TABLE (patmap))[4].rgb = *color; }