From 77405d3805b154ba86b66a7f39c213d41b4e2f07 Mon Sep 17 00:00:00 2001 From: RandoOnSteam Date: Tue, 8 Sep 2026 09:19:57 -0700 Subject: [PATCH 1/6] mac classic/carbon port --- curses.h | 3 ++- mac/CMakeLists.txt | 1 + mac/pdcclip.c | 1 + mac/pdcdisp.c | 1 + mac/pdcgetsc.c | 1 + mac/pdckbd.c | 1 + mac/pdcmac.h | 1 + mac/pdcscrn.c | 1 + mac/pdcsetsc.c | 1 + mac/pdcurses.r | 1 + mac/pdcursescw6win.mcp | Bin 0 -> 268637 bytes mac/pdcursescw8mac | Bin 0 -> 223034 bytes mac/pdcutil.c | 1 + pdcurses/debug.c | 4 +++- pdcurses/getch.c | 7 +++++++ 15 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 mac/CMakeLists.txt create mode 100644 mac/pdcclip.c create mode 100644 mac/pdcdisp.c create mode 100644 mac/pdcgetsc.c create mode 100644 mac/pdckbd.c create mode 100644 mac/pdcmac.h create mode 100644 mac/pdcscrn.c create mode 100644 mac/pdcsetsc.c create mode 100644 mac/pdcurses.r create mode 100644 mac/pdcursescw6win.mcp create mode 100644 mac/pdcursescw8mac create mode 100644 mac/pdcutil.c diff --git a/curses.h b/curses.h index 3049ee89..810bb744 100644 --- a/curses.h +++ b/curses.h @@ -179,7 +179,8 @@ enum PDC_port PDC_PORT_LINUX_FB = 10, PDC_PORT_OPENGL = 11, PDC_PORT_OS2GUI = 12, - PDC_PORT_SDL3 = 13 + PDC_PORT_SDL3 = 13, + PDC_PORT_MAC = 14 }; /* Use this structure with PDC_get_version() for run-time info about the diff --git a/mac/CMakeLists.txt b/mac/CMakeLists.txt new file mode 100644 index 00000000..d282b7c5 --- /dev/null +++ b/mac/CMakeLists.txt @@ -0,0 +1 @@ +cmake_minimum_required(VERSION 3.11) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "MinSizeRel" CACHE STRING "Choose the type of build, options are: Debug, Release, or MinSizeRel." FORCE) message(STATUS "No build type specified, defaulting to MinSizeRel.") endif() PROJECT(mac VERSION "${PROJECT_VERSION}" LANGUAGES C) add_definitions(-DTARGET_API_MAC_CARBON=1) INCLUDE(project_common) demo_app(../demos calendar) demo_app(../demos firework) demo_app(../demos init_col) demo_app(../demos mbrot) demo_app(../demos newtest) demo_app(../demos ozdemo) demo_app(../demos picsview) demo_app(../demos ptest) demo_app(../demos rain) demo_app(../demos speed) demo_app(../demos test_pan) demo_app(../demos testcurs) demo_app(../demos version) demo_app(../demos widetest) demo_app(../demos worm) demo_app(../demos xmas) SET(CPACK_COMPONENTS_ALL applications) \ No newline at end of file diff --git a/mac/pdcclip.c b/mac/pdcclip.c new file mode 100644 index 00000000..08441276 --- /dev/null +++ b/mac/pdcclip.c @@ -0,0 +1 @@ +#include "pdcmac.h" #include #include static const unsigned short macroman_unicode[128] = { 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8, 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02, 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7 }; unsigned short PDC_macroman_to_unicode(unsigned char ch) { if (ch < 0x80) return (unsigned short)ch; return macroman_unicode[ch - 0x80]; } unsigned char PDC_unicode_to_macroman(unsigned long code) { int i; if (code < 0x80) return (unsigned char)code; for (i = 0; i < 128; i++) { if ((unsigned long)macroman_unicode[i] == code) return (unsigned char)(i + 0x80); } return (unsigned char)'?'; } static int utf8_encode(unsigned long code, char *out) { if (code < 0x80) { out[0] = (char)code; return 1; } if (code < 0x800) { out[0] = (char)(0xC0 | (code >> 6)); out[1] = (char)(0x80 | (code & 0x3F)); return 2; } if (code < 0x10000) { out[0] = (char)(0xE0 | (code >> 12)); out[1] = (char)(0x80 | ((code >> 6) & 0x3F)); out[2] = (char)(0x80 | (code & 0x3F)); return 3; } out[0] = (char)(0xF0 | (code >> 18)); out[1] = (char)(0x80 | ((code >> 12) & 0x3F)); out[2] = (char)(0x80 | ((code >> 6) & 0x3F)); out[3] = (char)(0x80 | (code & 0x3F)); return 4; } static unsigned long utf8_decode(const unsigned char **pp, const unsigned char *end) { const unsigned char *p; unsigned long code; unsigned int extra; p = *pp; if (p >= end) return 0; if (p[0] < 0x80) { code = p[0]; *pp = p + 1; return code; } if ((p[0] & 0xE0) == 0xC0) { extra = 1; code = p[0] & 0x1F; } else if ((p[0] & 0xF0) == 0xE0) { extra = 2; code = p[0] & 0x0F; } else if ((p[0] & 0xF8) == 0xF0) { extra = 3; code = p[0] & 0x07; } else { *pp = p + 1; return (unsigned long)'?'; } if (p + extra >= end) { *pp = end; return (unsigned long)'?'; } while (extra) { p++; extra--; if ((p[0] & 0xC0) != 0x80) { *pp = p; return (unsigned long)'?'; } code = (code << 6) | (p[0] & 0x3F); } *pp = p + 1; return code; } static int use_utf8_clipboard(void) { #ifdef PDC_WIDE return 1; #else #ifdef PDC_FORCE_UTF8 return 1; #else return 0; #endif #endif } static char *macroman_buffer_to_result(const char *src, long srclen, long *outlen) { char *result; long i; long destlen; long destpos; if (!use_utf8_clipboard()) { result = (char *)malloc((size_t)srclen + 1); if (!result) return NULL; memcpy(result, src, (size_t)srclen); result[srclen] = 0; *outlen = srclen; return result; } destlen = 0; for (i = 0; i < srclen; i++) { unsigned long code; char temp[4]; code = PDC_macroman_to_unicode((unsigned char)src[i]); destlen += utf8_encode(code, temp); } result = (char *)malloc((size_t)destlen + 1); if (!result) return NULL; destpos = 0; for (i = 0; i < srclen; i++) { unsigned long code; char temp[4]; int n; code = PDC_macroman_to_unicode((unsigned char)src[i]); n = utf8_encode(code, temp); memcpy(result + destpos, temp, (size_t)n); destpos += n; } result[destpos] = 0; *outlen = destpos; return result; } static char *result_to_macroman(const char *src, long srclen, long *outlen) { char *result; long destpos; if (!use_utf8_clipboard()) { result = (char *)malloc((size_t)srclen + 1); if (!result) return NULL; memcpy(result, src, (size_t)srclen); result[srclen] = 0; *outlen = srclen; return result; } result = (char *)malloc((size_t)srclen + 1); if (!result) return NULL; destpos = 0; { const unsigned char *p; const unsigned char *end; p = (const unsigned char *)src; end = p + srclen; while (p < end) { unsigned long code; code = utf8_decode(&p, end); result[destpos] = (char)PDC_unicode_to_macroman(code); destpos++; } } result[destpos] = 0; *outlen = destpos; return result; } int PDC_getclipboard(char **contents, long *length) { char *raw; long rawlen; PDC_LOG(("PDC_getclipboard() - called\n")); *contents = NULL; *length = 0; #if TARGET_API_MAC_CARBON { ScrapRef scrap; Size bytecount; OSStatus err; err = GetCurrentScrap(&scrap); if (err != noErr) return PDC_CLIP_ACCESS_ERROR; err = GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &bytecount); if (err == noTypeErr || bytecount <= 0) return PDC_CLIP_EMPTY; if (err != noErr) return PDC_CLIP_ACCESS_ERROR; raw = (char *)malloc((size_t)bytecount + 1); if (!raw) return PDC_CLIP_MEMORY_ERROR; err = GetScrapFlavorData(scrap, kScrapFlavorTypeText, &bytecount, raw); if (err != noErr) { free(raw); return PDC_CLIP_ACCESS_ERROR; } rawlen = (long)bytecount; raw[rawlen] = 0; } #else { Handle datahandle; long offset; long scraplen; datahandle = NewHandle(0); if (!datahandle) return PDC_CLIP_MEMORY_ERROR; scraplen = GetScrap(datahandle, kScrapFlavorTypeText, &offset); if (scraplen <= 0) { DisposeHandle(datahandle); if (scraplen == 0 || scraplen == noTypeErr) return PDC_CLIP_EMPTY; return PDC_CLIP_ACCESS_ERROR; } HLock(datahandle); raw = (char *)malloc((size_t)scraplen + 1); if (!raw) { HUnlock(datahandle); DisposeHandle(datahandle); return PDC_CLIP_MEMORY_ERROR; } BlockMoveData(*datahandle, raw, scraplen); rawlen = scraplen; raw[rawlen] = 0; HUnlock(datahandle); DisposeHandle(datahandle); } #endif *contents = macroman_buffer_to_result(raw, rawlen, length); free(raw); if (!*contents) return PDC_CLIP_MEMORY_ERROR; return PDC_CLIP_SUCCESS; } int PDC_setclipboard(const char *contents, long length) { char *macroman; long maclen; #if TARGET_API_MAC_CARBON OSStatus err; #else OSErr err; #endif PDC_LOG(("PDC_setclipboard() - called\n")); if (!contents) return PDC_clearclipboard(); macroman = result_to_macroman(contents, length, &maclen); if (!macroman) return PDC_CLIP_MEMORY_ERROR; #if TARGET_API_MAC_CARBON { ScrapRef scrap; err = ClearCurrentScrap(); if (err == noErr) err = GetCurrentScrap(&scrap); if (err == noErr) err = PutScrapFlavor(scrap, kScrapFlavorTypeText, 0, maclen, macroman); } #else err = ZeroScrap(); if (err == noErr) err = PutScrap(maclen, kScrapFlavorTypeText, macroman); #endif free(macroman); if (err != noErr) return PDC_CLIP_ACCESS_ERROR; return PDC_CLIP_SUCCESS; } int PDC_freeclipboard(char *contents) { PDC_LOG(("PDC_freeclipboard() - called\n")); if (contents) free(contents); return PDC_CLIP_SUCCESS; } int PDC_clearclipboard(void) { #if TARGET_API_MAC_CARBON OSStatus err; #else OSErr err; #endif PDC_LOG(("PDC_clearclipboard() - called\n")); #if TARGET_API_MAC_CARBON err = ClearCurrentScrap(); #else err = ZeroScrap(); #endif if (err != noErr) return PDC_CLIP_ACCESS_ERROR; return PDC_CLIP_SUCCESS; } \ No newline at end of file diff --git a/mac/pdcdisp.c b/mac/pdcdisp.c new file mode 100644 index 00000000..8b0eb417 --- /dev/null +++ b/mac/pdcdisp.c @@ -0,0 +1 @@ +#include "pdcmac.h" #include #ifdef PDC_WIDE #define USE_UNICODE_ACS_CHARS 1 #else #define USE_UNICODE_ACS_CHARS 0 #endif #include #include #include #ifndef PACK_RGB #define PACK_RGB(red, green, blue) ((PACKED_RGB)(red) | ((PACKED_RGB)(green) << 8) | ((PACKED_RGB)(blue) << 16)) #endif static void packed_to_rgb(PACKED_RGB packed, RGBColor *color) { unsigned int red; unsigned int green; unsigned int blue; red = Get_RValue(packed); green = Get_GValue(packed); blue = Get_BValue(packed); color->red = (unsigned short)((red << 8) | red); color->green = (unsigned short)((green << 8) | green); color->blue = (unsigned short)((blue << 8) | blue); } static void fill_rect(Rect *cell, const RGBColor *color) { RGBForeColor(color); PaintRect(cell); } static int is_hline(unsigned long ch) { if (ch == 0x2500 || ch == 0x2501 || ch == 0x2550) return 1; if (ch == 0xC4 || ch == 0xCD) return 1; return 0; } static int is_vline(unsigned long ch) { if (ch == 0x2502 || ch == 0x2503 || ch == 0x2551) return 1; if (ch == 0xB3 || ch == 0xBA) return 1; return 0; } static int box_mask(unsigned long ch) { int mask; mask = 0; if (ch == 0x250C || ch == 0x250F || ch == 0x2554 || ch == 0xDA || ch == 0xC9) mask = 2 | 8; else if (ch == 0x2510 || ch == 0x2513 || ch == 0x2557 || ch == 0xBF || ch == 0xBB) mask = 2 | 4; else if (ch == 0x2514 || ch == 0x2517 || ch == 0x255A || ch == 0xC0 || ch == 0xC8) mask = 1 | 8; else if (ch == 0x2518 || ch == 0x251B || ch == 0x255D || ch == 0xD9 || ch == 0xBC) mask = 1 | 4; else if (ch == 0x251C || ch == 0x2523 || ch == 0x2560 || ch == 0xC3 || ch == 0xCC) mask = 1 | 2 | 8; else if (ch == 0x2524 || ch == 0x252B || ch == 0x2563 || ch == 0xB4 || ch == 0xB9) mask = 1 | 2 | 4; else if (ch == 0x252C || ch == 0x2533 || ch == 0x2566 || ch == 0xC2 || ch == 0xCB) mask = 2 | 4 | 8; else if (ch == 0x2534 || ch == 0x253B || ch == 0x2569 || ch == 0xC1 || ch == 0xCA) mask = 1 | 4 | 8; else if (ch == 0x253C || ch == 0x254B || ch == 0x256C || ch == 0xC5 || ch == 0xCE) mask = 1 | 2 | 4 | 8; return mask; } static int draw_graphic(unsigned long ch, Rect *cell, const RGBColor *fg) { int midx; int midy; int mask; midx = (cell->left + cell->right) / 2; midy = (cell->top + cell->bottom) / 2; RGBForeColor(fg); PenNormal(); PenSize(1, 1); if (ch == 0x2588 || ch == 0xDB) { PaintRect(cell); return 1; } if (ch == 0x2580 || ch == 0xDF) { Rect half; half = *cell; half.bottom = midy; PaintRect(&half); return 1; } if (ch == 0x2584 || ch == 0xDC) { Rect half; half = *cell; half.top = midy; PaintRect(&half); return 1; } if (ch == 0x258C || ch == 0xDD) { Rect half; half = *cell; half.right = midx; PaintRect(&half); return 1; } if (ch == 0x2590 || ch == 0xDE) { Rect half; half = *cell; half.left = midx; PaintRect(&half); return 1; } if (ch == 0x2591 || ch == 0xB0 || ch == 0x2592 || ch == 0xB1 || ch == 0x2593 || ch == 0xB2) { #if TARGET_API_MAC_CARBON Pattern pat; if (ch == 0x2591 || ch == 0xB0) GetQDGlobalsLightGray(&pat); else if (ch == 0x2593 || ch == 0xB2) GetQDGlobalsDarkGray(&pat); else GetQDGlobalsGray(&pat); PenPat(&pat); #else if (ch == 0x2591 || ch == 0xB0) PenPat(&qd.ltGray); else if (ch == 0x2593 || ch == 0xB2) PenPat(&qd.dkGray); else PenPat(&qd.gray); #endif PaintRect(cell); PenNormal(); return 1; } if (is_hline(ch)) { MoveTo(cell->left, midy); LineTo(cell->right - 1, midy); return 1; } if (is_vline(ch)) { MoveTo(midx, cell->top); LineTo(midx, cell->bottom - 1); return 1; } mask = box_mask(ch); if (mask) { if (mask & 1) { MoveTo(midx, cell->top); LineTo(midx, midy); } if (mask & 2) { MoveTo(midx, midy); LineTo(midx, cell->bottom - 1); } if (mask & 4) { MoveTo(cell->left, midy); LineTo(midx, midy); } if (mask & 8) { MoveTo(midx, midy); LineTo(cell->right - 1, midy); } return 1; } if (ch == 0x25C6 || ch == 0x2666 || ch == 0x04) { MoveTo(midx, cell->top + 1); LineTo(cell->right - 2, midy); LineTo(midx, cell->bottom - 2); LineTo(cell->left + 1, midy); LineTo(midx, cell->top + 1); return 1; } return 0; } static void draw_cursor_shape(Rect *cell, const RGBColor *fg) { int style; Rect bar; style = SP->drawing_cursor; RGBForeColor(fg); bar = *cell; if (style == 2) { InvertRect(&bar); return; } if (style == 1) { bar.top = bar.bottom - PDC_font_height / 5; if (bar.top < cell->top) bar.top = cell->top; PaintRect(&bar); } else if (style == 5) { bar.top = (cell->top + cell->bottom) / 2; PaintRect(&bar); } else if (style == 3) { FrameRect(&bar); } else if (style == 4) { MoveTo(cell->left + 1, cell->top); LineTo(cell->left + 1, cell->bottom - 1); } } static unsigned char char_to_mac(unsigned long ch) { if (ch < 0x100) return (unsigned char)ch; return PDC_unicode_to_macroman(ch); } void PDC_transform_line(int lineno, int x, int len, const chtype *srcp) { int i; Rect clipbounds; PDC_LOG(("PDC_transform_line() - called: lineno=%d\n", lineno)); if (!srcp || len <= 0 || !PDC_window) return; PDC_mac_set_port(); PDC_mac_port_bounds(&clipbounds); TextFont(monaco); TextSize(PDC_font_size); for (i = 0; i < len; i++) { chtype cell; unsigned long ch; PACKED_RGB fgpacked; PACKED_RGB bgpacked; RGBColor fg; RGBColor bg; Rect r; Style face; attr_t sysattrs; cell = srcp[i]; sysattrs = SP->termattrs; if (_is_altcharset(cell)) ch = (unsigned long)acs_map[cell & 0x7f]; else ch = (unsigned long)(cell & A_CHARTEXT); if ((cell & A_BLINK) && SP->blink_state && (sysattrs & A_BLINK)) ch = (unsigned long)' '; PDC_get_rgb_values(cell, &fgpacked, &bgpacked); if (fgpacked == (PACKED_RGB)-1) fgpacked = PACK_RGB(0xC0, 0xC0, 0xC0); if (bgpacked == (PACKED_RGB)-1) bgpacked = PACK_RGB(0, 0, 0); packed_to_rgb(fgpacked, &fg); packed_to_rgb(bgpacked, &bg); PDC_mac_cell_rect(lineno, x + i, &r); ClipRect(&r); fill_rect(&r, &bg); RGBForeColor(&fg); RGBBackColor(&bg); face = 0; if ((cell & A_BOLD) && (sysattrs & A_BOLD)) face |= bold; if ((cell & A_ITALIC) && (sysattrs & A_ITALIC)) face |= italic; TextFace(face); if (!draw_graphic(ch, &r, &fg)) { unsigned char drawn; drawn = char_to_mac(ch); if (drawn < 32) drawn = (unsigned char)' '; MoveTo(r.left, r.top + PDC_font_ascent); DrawChar(drawn); } if (cell & (A_UNDERLINE | A_TOP | A_LEFT | A_RIGHT | A_STRIKEOUT)) { RGBColor linec; int lineidx; lineidx = SP->line_color; if (lineidx != -1) packed_to_rgb(PDC_get_palette_entry(lineidx), &linec); else linec = fg; RGBForeColor(&linec); PenNormal(); if (cell & A_UNDERLINE) { MoveTo(r.left, r.bottom - 1); LineTo(r.right - 1, r.bottom - 1); } if (cell & A_TOP) { MoveTo(r.left, r.top); LineTo(r.right - 1, r.top); } if (cell & A_STRIKEOUT) { int midy; midy = (r.top + r.bottom) / 2; MoveTo(r.left, midy); LineTo(r.right - 1, midy); } if (cell & A_LEFT) { MoveTo(r.left, r.top); LineTo(r.left, r.bottom - 1); } if (cell & A_RIGHT) { MoveTo(r.right - 1, r.top); LineTo(r.right - 1, r.bottom - 1); } } if (SP->drawing_cursor) draw_cursor_shape(&r, &fg); ClipRect(&clipbounds); } TextFace(0); #ifdef MAC_OS_X_VERSION_10_0 { CGrafPtr port; port = GetWindowPort(PDC_window); if (port) QDFlushPortBuffer(port, NULL); } #endif } void PDC_doupdate(void) { #ifdef MAC_OS_X_VERSION_10_0 if (PDC_window) { CGrafPtr port; port = GetWindowPort(PDC_window); if (port) QDFlushPortBuffer(port, NULL); } #endif } \ No newline at end of file diff --git a/mac/pdcgetsc.c b/mac/pdcgetsc.c new file mode 100644 index 00000000..0927e7e2 --- /dev/null +++ b/mac/pdcgetsc.c @@ -0,0 +1 @@ +#include "pdcmac.h" int PDC_get_cursor_mode(void) { PDC_LOG(("PDC_get_cursor_mode() - called\n")); return 0; } int PDC_get_rows(void) { PDC_LOG(("PDC_get_rows() - called\n")); return PDC_rows; } int PDC_get_columns(void) { PDC_LOG(("PDC_get_columns() - called\n")); return PDC_cols; } \ No newline at end of file diff --git a/mac/pdckbd.c b/mac/pdckbd.c new file mode 100644 index 00000000..df79e23f --- /dev/null +++ b/mac/pdckbd.c @@ -0,0 +1 @@ +#include "pdcmac.h" #include #include #include #include int PDC_key_queue[PDC_KEY_QUEUE_SIZE]; int PDC_key_queue_head = 0; int PDC_key_queue_tail = 0; static int last_mouse_button = 0; static Point last_mouse_local; static int prev_special_key = -1; static const struct { unsigned char keycode; unsigned char numkeypad; unsigned short normal; unsigned short shifted; unsigned short control; unsigned short alt; } key_table[] = { { 0x7B, 0, KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT }, { 0x7C, 0, KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT }, { 0x7E, 0, KEY_UP, KEY_SUP, CTL_UP, ALT_UP }, { 0x7D, 0, KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN }, { 0x73, 0, KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME }, { 0x77, 0, KEY_END, KEY_SEND, CTL_END, ALT_END }, { 0x74, 0, KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP }, { 0x79, 0, KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN }, { 0x72, 0, KEY_IC, KEY_SIC, CTL_INS, ALT_INS }, { 0x75, 0, KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL }, { 0x33, 0, 0x08, 0x08, CTL_BKSP, ALT_BKSP }, { 0x30, 0, 0x09, KEY_BTAB, CTL_TAB, ALT_TAB }, { 0x35, 0, 0x1B, 0x1B, 0x1B, ALT_ESC }, { 0x24, 0, 0x0D, 0x0D, 0x0D, 0x0D }, { 0x4C, 1, PADENTER, PADENTER, CTL_PADENTER, ALT_PADENTER }, { 0x45, 1, PADPLUS, '+', CTL_PADPLUS, ALT_PADPLUS }, { 0x4E, 1, PADMINUS, '-', CTL_PADMINUS, ALT_PADMINUS }, { 0x43, 1, PADSTAR, '*', CTL_PADSTAR, ALT_PADSTAR }, { 0x4B, 1, PADSLASH, '/', CTL_PADSLASH, ALT_PADSLASH }, { 0x41, 1, PADSTOP, '.', CTL_PADSTOP, ALT_PADSTOP }, { 0x52, 1, PAD0, '0', CTL_PAD0, ALT_PAD0 }, { 0x53, 1, KEY_C1, '1', CTL_PAD1, ALT_PAD1 }, { 0x54, 1, KEY_C2, '2', CTL_PAD2, ALT_PAD2 }, { 0x55, 1, KEY_C3, '3', CTL_PAD3, ALT_PAD3 }, { 0x56, 1, KEY_B1, '4', CTL_PAD4, ALT_PAD4 }, { 0x57, 1, KEY_B2, '5', CTL_PAD5, ALT_PAD5 }, { 0x58, 1, KEY_B3, '6', CTL_PAD6, ALT_PAD6 }, { 0x59, 1, KEY_A1, '7', CTL_PAD7, ALT_PAD7 }, { 0x5B, 1, KEY_A2, '8', CTL_PAD8, ALT_PAD8 }, { 0x5C, 1, KEY_A3, '9', CTL_PAD9, ALT_PAD9 }, { 0x47, 1, KEY_CLEAR, KEY_CLEAR, KEY_CLEAR, KEY_CLEAR }, { 0x7A, 0, KEY_F(1), KEY_F(13), KEY_F(25), KEY_F(37) }, { 0x78, 0, KEY_F(2), KEY_F(14), KEY_F(26), KEY_F(38) }, { 0x63, 0, KEY_F(3), KEY_F(15), KEY_F(27), KEY_F(39) }, { 0x76, 0, KEY_F(4), KEY_F(16), KEY_F(28), KEY_F(40) }, { 0x60, 0, KEY_F(5), KEY_F(17), KEY_F(29), KEY_F(41) }, { 0x61, 0, KEY_F(6), KEY_F(18), KEY_F(30), KEY_F(42) }, { 0x62, 0, KEY_F(7), KEY_F(19), KEY_F(31), KEY_F(43) }, { 0x64, 0, KEY_F(8), KEY_F(20), KEY_F(32), KEY_F(44) }, { 0x65, 0, KEY_F(9), KEY_F(21), KEY_F(33), KEY_F(45) }, { 0x6D, 0, KEY_F(10), KEY_F(22), KEY_F(34), KEY_F(46) }, { 0x67, 0, KEY_F(11), KEY_F(23), KEY_F(35), KEY_F(47) }, { 0x6F, 0, KEY_F(12), KEY_F(24), KEY_F(36), KEY_F(48) }, { 0x69, 0, KEY_F(13), KEY_F(25), KEY_F(37), KEY_F(49) }, { 0x6B, 0, KEY_F(14), KEY_F(26), KEY_F(38), KEY_F(50) }, { 0x71, 0, KEY_F(15), KEY_F(27), KEY_F(39), KEY_F(51) }, { 0, 0, 0, 0, 0, 0 } }; void PDC_mac_add_key(int key) { int next; if (!key) return; next = PDC_key_queue_tail + 1; if (next >= PDC_KEY_QUEUE_SIZE) next = 0; if (next == PDC_key_queue_head) return; if (key == KEY_RESIZE) { int i; i = PDC_key_queue_head; while (i != PDC_key_queue_tail) { if (PDC_key_queue[i] == KEY_RESIZE) return; i++; if (i >= PDC_KEY_QUEUE_SIZE) i = 0; } if (SP) SP->resized = TRUE; } PDC_key_queue[PDC_key_queue_tail] = key; PDC_key_queue_tail = next; } static int queue_has_key(void) { if (PDC_key_queue_head != PDC_key_queue_tail) return 1; return 0; } static int pop_key(void) { int key; if (PDC_key_queue_head == PDC_key_queue_tail) return -1; key = PDC_key_queue[PDC_key_queue_head]; PDC_key_queue_head++; if (PDC_key_queue_head >= PDC_KEY_QUEUE_SIZE) PDC_key_queue_head = 0; if (key == KEY_MOUSE) _get_mouse_event(&SP->mouse_status); return key; } static unsigned long modifiers_from_event(const EventRecord *event) { unsigned long mods; mods = 0; if (event->modifiers & shiftKey) mods |= PDC_KEY_MODIFIER_SHIFT; if (event->modifiers & controlKey) mods |= PDC_KEY_MODIFIER_CONTROL; if (event->modifiers & optionKey) mods |= PDC_KEY_MODIFIER_ALT; if (event->modifiers & cmdKey) mods |= PDC_KEY_MODIFIER_SUPER; if (event->modifiers & alphaLock) mods |= PDC_KEY_MODIFIER_CAPSLOCK; return mods; } static int mouse_modifs(const EventRecord *event) { int mods; mods = 0; if (event->modifiers & shiftKey) mods |= BUTTON_SHIFT; if (event->modifiers & controlKey) mods |= BUTTON_CONTROL; if (event->modifiers & optionKey) mods |= BUTTON_ALT; return mods; } static int mouse_button_from_event(const EventRecord *event) { if (event->modifiers & controlKey) return 2; if (event->modifiers & optionKey) return 1; return 0; } static void local_mouse(const EventRecord *event, Point *local) { *local = event->where; PDC_mac_set_port(); GlobalToLocal(local); } static void queue_mouse(int button, int event_type, const EventRecord *event) { Point local; int x; int y; local_mouse(event, &local); last_mouse_local = local; x = local.h / PDC_font_width; y = local.v / PDC_font_height; if (x < 0) x = 0; if (y < 0) y = 0; if (SP && x >= SP->cols) x = SP->cols - 1; if (SP && y >= SP->lines) y = SP->lines - 1; _add_raw_mouse_event(button, event_type, mouse_modifs(event), x, y); if (_get_mouse_event(NULL)) PDC_mac_add_key(KEY_MOUSE); } static int lookup_special(unsigned char keycode, unsigned long modifiers) { int i; for (i = 0; key_table[i].normal; i++) { if (key_table[i].keycode != keycode) continue; if (modifiers & PDC_KEY_MODIFIER_SHIFT) return key_table[i].shifted; if (modifiers & PDC_KEY_MODIFIER_CONTROL) return key_table[i].control; if (modifiers & PDC_KEY_MODIFIER_ALT) return key_table[i].alt; return key_table[i].normal; } return 0; } static int translate_key(const EventRecord *event) { unsigned char keycode; unsigned char charcode; unsigned long modifiers; int key; keycode = (unsigned char)((event->message & keyCodeMask) >> 8); charcode = (unsigned char)(event->message & charCodeMask); modifiers = modifiers_from_event(event); SP->key_modifiers = modifiers; if (event->what == autoKey) SP->key_modifiers |= PDC_KEY_MODIFIER_REPEAT; if ((event->modifiers & cmdKey) && charcode == 'q') { key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); if (!key) exit(0); return key; } if ((event->modifiers & cmdKey) && charcode == 'c') { key = PDC_get_function_key(FUNCTION_KEY_COPY); if (key) return key; return 3; } if ((event->modifiers & cmdKey) && charcode == 'v') { key = PDC_get_function_key(FUNCTION_KEY_PASTE); if (key) return key; return 22; } if ((event->modifiers & cmdKey) && (charcode == '+' || charcode == '=')) { key = PDC_get_function_key(FUNCTION_KEY_ENLARGE_FONT); if (key) return key; PDC_font_size += 2; if (PDC_font_size > 48) PDC_font_size = 48; PDC_mac_apply_font(); PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 1); return -1; } if ((event->modifiers & cmdKey) && charcode == '-') { key = PDC_get_function_key(FUNCTION_KEY_SHRINK_FONT); if (key) return key; PDC_font_size -= 2; if (PDC_font_size < 6) PDC_font_size = 6; PDC_mac_apply_font(); PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 1); return -1; } key = lookup_special(keycode, modifiers); if (key) return key; if (event->modifiers & cmdKey) return -1; if (charcode >= 32) { #ifdef PDC_WIDE return (int)PDC_macroman_to_unicode(charcode); #else return (int)charcode; #endif } if (charcode > 0) return (int)charcode; return -1; } static void handle_key(EventRecord *event) { int key; if (event->modifiers & cmdKey) { long menuresult; menuresult = MenuKey((short)(event->message & charCodeMask)); if (HiWord(menuresult)) { PDC_mac_handle_menu(menuresult); return; } } if (event->what == keyUp) { unsigned char keycode; keycode = (unsigned char)((event->message & keyCodeMask) >> 8); if (SP && SP->return_key_modifiers) { if (keycode == 0x38 || keycode == 0x3C) PDC_mac_add_key(KEY_SHIFT_L); else if (keycode == 0x3B || keycode == 0x3E) PDC_mac_add_key(KEY_CONTROL_L); else if (keycode == 0x3A || keycode == 0x3D) PDC_mac_add_key(KEY_ALT_L); } prev_special_key = -1; return; } key = translate_key(event); if (key == 3 && SP && !SP->raw_inp) exit(0); if (key > 0) { if (prev_special_key == key) SP->key_modifiers |= PDC_KEY_MODIFIER_REPEAT; prev_special_key = key; PDC_mac_add_key(key); } } static void handle_content_click(EventRecord *event, int pressed) { int button; if (pressed) { button = mouse_button_from_event(event); last_mouse_button = button; queue_mouse(button, BUTTON_PRESSED, event); } else { button = last_mouse_button; queue_mouse(button, BUTTON_RELEASED, event); } } static void handle_mouse_moved(EventRecord *event) { Point local; int x; int y; if (!SP || !SP->_trap_mbe) { PDC_mac_reset_mouse_rgn(); return; } local_mouse(event, &local); if (local.h == last_mouse_local.h && local.v == last_mouse_local.v) { PDC_mac_reset_mouse_rgn(); return; } last_mouse_local = local; x = local.h / PDC_font_width; y = local.v / PDC_font_height; _add_raw_mouse_event(last_mouse_button, BUTTON_MOVED, mouse_modifs(event), x, y); PDC_mac_add_key(KEY_MOUSE); PDC_mac_reset_mouse_rgn(); } static void dispatch_event(EventRecord *event) { WindowPtr which; short part; switch (event->what) { case mouseDown: part = FindWindow(event->where, &which); if (part == inMenuBar) { PDC_mac_handle_menu(MenuSelect(event->where)); break; } #if !TARGET_API_MAC_CARBON if (part == inSysWindow) { SystemClick(event, which); break; } #endif if (which != PDC_window) { if (which) SelectWindow(which); break; } if (part == inDrag) PDC_mac_drag(event); else if (part == inGrow) PDC_mac_grow(event); else if (part == inGoAway) PDC_mac_goaway(event); else if (part == inZoomIn || part == inZoomOut) PDC_mac_zoom(event, part); else if (part == inContent) { SelectWindow(PDC_window); handle_content_click(event, 1); } break; case mouseUp: handle_content_click(event, 0); break; case keyDown: case autoKey: case keyUp: handle_key(event); break; case updateEvt: if ((WindowPtr)event->message == PDC_window) PDC_mac_redraw(); break; case activateEvt: if ((WindowPtr)event->message == PDC_window) { PDC_mac_set_port(); DrawGrowIcon(PDC_window); } break; case osEvt: { unsigned char kind; kind = (unsigned char)((event->message >> 24) & 0xFF); if (kind == mouseMovedMessage) handle_mouse_moved(event); else if (kind == suspendResumeMessage) { #if !TARGET_API_MAC_CARBON if (event->message & resumeFlag) LoadScrap(); else UnloadScrap(); #endif } } break; case kHighLevelEvent: AEProcessAppleEvent(event); break; default: break; } } void PDC_mac_process_events(int sleepticks) { EventRecord event; Boolean got; RgnHandle rgn; rgn = PDC_mouse_rgn; got = WaitNextEvent(everyEvent, &event, sleepticks, rgn); if (got) dispatch_event(&event); while (EventAvail(everyEvent, &event)) { got = WaitNextEvent(everyEvent, &event, 0, rgn); if (!got) break; dispatch_event(&event); } } void PDC_set_keyboard_binary(bool on) { INTENTIONALLY_UNUSED_PARAMETER(on); PDC_LOG(("PDC_set_keyboard_binary() - called\n")); } bool PDC_check_key(void) { PDC_check_for_blinking(); PDC_mac_process_events(0); if (queue_has_key()) return TRUE; return FALSE; } int PDC_get_key(void) { int key; if (!queue_has_key()) PDC_mac_process_events(GetCaretTime()); key = pop_key(); return key; } void PDC_flushinp(void) { PDC_LOG(("PDC_flushinp() - called\n")); PDC_key_queue_head = 0; PDC_key_queue_tail = 0; while (_get_mouse_event(&SP->mouse_status)) ; FlushEvents(keyDownMask | keyUpMask | autoKeyMask | mDownMask | mUpMask, 0); } bool PDC_has_mouse(void) { return TRUE; } int PDC_mouse_set(void) { PDC_mac_reset_mouse_rgn(); return OK; } int PDC_modifiers_set(void) { return OK; } \ No newline at end of file diff --git a/mac/pdcmac.h b/mac/pdcmac.h new file mode 100644 index 00000000..7553ead7 --- /dev/null +++ b/mac/pdcmac.h @@ -0,0 +1 @@ +#ifndef PDC_MAC_H #define PDC_MAC_H 1 #ifndef TARGET_API_MAC_CARBON # ifdef TARGET_CARBON # define TARGET_API_MAC_CARBON TARGET_CARBON # else # define TARGET_API_MAC_CARBON 0 # endif #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #undef MOUSE_MOVED #include #ifndef kScrapFlavorTypeText #define kScrapFlavorTypeText 'TEXT' #endif #ifndef zoomDocProc #define zoomDocProc 8 #endif #ifndef monaco #define monaco 4 #endif #ifndef bold #define bold 1 #endif #ifndef italic #define italic 2 #endif #ifndef everyEvent #define everyEvent 0xFFFF #endif #ifndef mouseMovedMessage #define mouseMovedMessage 0xFA #endif #ifndef suspendResumeMessage #define suspendResumeMessage 1 #endif #ifndef resumeFlag #define resumeFlag 1 #endif #ifndef kHighLevelEvent #define kHighLevelEvent 23 #endif #ifndef gestaltAppleEventsPresent #define gestaltAppleEventsPresent 0 #endif #ifndef noTypeErr #define noTypeErr -204 #endif #ifndef memFullErr #define memFullErr -108 #endif #ifndef charCodeMask #define charCodeMask 0x000000FF #endif #ifndef keyCodeMask #define keyCodeMask 0x0000FF00 #endif #ifndef activeFlag #define activeFlag 0x0001 #endif #define PDC_KEY_QUEUE_SIZE 64 extern WindowPtr PDC_window; extern int PDC_rows; extern int PDC_cols; extern int PDC_font_width; extern int PDC_font_height; extern int PDC_font_ascent; extern int PDC_font_size; extern int PDC_key_queue[PDC_KEY_QUEUE_SIZE]; extern int PDC_key_queue_head; extern int PDC_key_queue_tail; extern RgnHandle PDC_mouse_rgn; extern int PDC_min_lines; extern int PDC_max_lines; extern int PDC_min_cols; extern int PDC_max_cols; #define PDC_MENU_APPLE 128 #define PDC_MENU_FILE 129 #define PDC_MENU_EDIT 130 #define PDC_ITEM_QUIT 1 #define PDC_ITEM_CUT 1 #define PDC_ITEM_COPY 2 #define PDC_ITEM_PASTE 3 #define PDC_ITEM_CLEAR 4 void PDC_mac_set_port(void); void PDC_mac_port_bounds(Rect *bounds); void PDC_mac_invalidate(const Rect *bounds); void PDC_mac_invalidate_all(void); void PDC_mac_cell_rect(int row, int col, Rect *cell); void PDC_mac_add_key(int key); void PDC_mac_process_events(int sleepticks); void PDC_mac_apply_font(void); void PDC_mac_reset_mouse_rgn(void); void PDC_mac_drag(EventRecord *event); void PDC_mac_grow(EventRecord *event); void PDC_mac_zoom(EventRecord *event, short part); void PDC_mac_goaway(EventRecord *event); void PDC_mac_redraw(void); void PDC_mac_handle_menu(long menuresult); void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize); unsigned short PDC_macroman_to_unicode(unsigned char ch); unsigned char PDC_unicode_to_macroman(unsigned long code); void PDC_check_for_blinking(void); #endif \ No newline at end of file diff --git a/mac/pdcscrn.c b/mac/pdcscrn.c new file mode 100644 index 00000000..b867c071 --- /dev/null +++ b/mac/pdcscrn.c @@ -0,0 +1 @@ +#include "pdcmac.h" #include #include #include #include #if UNIVERSAL_INTERFACES_VERSION >= 0x0340 #define AEEVENTCBPARAM3 long #else #define AEEVENTCBPARAM3 UInt32 #endif WindowPtr PDC_window = NULL; int PDC_rows = 25; int PDC_cols = 80; int PDC_font_width = 6; int PDC_font_height = 12; int PDC_font_ascent = 9; int PDC_font_size = 12; RgnHandle PDC_mouse_rgn = NULL; int PDC_min_lines = 2; int PDC_max_lines = 200; int PDC_min_cols = 2; int PDC_max_cols = 300; static int toolbox_ready = 0; static int initial_rows = 0; static int initial_cols = 0; static MenuHandle apple_menu; static MenuHandle file_menu; static MenuHandle edit_menu; static void c_to_pstr(const char *src, Str255 dst) { unsigned int length; unsigned int i; length = 0; while (src[length] != 0 && length < 255) length++; dst[0] = (unsigned char)length; for (i = 0; i < length; i++) dst[i + 1] = (unsigned char)src[i]; } void PDC_mac_set_port(void) { if (!PDC_window) return; #if TARGET_API_MAC_CARBON SetPortWindowPort(PDC_window); #else SetPort((GrafPtr)PDC_window); #endif } void PDC_mac_port_bounds(Rect *bounds) { #if TARGET_API_MAC_CARBON || ACCESSOR_CALLS_ARE_FUNCTIONS GetWindowPortBounds(PDC_window, bounds); #else *bounds = PDC_window->portRect; #endif } void PDC_mac_invalidate(const Rect *bounds) { PDC_mac_set_port(); #if TARGET_API_MAC_CARBON InvalWindowRect(PDC_window, (Rect *)bounds); #else InvalRect((Rect *)bounds); #endif } void PDC_mac_invalidate_all(void) { Rect bounds; PDC_mac_port_bounds(&bounds); PDC_mac_invalidate(&bounds); } void PDC_mac_cell_rect(int row, int col, Rect *cell) { cell->left = (short)(col * PDC_font_width); cell->top = (short)(row * PDC_font_height); cell->right = (short)(cell->left + PDC_font_width); cell->bottom = (short)(cell->top + PDC_font_height); } void PDC_mac_reset_mouse_rgn(void) { Point pt; Rect r; if (!PDC_mouse_rgn) return; #if TARGET_API_MAC_CARBON GetGlobalMouse(&pt); #else GetMouse(&pt); PDC_mac_set_port(); LocalToGlobal(&pt); #endif SetRect(&r, pt.h, pt.v, pt.h + 1, pt.v + 1); RectRgn(PDC_mouse_rgn, &r); } void PDC_mac_apply_font(void) { FontInfo info; PDC_mac_set_port(); TextFont(monaco); TextFace(0); TextSize(PDC_font_size); GetFontInfo(&info); PDC_font_ascent = info.ascent; PDC_font_height = info.ascent + info.descent + info.leading; PDC_font_width = CharWidth('M'); if (PDC_font_width < 1) PDC_font_width = CharWidth('W'); if (PDC_font_width < 1) PDC_font_width = PDC_font_size / 2 + 1; if (PDC_font_height < 1) PDC_font_height = PDC_font_size + 2; } static void screen_work_rect(Rect *bounds) { #if TARGET_API_MAC_CARBON BitMap screenbits; GetQDGlobalsScreenBits(&screenbits); *bounds = screenbits.bounds; #else *bounds = qd.screenBits.bounds; #endif bounds->top = (short)(bounds->top + GetMBarHeight()); } void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize) { int rows; int cols; Rect limits; cols = pixelwidth / PDC_font_width; rows = pixelheight / PDC_font_height; if (cols < PDC_min_cols) cols = PDC_min_cols; if (rows < PDC_min_lines) rows = PDC_min_lines; if (cols > PDC_max_cols) cols = PDC_max_cols; if (rows > PDC_max_lines) rows = PDC_max_lines; if (cols < 2) cols = 2; if (rows < 2) rows = 2; SizeWindow(PDC_window, (short)(cols * PDC_font_width), (short)(rows * PDC_font_height), TRUE); if (PDC_cols != cols || PDC_rows != rows) { PDC_cols = cols; PDC_rows = rows; if (queue_resize) PDC_mac_add_key(KEY_RESIZE); } PDC_mac_port_bounds(&limits); PDC_mac_invalidate(&limits); PDC_mac_set_port(); DrawGrowIcon(PDC_window); } void PDC_mac_drag(EventRecord *event) { Rect screen; screen_work_rect(&screen); DragWindow(PDC_window, event->where, &screen); } void PDC_mac_grow(EventRecord *event) { Rect limits; long grow; SetRect(&limits, (short)(PDC_min_cols * PDC_font_width), (short)(PDC_min_lines * PDC_font_height), (short)(PDC_max_cols * PDC_font_width), (short)(PDC_max_lines * PDC_font_height)); grow = GrowWindow(PDC_window, event->where, &limits); if (grow) PDC_mac_adjust_size(LoWord(grow), HiWord(grow), 1); } void PDC_mac_zoom(EventRecord *event, short part) { Rect bounds; if (!TrackBox(PDC_window, event->where, part)) return; ZoomWindow(PDC_window, part, TRUE); PDC_mac_port_bounds(&bounds); PDC_mac_adjust_size(bounds.right - bounds.left, bounds.bottom - bounds.top, 1); } void PDC_mac_goaway(EventRecord *event) { int key; if (!TrackGoAway(PDC_window, event->where)) return; key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); if (!key) exit(0); PDC_mac_add_key(key); } void PDC_mac_redraw(void) { Rect bounds; int y; BeginUpdate(PDC_window); PDC_mac_set_port(); PDC_mac_port_bounds(&bounds); EraseRect(&bounds); if (curscr && SP) { int cols; cols = SP->cols; if (cols > PDC_cols) cols = PDC_cols; for (y = 0; y < SP->lines && y < PDC_rows; y++) { if (curscr->_y[y]) PDC_transform_line(y, 0, cols, curscr->_y[y]); } } DrawGrowIcon(PDC_window); EndUpdate(PDC_window); } void PDC_mac_handle_menu(long menuresult) { short menuid; short item; int key; menuid = HiWord(menuresult); item = LoWord(menuresult); if (menuid == PDC_MENU_FILE && item == PDC_ITEM_QUIT) { key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); if (!key) exit(0); PDC_mac_add_key(key); } else if (menuid == PDC_MENU_EDIT) { if (item == PDC_ITEM_COPY) { key = PDC_get_function_key(FUNCTION_KEY_COPY); if (!key) key = 3; PDC_mac_add_key(key); } else if (item == PDC_ITEM_PASTE) { key = PDC_get_function_key(FUNCTION_KEY_PASTE); if (!key) key = 22; PDC_mac_add_key(key); } else if (item == PDC_ITEM_CLEAR) PDC_clearclipboard(); } #if !TARGET_API_MAC_CARBON else if (menuid == PDC_MENU_APPLE && item > 1) { Str255 name; GetMenuItemText(apple_menu, item, name); OpenDeskAcc(name); } #endif HiliteMenu(0); } static pascal OSErr ae_quit(const AppleEvent *evt, AppleEvent *reply, AEEVENTCBPARAM3 refcon) { int key; INTENTIONALLY_UNUSED_PARAMETER(evt); INTENTIONALLY_UNUSED_PARAMETER(reply); INTENTIONALLY_UNUSED_PARAMETER(refcon); key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); if (!key) exit(0); PDC_mac_add_key(key); return noErr; } static void init_toolbox(void) { if (toolbox_ready) return; #if TARGET_API_MAC_CARBON InitCursor(); #else MaxApplZone(); MoreMasters(); MoreMasters(); InitGraf(&qd.thePort); InitFonts(); FlushEvents(everyEvent, 0); InitWindows(); InitMenus(); TEInit(); InitDialogs(NULL); InitCursor(); #endif toolbox_ready = 1; } static void init_menus(void) { Str255 title; title[0] = 1; title[1] = 0x14; apple_menu = NewMenu(PDC_MENU_APPLE, title); c_to_pstr("About PDCursesMod", title); AppendMenu(apple_menu, title); #if !TARGET_API_MAC_CARBON c_to_pstr("(-", title); AppendMenu(apple_menu, title); AppendResMenu(apple_menu, 'DRVR'); #endif c_to_pstr("File", title); file_menu = NewMenu(PDC_MENU_FILE, title); c_to_pstr("Quit/Q", title); AppendMenu(file_menu, title); c_to_pstr("Edit", title); edit_menu = NewMenu(PDC_MENU_EDIT, title); c_to_pstr("Cut/X;Copy/C;Paste/V;Clear", title); AppendMenu(edit_menu, title); InsertMenu(apple_menu, 0); InsertMenu(file_menu, 0); InsertMenu(edit_menu, 0); DrawMenuBar(); } static void install_apple_events(void) { #if TARGET_API_MAC_CARBON AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(ae_quit), 0, FALSE); #else { long attr; if (Gestalt(gestaltAppleEventsAttr, &attr) == noErr) { if (attr & (1L << gestaltAppleEventsPresent)) AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(ae_quit), 0, FALSE); } } #endif } static WindowPtr create_window(void) { Rect screen; Rect bounds; Str255 title; int width; int height; int left; int top; WindowPtr window; screen_work_rect(&screen); width = PDC_cols * PDC_font_width; height = PDC_rows * PDC_font_height; if (width > screen.right - screen.left - 8) width = screen.right - screen.left - 8; if (height > screen.bottom - screen.top - 8) height = screen.bottom - screen.top - 8; left = screen.left + (screen.right - screen.left - width) / 2; top = screen.top + 16; SetRect(&bounds, (short)left, (short)top, (short)(left + width), (short)(top + height)); c_to_pstr("PDCursesMod", title); window = NewCWindow(NULL, &bounds, title, FALSE, zoomDocProc, (WindowPtr)-1L, TRUE, 0); return window; } void PDC_scr_close(void) { PDC_LOG(("PDC_scr_close() - called\n")); } void PDC_scr_free(void) { PDC_free_palette(); if (PDC_window) { DisposeWindow(PDC_window); PDC_window = NULL; } if (PDC_mouse_rgn) { DisposeRgn(PDC_mouse_rgn); PDC_mouse_rgn = NULL; } #ifdef USING_COMBINING_CHARACTER_SCHEME PDC_expand_combined_characters(0, NULL); #endif } int PDC_scr_open(void) { const char *env; PDC_LOG(("PDC_scr_open() - called\n")); if (!SP) return ERR; if (PDC_init_palette()) return ERR; init_toolbox(); env = getenv("PDC_FONT_SIZE"); if (env) PDC_font_size = atoi(env); if (PDC_font_size < 6) PDC_font_size = 12; env = getenv("PDC_LINES"); if (env) PDC_rows = atoi(env); env = getenv("PDC_COLS"); if (env) PDC_cols = atoi(env); if (initial_rows > 1) PDC_rows = initial_rows; if (initial_cols > 1) PDC_cols = initial_cols; if (PDC_rows < 2) PDC_rows = 25; if (PDC_cols < 2) PDC_cols = 80; if (!PDC_window) { PDC_font_width = PDC_font_size / 2 + 1; PDC_font_height = PDC_font_size + 3; PDC_font_ascent = PDC_font_size - 2; PDC_window = create_window(); if (!PDC_window) return ERR; init_menus(); install_apple_events(); PDC_mouse_rgn = NewRgn(); ShowWindow(PDC_window); SelectWindow(PDC_window); PDC_mac_set_port(); PDC_mac_apply_font(); PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 0); PDC_mac_reset_mouse_rgn(); } SP->mouse_wait = PDC_CLICK_PERIOD; SP->audible = TRUE; SP->mono = FALSE; SP->orig_attr = TRUE; SP->orig_fore = COLOR_WHITE; SP->orig_back = COLOR_BLACK; SP->termattrs = A_COLOR | A_UNDERLINE | A_LEFT | A_RIGHT | A_REVERSE | A_STRIKEOUT | A_TOP | A_BLINK | A_DIM | A_BOLD | A_ITALIC; SP->lines = PDC_rows; SP->cols = PDC_cols; COLORS = 256 + (256 * 256 * 256); PDC_reset_prog_mode(); return OK; } int PDC_resize_screen(int nlines, int ncols) { if (!stdscr) { if (nlines > 1) initial_rows = nlines; if (ncols > 1) initial_cols = ncols; if (nlines > 1) PDC_rows = nlines; if (ncols > 1) PDC_cols = ncols; return OK; } if (nlines > 1 && ncols > 1) PDC_mac_adjust_size(ncols * PDC_font_width, nlines * PDC_font_height, 0); return OK; } void PDC_reset_prog_mode(void) { PDC_LOG(("PDC_reset_prog_mode() - called.\n")); if (PDC_window) { ShowWindow(PDC_window); SelectWindow(PDC_window); PDC_mac_set_port(); } } void PDC_reset_shell_mode(void) { PDC_LOG(("PDC_reset_shell_mode() - called.\n")); } void PDC_restore_screen_mode(int i) { INTENTIONALLY_UNUSED_PARAMETER(i); } void PDC_save_screen_mode(int i) { INTENTIONALLY_UNUSED_PARAMETER(i); } void PDC_set_resize_limits(const int new_min_lines, const int new_max_lines, const int new_min_cols, const int new_max_cols) { PDC_min_lines = new_min_lines; PDC_max_lines = new_max_lines; PDC_min_cols = new_min_cols; PDC_max_cols = new_max_cols; if (PDC_min_lines < 2) PDC_min_lines = 2; if (PDC_min_cols < 2) PDC_min_cols = 2; } bool PDC_can_change_color(void) { return TRUE; } int PDC_color_content(int color, int *red, int *green, int *blue) { const PACKED_RGB col = PDC_get_palette_entry(color); *red = DIVROUND(Get_RValue(col) * 1000, 255); *green = DIVROUND(Get_GValue(col) * 1000, 255); *blue = DIVROUND(Get_BValue(col) * 1000, 255); return OK; } int PDC_init_color(int color, int red, int green, int blue) { const PACKED_RGB new_rgb = PACK_RGB(DIVROUND(red * 255, 1000), DIVROUND(green * 255, 1000), DIVROUND(blue * 255, 1000)); if (!PDC_set_palette_entry(color, new_rgb)) { if (curscr) curscr->_clear = TRUE; } return OK; } \ No newline at end of file diff --git a/mac/pdcsetsc.c b/mac/pdcsetsc.c new file mode 100644 index 00000000..3eaf3c2d --- /dev/null +++ b/mac/pdcsetsc.c @@ -0,0 +1 @@ +#include "pdcmac.h" int PDC_curs_set(int visibility) { int ret_vis; PDC_LOG(("PDC_curs_set() - called: visibility=%d\n", visibility)); ret_vis = SP->visibility; SP->visibility = visibility; PDC_gotoyx(SP->cursrow, SP->curscol); return ret_vis; } void PDC_set_title(const char *title) { Str255 pname; PDC_LOG(("PDC_set_title() - called:<%s>\n", title)); if (!PDC_window) return; { unsigned int length; unsigned int i; length = 0; while (title[length] != 0 && length < 255) length++; pname[0] = (unsigned char)length; for (i = 0; i < length; i++) pname[i + 1] = (unsigned char)title[i]; } SetWTitle(PDC_window, pname); } static int reset_attr(attr_t attr, bool attron) { attr_t prev; if (!SP) return ERR; prev = SP->termattrs; if (attron) SP->termattrs |= attr; else SP->termattrs &= ~attr; if (prev != SP->termattrs && curscr) curscr->_clear = TRUE; return OK; } int PDC_set_blink(bool blinkon) { if (SP && SP->color_started) COLORS = 256 + (256 * 256 * 256); return reset_attr(A_BLINK, blinkon); } int PDC_set_bold(bool boldon) { return reset_attr(A_BOLD, boldon); } \ No newline at end of file diff --git a/mac/pdcurses.r b/mac/pdcurses.r new file mode 100644 index 00000000..9cb1e21f --- /dev/null +++ b/mac/pdcurses.r @@ -0,0 +1 @@ +#include "Types.r" resource 'SIZE' (-1) { reserved, acceptSuspendResumeEvents, reserved, canBackground, doesActivateOnFGSwitch, backgroundAndForeground, dontGetFrontClicks, ignoreChildDiedEvents, is32BitCompatible, isHighLevelEventAware, onlyLocalHLEvents, notStationeryAware, dontUseTextEditServices, reserved, reserved, reserved, 2048 * 1024, 512 * 1024 }; \ No newline at end of file diff --git a/mac/pdcursescw6win.mcp b/mac/pdcursescw6win.mcp new file mode 100644 index 0000000000000000000000000000000000000000..3b022b3409afb7f8ee2635f27b3f247782088dc1 GIT binary patch literal 268637 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 literal 0 HcmV?d00001 diff --git a/mac/pdcursescw8mac b/mac/pdcursescw8mac new file mode 100644 index 0000000000000000000000000000000000000000..565b7c694b20737ad747934c48978a00ed407ffa GIT binary patch literal 223034 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

k%B;fRgVH35J(Fm7-(-%f~ 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 #include -#include +#if !defined(macintosh) + #include +#endif #include void PDC_debug(const char *fmt, ...) diff --git a/pdcurses/getch.c b/pdcurses/getch.c index a0eab2b6..2cd5e7d8 100644 --- a/pdcurses/getch.c +++ b/pdcurses/getch.c @@ -482,6 +482,13 @@ long PDC_millisecs( void) return( t.tv_sec * 1000 + t.tv_usec / 1000); } +#elif defined(macintosh) +#include +long PDC_millisecs( void) +{ + return (((long)TickCount()) * 1000) / 60; +} + #else /* neither gettimeofday() or clock_gettime() available */ #include From 7b0b610f508610a8f24607d745b04a3e4b79d1f0 Mon Sep 17 00:00:00 2001 From: RandoOnSteam Date: Tue, 8 Sep 2026 09:23:19 -0700 Subject: [PATCH 2/6] fix newlines in mac classic/carbon port (before I edited them on mac so they got CR only) --- mac/pdcclip.c | 362 ++++++++++++++++++++++++++++++- mac/pdcdisp.c | 381 +++++++++++++++++++++++++++++++- mac/pdcgetsc.c | 20 +- mac/pdckbd.c | 534 ++++++++++++++++++++++++++++++++++++++++++++- mac/pdcmac.h | 146 ++++++++++++- mac/pdcscrn.c | 578 ++++++++++++++++++++++++++++++++++++++++++++++++- mac/pdcsetsc.c | 62 +++++- mac/pdcutil.c | 35 ++- 8 files changed, 2110 insertions(+), 8 deletions(-) diff --git a/mac/pdcclip.c b/mac/pdcclip.c index 08441276..3c61d011 100644 --- a/mac/pdcclip.c +++ b/mac/pdcclip.c @@ -1 +1,361 @@ -#include "pdcmac.h" #include #include static const unsigned short macroman_unicode[128] = { 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8, 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02, 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7 }; unsigned short PDC_macroman_to_unicode(unsigned char ch) { if (ch < 0x80) return (unsigned short)ch; return macroman_unicode[ch - 0x80]; } unsigned char PDC_unicode_to_macroman(unsigned long code) { int i; if (code < 0x80) return (unsigned char)code; for (i = 0; i < 128; i++) { if ((unsigned long)macroman_unicode[i] == code) return (unsigned char)(i + 0x80); } return (unsigned char)'?'; } static int utf8_encode(unsigned long code, char *out) { if (code < 0x80) { out[0] = (char)code; return 1; } if (code < 0x800) { out[0] = (char)(0xC0 | (code >> 6)); out[1] = (char)(0x80 | (code & 0x3F)); return 2; } if (code < 0x10000) { out[0] = (char)(0xE0 | (code >> 12)); out[1] = (char)(0x80 | ((code >> 6) & 0x3F)); out[2] = (char)(0x80 | (code & 0x3F)); return 3; } out[0] = (char)(0xF0 | (code >> 18)); out[1] = (char)(0x80 | ((code >> 12) & 0x3F)); out[2] = (char)(0x80 | ((code >> 6) & 0x3F)); out[3] = (char)(0x80 | (code & 0x3F)); return 4; } static unsigned long utf8_decode(const unsigned char **pp, const unsigned char *end) { const unsigned char *p; unsigned long code; unsigned int extra; p = *pp; if (p >= end) return 0; if (p[0] < 0x80) { code = p[0]; *pp = p + 1; return code; } if ((p[0] & 0xE0) == 0xC0) { extra = 1; code = p[0] & 0x1F; } else if ((p[0] & 0xF0) == 0xE0) { extra = 2; code = p[0] & 0x0F; } else if ((p[0] & 0xF8) == 0xF0) { extra = 3; code = p[0] & 0x07; } else { *pp = p + 1; return (unsigned long)'?'; } if (p + extra >= end) { *pp = end; return (unsigned long)'?'; } while (extra) { p++; extra--; if ((p[0] & 0xC0) != 0x80) { *pp = p; return (unsigned long)'?'; } code = (code << 6) | (p[0] & 0x3F); } *pp = p + 1; return code; } static int use_utf8_clipboard(void) { #ifdef PDC_WIDE return 1; #else #ifdef PDC_FORCE_UTF8 return 1; #else return 0; #endif #endif } static char *macroman_buffer_to_result(const char *src, long srclen, long *outlen) { char *result; long i; long destlen; long destpos; if (!use_utf8_clipboard()) { result = (char *)malloc((size_t)srclen + 1); if (!result) return NULL; memcpy(result, src, (size_t)srclen); result[srclen] = 0; *outlen = srclen; return result; } destlen = 0; for (i = 0; i < srclen; i++) { unsigned long code; char temp[4]; code = PDC_macroman_to_unicode((unsigned char)src[i]); destlen += utf8_encode(code, temp); } result = (char *)malloc((size_t)destlen + 1); if (!result) return NULL; destpos = 0; for (i = 0; i < srclen; i++) { unsigned long code; char temp[4]; int n; code = PDC_macroman_to_unicode((unsigned char)src[i]); n = utf8_encode(code, temp); memcpy(result + destpos, temp, (size_t)n); destpos += n; } result[destpos] = 0; *outlen = destpos; return result; } static char *result_to_macroman(const char *src, long srclen, long *outlen) { char *result; long destpos; if (!use_utf8_clipboard()) { result = (char *)malloc((size_t)srclen + 1); if (!result) return NULL; memcpy(result, src, (size_t)srclen); result[srclen] = 0; *outlen = srclen; return result; } result = (char *)malloc((size_t)srclen + 1); if (!result) return NULL; destpos = 0; { const unsigned char *p; const unsigned char *end; p = (const unsigned char *)src; end = p + srclen; while (p < end) { unsigned long code; code = utf8_decode(&p, end); result[destpos] = (char)PDC_unicode_to_macroman(code); destpos++; } } result[destpos] = 0; *outlen = destpos; return result; } int PDC_getclipboard(char **contents, long *length) { char *raw; long rawlen; PDC_LOG(("PDC_getclipboard() - called\n")); *contents = NULL; *length = 0; #if TARGET_API_MAC_CARBON { ScrapRef scrap; Size bytecount; OSStatus err; err = GetCurrentScrap(&scrap); if (err != noErr) return PDC_CLIP_ACCESS_ERROR; err = GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &bytecount); if (err == noTypeErr || bytecount <= 0) return PDC_CLIP_EMPTY; if (err != noErr) return PDC_CLIP_ACCESS_ERROR; raw = (char *)malloc((size_t)bytecount + 1); if (!raw) return PDC_CLIP_MEMORY_ERROR; err = GetScrapFlavorData(scrap, kScrapFlavorTypeText, &bytecount, raw); if (err != noErr) { free(raw); return PDC_CLIP_ACCESS_ERROR; } rawlen = (long)bytecount; raw[rawlen] = 0; } #else { Handle datahandle; long offset; long scraplen; datahandle = NewHandle(0); if (!datahandle) return PDC_CLIP_MEMORY_ERROR; scraplen = GetScrap(datahandle, kScrapFlavorTypeText, &offset); if (scraplen <= 0) { DisposeHandle(datahandle); if (scraplen == 0 || scraplen == noTypeErr) return PDC_CLIP_EMPTY; return PDC_CLIP_ACCESS_ERROR; } HLock(datahandle); raw = (char *)malloc((size_t)scraplen + 1); if (!raw) { HUnlock(datahandle); DisposeHandle(datahandle); return PDC_CLIP_MEMORY_ERROR; } BlockMoveData(*datahandle, raw, scraplen); rawlen = scraplen; raw[rawlen] = 0; HUnlock(datahandle); DisposeHandle(datahandle); } #endif *contents = macroman_buffer_to_result(raw, rawlen, length); free(raw); if (!*contents) return PDC_CLIP_MEMORY_ERROR; return PDC_CLIP_SUCCESS; } int PDC_setclipboard(const char *contents, long length) { char *macroman; long maclen; #if TARGET_API_MAC_CARBON OSStatus err; #else OSErr err; #endif PDC_LOG(("PDC_setclipboard() - called\n")); if (!contents) return PDC_clearclipboard(); macroman = result_to_macroman(contents, length, &maclen); if (!macroman) return PDC_CLIP_MEMORY_ERROR; #if TARGET_API_MAC_CARBON { ScrapRef scrap; err = ClearCurrentScrap(); if (err == noErr) err = GetCurrentScrap(&scrap); if (err == noErr) err = PutScrapFlavor(scrap, kScrapFlavorTypeText, 0, maclen, macroman); } #else err = ZeroScrap(); if (err == noErr) err = PutScrap(maclen, kScrapFlavorTypeText, macroman); #endif free(macroman); if (err != noErr) return PDC_CLIP_ACCESS_ERROR; return PDC_CLIP_SUCCESS; } int PDC_freeclipboard(char *contents) { PDC_LOG(("PDC_freeclipboard() - called\n")); if (contents) free(contents); return PDC_CLIP_SUCCESS; } int PDC_clearclipboard(void) { #if TARGET_API_MAC_CARBON OSStatus err; #else OSErr err; #endif PDC_LOG(("PDC_clearclipboard() - called\n")); #if TARGET_API_MAC_CARBON err = ClearCurrentScrap(); #else err = ZeroScrap(); #endif if (err != noErr) return PDC_CLIP_ACCESS_ERROR; return PDC_CLIP_SUCCESS; } \ No newline at end of file +#include "pdcmac.h" +#include +#include + +static const unsigned short macroman_unicode[128] = +{ + 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, + 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, + 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, + 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, + 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, + 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, + 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, + 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8, + 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, + 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02, + 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, + 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, + 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, + 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7 +}; + +unsigned short PDC_macroman_to_unicode(unsigned char ch) +{ + if (ch < 0x80) + return (unsigned short)ch; + return macroman_unicode[ch - 0x80]; +} + +unsigned char PDC_unicode_to_macroman(unsigned long code) +{ + int i; + + if (code < 0x80) + return (unsigned char)code; + for (i = 0; i < 128; i++) + { + if ((unsigned long)macroman_unicode[i] == code) + return (unsigned char)(i + 0x80); + } + return (unsigned char)'?'; +} + +static int utf8_encode(unsigned long code, char *out) +{ + if (code < 0x80) + { + out[0] = (char)code; + return 1; + } + if (code < 0x800) + { + out[0] = (char)(0xC0 | (code >> 6)); + out[1] = (char)(0x80 | (code & 0x3F)); + return 2; + } + if (code < 0x10000) + { + out[0] = (char)(0xE0 | (code >> 12)); + out[1] = (char)(0x80 | ((code >> 6) & 0x3F)); + out[2] = (char)(0x80 | (code & 0x3F)); + return 3; + } + out[0] = (char)(0xF0 | (code >> 18)); + out[1] = (char)(0x80 | ((code >> 12) & 0x3F)); + out[2] = (char)(0x80 | ((code >> 6) & 0x3F)); + out[3] = (char)(0x80 | (code & 0x3F)); + return 4; +} + +static unsigned long utf8_decode(const unsigned char **pp, const unsigned char *end) +{ + const unsigned char *p; + unsigned long code; + unsigned int extra; + + p = *pp; + if (p >= end) + return 0; + if (p[0] < 0x80) + { + code = p[0]; + *pp = p + 1; + return code; + } + if ((p[0] & 0xE0) == 0xC0) + { + extra = 1; + code = p[0] & 0x1F; + } + else if ((p[0] & 0xF0) == 0xE0) + { + extra = 2; + code = p[0] & 0x0F; + } + else if ((p[0] & 0xF8) == 0xF0) + { + extra = 3; + code = p[0] & 0x07; + } + else + { + *pp = p + 1; + return (unsigned long)'?'; + } + if (p + extra >= end) + { + *pp = end; + return (unsigned long)'?'; + } + while (extra) + { + p++; + extra--; + if ((p[0] & 0xC0) != 0x80) + { + *pp = p; + return (unsigned long)'?'; + } + code = (code << 6) | (p[0] & 0x3F); + } + *pp = p + 1; + return code; +} + +static int use_utf8_clipboard(void) +{ +#ifdef PDC_WIDE + return 1; +#else +#ifdef PDC_FORCE_UTF8 + return 1; +#else + return 0; +#endif +#endif +} + +static char *macroman_buffer_to_result(const char *src, long srclen, long *outlen) +{ + char *result; + long i; + long destlen; + long destpos; + + if (!use_utf8_clipboard()) + { + result = (char *)malloc((size_t)srclen + 1); + if (!result) + return NULL; + memcpy(result, src, (size_t)srclen); + result[srclen] = 0; + *outlen = srclen; + return result; + } + destlen = 0; + for (i = 0; i < srclen; i++) + { + unsigned long code; + char temp[4]; + + code = PDC_macroman_to_unicode((unsigned char)src[i]); + destlen += utf8_encode(code, temp); + } + result = (char *)malloc((size_t)destlen + 1); + if (!result) + return NULL; + destpos = 0; + for (i = 0; i < srclen; i++) + { + unsigned long code; + char temp[4]; + int n; + + code = PDC_macroman_to_unicode((unsigned char)src[i]); + n = utf8_encode(code, temp); + memcpy(result + destpos, temp, (size_t)n); + destpos += n; + } + result[destpos] = 0; + *outlen = destpos; + return result; +} + +static char *result_to_macroman(const char *src, long srclen, long *outlen) +{ + char *result; + long destpos; + + if (!use_utf8_clipboard()) + { + result = (char *)malloc((size_t)srclen + 1); + if (!result) + return NULL; + memcpy(result, src, (size_t)srclen); + result[srclen] = 0; + *outlen = srclen; + return result; + } + result = (char *)malloc((size_t)srclen + 1); + if (!result) + return NULL; + destpos = 0; + { + const unsigned char *p; + const unsigned char *end; + + p = (const unsigned char *)src; + end = p + srclen; + while (p < end) + { + unsigned long code; + + code = utf8_decode(&p, end); + result[destpos] = (char)PDC_unicode_to_macroman(code); + destpos++; + } + } + result[destpos] = 0; + *outlen = destpos; + return result; +} + +int PDC_getclipboard(char **contents, long *length) +{ + char *raw; + long rawlen; + + PDC_LOG(("PDC_getclipboard() - called\n")); + *contents = NULL; + *length = 0; +#if TARGET_API_MAC_CARBON + { + ScrapRef scrap; + Size bytecount; + OSStatus err; + + err = GetCurrentScrap(&scrap); + if (err != noErr) + return PDC_CLIP_ACCESS_ERROR; + err = GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &bytecount); + if (err == noTypeErr || bytecount <= 0) + return PDC_CLIP_EMPTY; + if (err != noErr) + return PDC_CLIP_ACCESS_ERROR; + raw = (char *)malloc((size_t)bytecount + 1); + if (!raw) + return PDC_CLIP_MEMORY_ERROR; + err = GetScrapFlavorData(scrap, kScrapFlavorTypeText, &bytecount, raw); + if (err != noErr) + { + free(raw); + return PDC_CLIP_ACCESS_ERROR; + } + rawlen = (long)bytecount; + raw[rawlen] = 0; + } +#else + { + Handle datahandle; + long offset; + long scraplen; + + datahandle = NewHandle(0); + if (!datahandle) + return PDC_CLIP_MEMORY_ERROR; + scraplen = GetScrap(datahandle, kScrapFlavorTypeText, &offset); + if (scraplen <= 0) + { + DisposeHandle(datahandle); + if (scraplen == 0 || scraplen == noTypeErr) + return PDC_CLIP_EMPTY; + return PDC_CLIP_ACCESS_ERROR; + } + HLock(datahandle); + raw = (char *)malloc((size_t)scraplen + 1); + if (!raw) + { + HUnlock(datahandle); + DisposeHandle(datahandle); + return PDC_CLIP_MEMORY_ERROR; + } + BlockMoveData(*datahandle, raw, scraplen); + rawlen = scraplen; + raw[rawlen] = 0; + HUnlock(datahandle); + DisposeHandle(datahandle); + } +#endif + *contents = macroman_buffer_to_result(raw, rawlen, length); + free(raw); + if (!*contents) + return PDC_CLIP_MEMORY_ERROR; + return PDC_CLIP_SUCCESS; +} + +int PDC_setclipboard(const char *contents, long length) +{ + char *macroman; + long maclen; +#if TARGET_API_MAC_CARBON + OSStatus err; +#else + OSErr err; +#endif + + PDC_LOG(("PDC_setclipboard() - called\n")); + if (!contents) + return PDC_clearclipboard(); + macroman = result_to_macroman(contents, length, &maclen); + if (!macroman) + return PDC_CLIP_MEMORY_ERROR; +#if TARGET_API_MAC_CARBON + { + ScrapRef scrap; + + err = ClearCurrentScrap(); + if (err == noErr) + err = GetCurrentScrap(&scrap); + if (err == noErr) + err = PutScrapFlavor(scrap, kScrapFlavorTypeText, 0, maclen, macroman); + } +#else + err = ZeroScrap(); + if (err == noErr) + err = PutScrap(maclen, kScrapFlavorTypeText, macroman); +#endif + free(macroman); + if (err != noErr) + return PDC_CLIP_ACCESS_ERROR; + return PDC_CLIP_SUCCESS; +} + +int PDC_freeclipboard(char *contents) +{ + PDC_LOG(("PDC_freeclipboard() - called\n")); + if (contents) + free(contents); + return PDC_CLIP_SUCCESS; +} + +int PDC_clearclipboard(void) +{ +#if TARGET_API_MAC_CARBON + OSStatus err; +#else + OSErr err; +#endif + + PDC_LOG(("PDC_clearclipboard() - called\n")); +#if TARGET_API_MAC_CARBON + err = ClearCurrentScrap(); +#else + err = ZeroScrap(); +#endif + if (err != noErr) + return PDC_CLIP_ACCESS_ERROR; + return PDC_CLIP_SUCCESS; +} diff --git a/mac/pdcdisp.c b/mac/pdcdisp.c index 8b0eb417..7122e3a0 100644 --- a/mac/pdcdisp.c +++ b/mac/pdcdisp.c @@ -1 +1,380 @@ -#include "pdcmac.h" #include #ifdef PDC_WIDE #define USE_UNICODE_ACS_CHARS 1 #else #define USE_UNICODE_ACS_CHARS 0 #endif #include #include #include #ifndef PACK_RGB #define PACK_RGB(red, green, blue) ((PACKED_RGB)(red) | ((PACKED_RGB)(green) << 8) | ((PACKED_RGB)(blue) << 16)) #endif static void packed_to_rgb(PACKED_RGB packed, RGBColor *color) { unsigned int red; unsigned int green; unsigned int blue; red = Get_RValue(packed); green = Get_GValue(packed); blue = Get_BValue(packed); color->red = (unsigned short)((red << 8) | red); color->green = (unsigned short)((green << 8) | green); color->blue = (unsigned short)((blue << 8) | blue); } static void fill_rect(Rect *cell, const RGBColor *color) { RGBForeColor(color); PaintRect(cell); } static int is_hline(unsigned long ch) { if (ch == 0x2500 || ch == 0x2501 || ch == 0x2550) return 1; if (ch == 0xC4 || ch == 0xCD) return 1; return 0; } static int is_vline(unsigned long ch) { if (ch == 0x2502 || ch == 0x2503 || ch == 0x2551) return 1; if (ch == 0xB3 || ch == 0xBA) return 1; return 0; } static int box_mask(unsigned long ch) { int mask; mask = 0; if (ch == 0x250C || ch == 0x250F || ch == 0x2554 || ch == 0xDA || ch == 0xC9) mask = 2 | 8; else if (ch == 0x2510 || ch == 0x2513 || ch == 0x2557 || ch == 0xBF || ch == 0xBB) mask = 2 | 4; else if (ch == 0x2514 || ch == 0x2517 || ch == 0x255A || ch == 0xC0 || ch == 0xC8) mask = 1 | 8; else if (ch == 0x2518 || ch == 0x251B || ch == 0x255D || ch == 0xD9 || ch == 0xBC) mask = 1 | 4; else if (ch == 0x251C || ch == 0x2523 || ch == 0x2560 || ch == 0xC3 || ch == 0xCC) mask = 1 | 2 | 8; else if (ch == 0x2524 || ch == 0x252B || ch == 0x2563 || ch == 0xB4 || ch == 0xB9) mask = 1 | 2 | 4; else if (ch == 0x252C || ch == 0x2533 || ch == 0x2566 || ch == 0xC2 || ch == 0xCB) mask = 2 | 4 | 8; else if (ch == 0x2534 || ch == 0x253B || ch == 0x2569 || ch == 0xC1 || ch == 0xCA) mask = 1 | 4 | 8; else if (ch == 0x253C || ch == 0x254B || ch == 0x256C || ch == 0xC5 || ch == 0xCE) mask = 1 | 2 | 4 | 8; return mask; } static int draw_graphic(unsigned long ch, Rect *cell, const RGBColor *fg) { int midx; int midy; int mask; midx = (cell->left + cell->right) / 2; midy = (cell->top + cell->bottom) / 2; RGBForeColor(fg); PenNormal(); PenSize(1, 1); if (ch == 0x2588 || ch == 0xDB) { PaintRect(cell); return 1; } if (ch == 0x2580 || ch == 0xDF) { Rect half; half = *cell; half.bottom = midy; PaintRect(&half); return 1; } if (ch == 0x2584 || ch == 0xDC) { Rect half; half = *cell; half.top = midy; PaintRect(&half); return 1; } if (ch == 0x258C || ch == 0xDD) { Rect half; half = *cell; half.right = midx; PaintRect(&half); return 1; } if (ch == 0x2590 || ch == 0xDE) { Rect half; half = *cell; half.left = midx; PaintRect(&half); return 1; } if (ch == 0x2591 || ch == 0xB0 || ch == 0x2592 || ch == 0xB1 || ch == 0x2593 || ch == 0xB2) { #if TARGET_API_MAC_CARBON Pattern pat; if (ch == 0x2591 || ch == 0xB0) GetQDGlobalsLightGray(&pat); else if (ch == 0x2593 || ch == 0xB2) GetQDGlobalsDarkGray(&pat); else GetQDGlobalsGray(&pat); PenPat(&pat); #else if (ch == 0x2591 || ch == 0xB0) PenPat(&qd.ltGray); else if (ch == 0x2593 || ch == 0xB2) PenPat(&qd.dkGray); else PenPat(&qd.gray); #endif PaintRect(cell); PenNormal(); return 1; } if (is_hline(ch)) { MoveTo(cell->left, midy); LineTo(cell->right - 1, midy); return 1; } if (is_vline(ch)) { MoveTo(midx, cell->top); LineTo(midx, cell->bottom - 1); return 1; } mask = box_mask(ch); if (mask) { if (mask & 1) { MoveTo(midx, cell->top); LineTo(midx, midy); } if (mask & 2) { MoveTo(midx, midy); LineTo(midx, cell->bottom - 1); } if (mask & 4) { MoveTo(cell->left, midy); LineTo(midx, midy); } if (mask & 8) { MoveTo(midx, midy); LineTo(cell->right - 1, midy); } return 1; } if (ch == 0x25C6 || ch == 0x2666 || ch == 0x04) { MoveTo(midx, cell->top + 1); LineTo(cell->right - 2, midy); LineTo(midx, cell->bottom - 2); LineTo(cell->left + 1, midy); LineTo(midx, cell->top + 1); return 1; } return 0; } static void draw_cursor_shape(Rect *cell, const RGBColor *fg) { int style; Rect bar; style = SP->drawing_cursor; RGBForeColor(fg); bar = *cell; if (style == 2) { InvertRect(&bar); return; } if (style == 1) { bar.top = bar.bottom - PDC_font_height / 5; if (bar.top < cell->top) bar.top = cell->top; PaintRect(&bar); } else if (style == 5) { bar.top = (cell->top + cell->bottom) / 2; PaintRect(&bar); } else if (style == 3) { FrameRect(&bar); } else if (style == 4) { MoveTo(cell->left + 1, cell->top); LineTo(cell->left + 1, cell->bottom - 1); } } static unsigned char char_to_mac(unsigned long ch) { if (ch < 0x100) return (unsigned char)ch; return PDC_unicode_to_macroman(ch); } void PDC_transform_line(int lineno, int x, int len, const chtype *srcp) { int i; Rect clipbounds; PDC_LOG(("PDC_transform_line() - called: lineno=%d\n", lineno)); if (!srcp || len <= 0 || !PDC_window) return; PDC_mac_set_port(); PDC_mac_port_bounds(&clipbounds); TextFont(monaco); TextSize(PDC_font_size); for (i = 0; i < len; i++) { chtype cell; unsigned long ch; PACKED_RGB fgpacked; PACKED_RGB bgpacked; RGBColor fg; RGBColor bg; Rect r; Style face; attr_t sysattrs; cell = srcp[i]; sysattrs = SP->termattrs; if (_is_altcharset(cell)) ch = (unsigned long)acs_map[cell & 0x7f]; else ch = (unsigned long)(cell & A_CHARTEXT); if ((cell & A_BLINK) && SP->blink_state && (sysattrs & A_BLINK)) ch = (unsigned long)' '; PDC_get_rgb_values(cell, &fgpacked, &bgpacked); if (fgpacked == (PACKED_RGB)-1) fgpacked = PACK_RGB(0xC0, 0xC0, 0xC0); if (bgpacked == (PACKED_RGB)-1) bgpacked = PACK_RGB(0, 0, 0); packed_to_rgb(fgpacked, &fg); packed_to_rgb(bgpacked, &bg); PDC_mac_cell_rect(lineno, x + i, &r); ClipRect(&r); fill_rect(&r, &bg); RGBForeColor(&fg); RGBBackColor(&bg); face = 0; if ((cell & A_BOLD) && (sysattrs & A_BOLD)) face |= bold; if ((cell & A_ITALIC) && (sysattrs & A_ITALIC)) face |= italic; TextFace(face); if (!draw_graphic(ch, &r, &fg)) { unsigned char drawn; drawn = char_to_mac(ch); if (drawn < 32) drawn = (unsigned char)' '; MoveTo(r.left, r.top + PDC_font_ascent); DrawChar(drawn); } if (cell & (A_UNDERLINE | A_TOP | A_LEFT | A_RIGHT | A_STRIKEOUT)) { RGBColor linec; int lineidx; lineidx = SP->line_color; if (lineidx != -1) packed_to_rgb(PDC_get_palette_entry(lineidx), &linec); else linec = fg; RGBForeColor(&linec); PenNormal(); if (cell & A_UNDERLINE) { MoveTo(r.left, r.bottom - 1); LineTo(r.right - 1, r.bottom - 1); } if (cell & A_TOP) { MoveTo(r.left, r.top); LineTo(r.right - 1, r.top); } if (cell & A_STRIKEOUT) { int midy; midy = (r.top + r.bottom) / 2; MoveTo(r.left, midy); LineTo(r.right - 1, midy); } if (cell & A_LEFT) { MoveTo(r.left, r.top); LineTo(r.left, r.bottom - 1); } if (cell & A_RIGHT) { MoveTo(r.right - 1, r.top); LineTo(r.right - 1, r.bottom - 1); } } if (SP->drawing_cursor) draw_cursor_shape(&r, &fg); ClipRect(&clipbounds); } TextFace(0); #ifdef MAC_OS_X_VERSION_10_0 { CGrafPtr port; port = GetWindowPort(PDC_window); if (port) QDFlushPortBuffer(port, NULL); } #endif } void PDC_doupdate(void) { #ifdef MAC_OS_X_VERSION_10_0 if (PDC_window) { CGrafPtr port; port = GetWindowPort(PDC_window); if (port) QDFlushPortBuffer(port, NULL); } #endif } \ No newline at end of file +#include "pdcmac.h" +#include + +#ifdef PDC_WIDE +#define USE_UNICODE_ACS_CHARS 1 +#else +#define USE_UNICODE_ACS_CHARS 0 +#endif + +#include +#include +#include + +#ifndef PACK_RGB +#define PACK_RGB(red, green, blue) ((PACKED_RGB)(red) | ((PACKED_RGB)(green) << 8) | ((PACKED_RGB)(blue) << 16)) +#endif + +static void packed_to_rgb(PACKED_RGB packed, RGBColor *color) +{ + unsigned int red; + unsigned int green; + unsigned int blue; + + red = Get_RValue(packed); + green = Get_GValue(packed); + blue = Get_BValue(packed); + color->red = (unsigned short)((red << 8) | red); + color->green = (unsigned short)((green << 8) | green); + color->blue = (unsigned short)((blue << 8) | blue); +} + +static void fill_rect(Rect *cell, const RGBColor *color) +{ + RGBForeColor(color); + PaintRect(cell); +} + +static int is_hline(unsigned long ch) +{ + if (ch == 0x2500 || ch == 0x2501 || ch == 0x2550) + return 1; + if (ch == 0xC4 || ch == 0xCD) + return 1; + return 0; +} + +static int is_vline(unsigned long ch) +{ + if (ch == 0x2502 || ch == 0x2503 || ch == 0x2551) + return 1; + if (ch == 0xB3 || ch == 0xBA) + return 1; + return 0; +} + +static int box_mask(unsigned long ch) +{ + int mask; + + mask = 0; + if (ch == 0x250C || ch == 0x250F || ch == 0x2554 || ch == 0xDA || ch == 0xC9) + mask = 2 | 8; + else if (ch == 0x2510 || ch == 0x2513 || ch == 0x2557 || ch == 0xBF || ch == 0xBB) + mask = 2 | 4; + else if (ch == 0x2514 || ch == 0x2517 || ch == 0x255A || ch == 0xC0 || ch == 0xC8) + mask = 1 | 8; + else if (ch == 0x2518 || ch == 0x251B || ch == 0x255D || ch == 0xD9 || ch == 0xBC) + mask = 1 | 4; + else if (ch == 0x251C || ch == 0x2523 || ch == 0x2560 || ch == 0xC3 || ch == 0xCC) + mask = 1 | 2 | 8; + else if (ch == 0x2524 || ch == 0x252B || ch == 0x2563 || ch == 0xB4 || ch == 0xB9) + mask = 1 | 2 | 4; + else if (ch == 0x252C || ch == 0x2533 || ch == 0x2566 || ch == 0xC2 || ch == 0xCB) + mask = 2 | 4 | 8; + else if (ch == 0x2534 || ch == 0x253B || ch == 0x2569 || ch == 0xC1 || ch == 0xCA) + mask = 1 | 4 | 8; + else if (ch == 0x253C || ch == 0x254B || ch == 0x256C || ch == 0xC5 || ch == 0xCE) + mask = 1 | 2 | 4 | 8; + return mask; +} + +static int draw_graphic(unsigned long ch, Rect *cell, const RGBColor *fg) +{ + int midx; + int midy; + int mask; + + midx = (cell->left + cell->right) / 2; + midy = (cell->top + cell->bottom) / 2; + RGBForeColor(fg); + PenNormal(); + PenSize(1, 1); + if (ch == 0x2588 || ch == 0xDB) + { + PaintRect(cell); + return 1; + } + if (ch == 0x2580 || ch == 0xDF) + { + Rect half; + + half = *cell; + half.bottom = midy; + PaintRect(&half); + return 1; + } + if (ch == 0x2584 || ch == 0xDC) + { + Rect half; + + half = *cell; + half.top = midy; + PaintRect(&half); + return 1; + } + if (ch == 0x258C || ch == 0xDD) + { + Rect half; + + half = *cell; + half.right = midx; + PaintRect(&half); + return 1; + } + if (ch == 0x2590 || ch == 0xDE) + { + Rect half; + + half = *cell; + half.left = midx; + PaintRect(&half); + return 1; + } + if (ch == 0x2591 || ch == 0xB0 || ch == 0x2592 || ch == 0xB1 + || ch == 0x2593 || ch == 0xB2) + { +#if TARGET_API_MAC_CARBON + Pattern pat; + + if (ch == 0x2591 || ch == 0xB0) + GetQDGlobalsLightGray(&pat); + else if (ch == 0x2593 || ch == 0xB2) + GetQDGlobalsDarkGray(&pat); + else + GetQDGlobalsGray(&pat); + PenPat(&pat); +#else + if (ch == 0x2591 || ch == 0xB0) + PenPat(&qd.ltGray); + else if (ch == 0x2593 || ch == 0xB2) + PenPat(&qd.dkGray); + else + PenPat(&qd.gray); +#endif + PaintRect(cell); + PenNormal(); + return 1; + } + if (is_hline(ch)) + { + MoveTo(cell->left, midy); + LineTo(cell->right - 1, midy); + return 1; + } + if (is_vline(ch)) + { + MoveTo(midx, cell->top); + LineTo(midx, cell->bottom - 1); + return 1; + } + mask = box_mask(ch); + if (mask) + { + if (mask & 1) + { + MoveTo(midx, cell->top); + LineTo(midx, midy); + } + if (mask & 2) + { + MoveTo(midx, midy); + LineTo(midx, cell->bottom - 1); + } + if (mask & 4) + { + MoveTo(cell->left, midy); + LineTo(midx, midy); + } + if (mask & 8) + { + MoveTo(midx, midy); + LineTo(cell->right - 1, midy); + } + return 1; + } + if (ch == 0x25C6 || ch == 0x2666 || ch == 0x04) + { + MoveTo(midx, cell->top + 1); + LineTo(cell->right - 2, midy); + LineTo(midx, cell->bottom - 2); + LineTo(cell->left + 1, midy); + LineTo(midx, cell->top + 1); + return 1; + } + return 0; +} + +static void draw_cursor_shape(Rect *cell, const RGBColor *fg) +{ + int style; + Rect bar; + + style = SP->drawing_cursor; + RGBForeColor(fg); + bar = *cell; + if (style == 2) + { + InvertRect(&bar); + return; + } + if (style == 1) + { + bar.top = bar.bottom - PDC_font_height / 5; + if (bar.top < cell->top) + bar.top = cell->top; + PaintRect(&bar); + } + else if (style == 5) + { + bar.top = (cell->top + cell->bottom) / 2; + PaintRect(&bar); + } + else if (style == 3) + { + FrameRect(&bar); + } + else if (style == 4) + { + MoveTo(cell->left + 1, cell->top); + LineTo(cell->left + 1, cell->bottom - 1); + } +} + +static unsigned char char_to_mac(unsigned long ch) +{ + if (ch < 0x100) + return (unsigned char)ch; + return PDC_unicode_to_macroman(ch); +} + +void PDC_transform_line(int lineno, int x, int len, const chtype *srcp) +{ + int i; + Rect clipbounds; + + PDC_LOG(("PDC_transform_line() - called: lineno=%d\n", lineno)); + if (!srcp || len <= 0 || !PDC_window) + return; + PDC_mac_set_port(); + PDC_mac_port_bounds(&clipbounds); + TextFont(monaco); + TextSize(PDC_font_size); + for (i = 0; i < len; i++) + { + chtype cell; + unsigned long ch; + PACKED_RGB fgpacked; + PACKED_RGB bgpacked; + RGBColor fg; + RGBColor bg; + Rect r; + Style face; + attr_t sysattrs; + + cell = srcp[i]; + sysattrs = SP->termattrs; + if (_is_altcharset(cell)) + ch = (unsigned long)acs_map[cell & 0x7f]; + else + ch = (unsigned long)(cell & A_CHARTEXT); + if ((cell & A_BLINK) && SP->blink_state && (sysattrs & A_BLINK)) + ch = (unsigned long)' '; + PDC_get_rgb_values(cell, &fgpacked, &bgpacked); + if (fgpacked == (PACKED_RGB)-1) + fgpacked = PACK_RGB(0xC0, 0xC0, 0xC0); + if (bgpacked == (PACKED_RGB)-1) + bgpacked = PACK_RGB(0, 0, 0); + packed_to_rgb(fgpacked, &fg); + packed_to_rgb(bgpacked, &bg); + PDC_mac_cell_rect(lineno, x + i, &r); + ClipRect(&r); + fill_rect(&r, &bg); + RGBForeColor(&fg); + RGBBackColor(&bg); + face = 0; + if ((cell & A_BOLD) && (sysattrs & A_BOLD)) + face |= bold; + if ((cell & A_ITALIC) && (sysattrs & A_ITALIC)) + face |= italic; + TextFace(face); + if (!draw_graphic(ch, &r, &fg)) + { + unsigned char drawn; + + drawn = char_to_mac(ch); + if (drawn < 32) + drawn = (unsigned char)' '; + MoveTo(r.left, r.top + PDC_font_ascent); + DrawChar(drawn); + } + if (cell & (A_UNDERLINE | A_TOP | A_LEFT | A_RIGHT | A_STRIKEOUT)) + { + RGBColor linec; + int lineidx; + + lineidx = SP->line_color; + if (lineidx != -1) + packed_to_rgb(PDC_get_palette_entry(lineidx), &linec); + else + linec = fg; + RGBForeColor(&linec); + PenNormal(); + if (cell & A_UNDERLINE) + { + MoveTo(r.left, r.bottom - 1); + LineTo(r.right - 1, r.bottom - 1); + } + if (cell & A_TOP) + { + MoveTo(r.left, r.top); + LineTo(r.right - 1, r.top); + } + if (cell & A_STRIKEOUT) + { + int midy; + + midy = (r.top + r.bottom) / 2; + MoveTo(r.left, midy); + LineTo(r.right - 1, midy); + } + if (cell & A_LEFT) + { + MoveTo(r.left, r.top); + LineTo(r.left, r.bottom - 1); + } + if (cell & A_RIGHT) + { + MoveTo(r.right - 1, r.top); + LineTo(r.right - 1, r.bottom - 1); + } + } + if (SP->drawing_cursor) + draw_cursor_shape(&r, &fg); + ClipRect(&clipbounds); + } + TextFace(0); +#ifdef MAC_OS_X_VERSION_10_0 + { + CGrafPtr port; + + port = GetWindowPort(PDC_window); + if (port) + QDFlushPortBuffer(port, NULL); + } +#endif +} + +void PDC_doupdate(void) +{ +#ifdef MAC_OS_X_VERSION_10_0 + if (PDC_window) + { + CGrafPtr port; + + port = GetWindowPort(PDC_window); + if (port) + QDFlushPortBuffer(port, NULL); + } +#endif +} diff --git a/mac/pdcgetsc.c b/mac/pdcgetsc.c index 0927e7e2..9bd40758 100644 --- a/mac/pdcgetsc.c +++ b/mac/pdcgetsc.c @@ -1 +1,19 @@ -#include "pdcmac.h" int PDC_get_cursor_mode(void) { PDC_LOG(("PDC_get_cursor_mode() - called\n")); return 0; } int PDC_get_rows(void) { PDC_LOG(("PDC_get_rows() - called\n")); return PDC_rows; } int PDC_get_columns(void) { PDC_LOG(("PDC_get_columns() - called\n")); return PDC_cols; } \ No newline at end of file +#include "pdcmac.h" + +int PDC_get_cursor_mode(void) +{ + PDC_LOG(("PDC_get_cursor_mode() - called\n")); + return 0; +} + +int PDC_get_rows(void) +{ + PDC_LOG(("PDC_get_rows() - called\n")); + return PDC_rows; +} + +int PDC_get_columns(void) +{ + PDC_LOG(("PDC_get_columns() - called\n")); + return PDC_cols; +} diff --git a/mac/pdckbd.c b/mac/pdckbd.c index df79e23f..0fb1a952 100644 --- a/mac/pdckbd.c +++ b/mac/pdckbd.c @@ -1 +1,533 @@ -#include "pdcmac.h" #include #include #include #include int PDC_key_queue[PDC_KEY_QUEUE_SIZE]; int PDC_key_queue_head = 0; int PDC_key_queue_tail = 0; static int last_mouse_button = 0; static Point last_mouse_local; static int prev_special_key = -1; static const struct { unsigned char keycode; unsigned char numkeypad; unsigned short normal; unsigned short shifted; unsigned short control; unsigned short alt; } key_table[] = { { 0x7B, 0, KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT }, { 0x7C, 0, KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT }, { 0x7E, 0, KEY_UP, KEY_SUP, CTL_UP, ALT_UP }, { 0x7D, 0, KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN }, { 0x73, 0, KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME }, { 0x77, 0, KEY_END, KEY_SEND, CTL_END, ALT_END }, { 0x74, 0, KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP }, { 0x79, 0, KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN }, { 0x72, 0, KEY_IC, KEY_SIC, CTL_INS, ALT_INS }, { 0x75, 0, KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL }, { 0x33, 0, 0x08, 0x08, CTL_BKSP, ALT_BKSP }, { 0x30, 0, 0x09, KEY_BTAB, CTL_TAB, ALT_TAB }, { 0x35, 0, 0x1B, 0x1B, 0x1B, ALT_ESC }, { 0x24, 0, 0x0D, 0x0D, 0x0D, 0x0D }, { 0x4C, 1, PADENTER, PADENTER, CTL_PADENTER, ALT_PADENTER }, { 0x45, 1, PADPLUS, '+', CTL_PADPLUS, ALT_PADPLUS }, { 0x4E, 1, PADMINUS, '-', CTL_PADMINUS, ALT_PADMINUS }, { 0x43, 1, PADSTAR, '*', CTL_PADSTAR, ALT_PADSTAR }, { 0x4B, 1, PADSLASH, '/', CTL_PADSLASH, ALT_PADSLASH }, { 0x41, 1, PADSTOP, '.', CTL_PADSTOP, ALT_PADSTOP }, { 0x52, 1, PAD0, '0', CTL_PAD0, ALT_PAD0 }, { 0x53, 1, KEY_C1, '1', CTL_PAD1, ALT_PAD1 }, { 0x54, 1, KEY_C2, '2', CTL_PAD2, ALT_PAD2 }, { 0x55, 1, KEY_C3, '3', CTL_PAD3, ALT_PAD3 }, { 0x56, 1, KEY_B1, '4', CTL_PAD4, ALT_PAD4 }, { 0x57, 1, KEY_B2, '5', CTL_PAD5, ALT_PAD5 }, { 0x58, 1, KEY_B3, '6', CTL_PAD6, ALT_PAD6 }, { 0x59, 1, KEY_A1, '7', CTL_PAD7, ALT_PAD7 }, { 0x5B, 1, KEY_A2, '8', CTL_PAD8, ALT_PAD8 }, { 0x5C, 1, KEY_A3, '9', CTL_PAD9, ALT_PAD9 }, { 0x47, 1, KEY_CLEAR, KEY_CLEAR, KEY_CLEAR, KEY_CLEAR }, { 0x7A, 0, KEY_F(1), KEY_F(13), KEY_F(25), KEY_F(37) }, { 0x78, 0, KEY_F(2), KEY_F(14), KEY_F(26), KEY_F(38) }, { 0x63, 0, KEY_F(3), KEY_F(15), KEY_F(27), KEY_F(39) }, { 0x76, 0, KEY_F(4), KEY_F(16), KEY_F(28), KEY_F(40) }, { 0x60, 0, KEY_F(5), KEY_F(17), KEY_F(29), KEY_F(41) }, { 0x61, 0, KEY_F(6), KEY_F(18), KEY_F(30), KEY_F(42) }, { 0x62, 0, KEY_F(7), KEY_F(19), KEY_F(31), KEY_F(43) }, { 0x64, 0, KEY_F(8), KEY_F(20), KEY_F(32), KEY_F(44) }, { 0x65, 0, KEY_F(9), KEY_F(21), KEY_F(33), KEY_F(45) }, { 0x6D, 0, KEY_F(10), KEY_F(22), KEY_F(34), KEY_F(46) }, { 0x67, 0, KEY_F(11), KEY_F(23), KEY_F(35), KEY_F(47) }, { 0x6F, 0, KEY_F(12), KEY_F(24), KEY_F(36), KEY_F(48) }, { 0x69, 0, KEY_F(13), KEY_F(25), KEY_F(37), KEY_F(49) }, { 0x6B, 0, KEY_F(14), KEY_F(26), KEY_F(38), KEY_F(50) }, { 0x71, 0, KEY_F(15), KEY_F(27), KEY_F(39), KEY_F(51) }, { 0, 0, 0, 0, 0, 0 } }; void PDC_mac_add_key(int key) { int next; if (!key) return; next = PDC_key_queue_tail + 1; if (next >= PDC_KEY_QUEUE_SIZE) next = 0; if (next == PDC_key_queue_head) return; if (key == KEY_RESIZE) { int i; i = PDC_key_queue_head; while (i != PDC_key_queue_tail) { if (PDC_key_queue[i] == KEY_RESIZE) return; i++; if (i >= PDC_KEY_QUEUE_SIZE) i = 0; } if (SP) SP->resized = TRUE; } PDC_key_queue[PDC_key_queue_tail] = key; PDC_key_queue_tail = next; } static int queue_has_key(void) { if (PDC_key_queue_head != PDC_key_queue_tail) return 1; return 0; } static int pop_key(void) { int key; if (PDC_key_queue_head == PDC_key_queue_tail) return -1; key = PDC_key_queue[PDC_key_queue_head]; PDC_key_queue_head++; if (PDC_key_queue_head >= PDC_KEY_QUEUE_SIZE) PDC_key_queue_head = 0; if (key == KEY_MOUSE) _get_mouse_event(&SP->mouse_status); return key; } static unsigned long modifiers_from_event(const EventRecord *event) { unsigned long mods; mods = 0; if (event->modifiers & shiftKey) mods |= PDC_KEY_MODIFIER_SHIFT; if (event->modifiers & controlKey) mods |= PDC_KEY_MODIFIER_CONTROL; if (event->modifiers & optionKey) mods |= PDC_KEY_MODIFIER_ALT; if (event->modifiers & cmdKey) mods |= PDC_KEY_MODIFIER_SUPER; if (event->modifiers & alphaLock) mods |= PDC_KEY_MODIFIER_CAPSLOCK; return mods; } static int mouse_modifs(const EventRecord *event) { int mods; mods = 0; if (event->modifiers & shiftKey) mods |= BUTTON_SHIFT; if (event->modifiers & controlKey) mods |= BUTTON_CONTROL; if (event->modifiers & optionKey) mods |= BUTTON_ALT; return mods; } static int mouse_button_from_event(const EventRecord *event) { if (event->modifiers & controlKey) return 2; if (event->modifiers & optionKey) return 1; return 0; } static void local_mouse(const EventRecord *event, Point *local) { *local = event->where; PDC_mac_set_port(); GlobalToLocal(local); } static void queue_mouse(int button, int event_type, const EventRecord *event) { Point local; int x; int y; local_mouse(event, &local); last_mouse_local = local; x = local.h / PDC_font_width; y = local.v / PDC_font_height; if (x < 0) x = 0; if (y < 0) y = 0; if (SP && x >= SP->cols) x = SP->cols - 1; if (SP && y >= SP->lines) y = SP->lines - 1; _add_raw_mouse_event(button, event_type, mouse_modifs(event), x, y); if (_get_mouse_event(NULL)) PDC_mac_add_key(KEY_MOUSE); } static int lookup_special(unsigned char keycode, unsigned long modifiers) { int i; for (i = 0; key_table[i].normal; i++) { if (key_table[i].keycode != keycode) continue; if (modifiers & PDC_KEY_MODIFIER_SHIFT) return key_table[i].shifted; if (modifiers & PDC_KEY_MODIFIER_CONTROL) return key_table[i].control; if (modifiers & PDC_KEY_MODIFIER_ALT) return key_table[i].alt; return key_table[i].normal; } return 0; } static int translate_key(const EventRecord *event) { unsigned char keycode; unsigned char charcode; unsigned long modifiers; int key; keycode = (unsigned char)((event->message & keyCodeMask) >> 8); charcode = (unsigned char)(event->message & charCodeMask); modifiers = modifiers_from_event(event); SP->key_modifiers = modifiers; if (event->what == autoKey) SP->key_modifiers |= PDC_KEY_MODIFIER_REPEAT; if ((event->modifiers & cmdKey) && charcode == 'q') { key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); if (!key) exit(0); return key; } if ((event->modifiers & cmdKey) && charcode == 'c') { key = PDC_get_function_key(FUNCTION_KEY_COPY); if (key) return key; return 3; } if ((event->modifiers & cmdKey) && charcode == 'v') { key = PDC_get_function_key(FUNCTION_KEY_PASTE); if (key) return key; return 22; } if ((event->modifiers & cmdKey) && (charcode == '+' || charcode == '=')) { key = PDC_get_function_key(FUNCTION_KEY_ENLARGE_FONT); if (key) return key; PDC_font_size += 2; if (PDC_font_size > 48) PDC_font_size = 48; PDC_mac_apply_font(); PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 1); return -1; } if ((event->modifiers & cmdKey) && charcode == '-') { key = PDC_get_function_key(FUNCTION_KEY_SHRINK_FONT); if (key) return key; PDC_font_size -= 2; if (PDC_font_size < 6) PDC_font_size = 6; PDC_mac_apply_font(); PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 1); return -1; } key = lookup_special(keycode, modifiers); if (key) return key; if (event->modifiers & cmdKey) return -1; if (charcode >= 32) { #ifdef PDC_WIDE return (int)PDC_macroman_to_unicode(charcode); #else return (int)charcode; #endif } if (charcode > 0) return (int)charcode; return -1; } static void handle_key(EventRecord *event) { int key; if (event->modifiers & cmdKey) { long menuresult; menuresult = MenuKey((short)(event->message & charCodeMask)); if (HiWord(menuresult)) { PDC_mac_handle_menu(menuresult); return; } } if (event->what == keyUp) { unsigned char keycode; keycode = (unsigned char)((event->message & keyCodeMask) >> 8); if (SP && SP->return_key_modifiers) { if (keycode == 0x38 || keycode == 0x3C) PDC_mac_add_key(KEY_SHIFT_L); else if (keycode == 0x3B || keycode == 0x3E) PDC_mac_add_key(KEY_CONTROL_L); else if (keycode == 0x3A || keycode == 0x3D) PDC_mac_add_key(KEY_ALT_L); } prev_special_key = -1; return; } key = translate_key(event); if (key == 3 && SP && !SP->raw_inp) exit(0); if (key > 0) { if (prev_special_key == key) SP->key_modifiers |= PDC_KEY_MODIFIER_REPEAT; prev_special_key = key; PDC_mac_add_key(key); } } static void handle_content_click(EventRecord *event, int pressed) { int button; if (pressed) { button = mouse_button_from_event(event); last_mouse_button = button; queue_mouse(button, BUTTON_PRESSED, event); } else { button = last_mouse_button; queue_mouse(button, BUTTON_RELEASED, event); } } static void handle_mouse_moved(EventRecord *event) { Point local; int x; int y; if (!SP || !SP->_trap_mbe) { PDC_mac_reset_mouse_rgn(); return; } local_mouse(event, &local); if (local.h == last_mouse_local.h && local.v == last_mouse_local.v) { PDC_mac_reset_mouse_rgn(); return; } last_mouse_local = local; x = local.h / PDC_font_width; y = local.v / PDC_font_height; _add_raw_mouse_event(last_mouse_button, BUTTON_MOVED, mouse_modifs(event), x, y); PDC_mac_add_key(KEY_MOUSE); PDC_mac_reset_mouse_rgn(); } static void dispatch_event(EventRecord *event) { WindowPtr which; short part; switch (event->what) { case mouseDown: part = FindWindow(event->where, &which); if (part == inMenuBar) { PDC_mac_handle_menu(MenuSelect(event->where)); break; } #if !TARGET_API_MAC_CARBON if (part == inSysWindow) { SystemClick(event, which); break; } #endif if (which != PDC_window) { if (which) SelectWindow(which); break; } if (part == inDrag) PDC_mac_drag(event); else if (part == inGrow) PDC_mac_grow(event); else if (part == inGoAway) PDC_mac_goaway(event); else if (part == inZoomIn || part == inZoomOut) PDC_mac_zoom(event, part); else if (part == inContent) { SelectWindow(PDC_window); handle_content_click(event, 1); } break; case mouseUp: handle_content_click(event, 0); break; case keyDown: case autoKey: case keyUp: handle_key(event); break; case updateEvt: if ((WindowPtr)event->message == PDC_window) PDC_mac_redraw(); break; case activateEvt: if ((WindowPtr)event->message == PDC_window) { PDC_mac_set_port(); DrawGrowIcon(PDC_window); } break; case osEvt: { unsigned char kind; kind = (unsigned char)((event->message >> 24) & 0xFF); if (kind == mouseMovedMessage) handle_mouse_moved(event); else if (kind == suspendResumeMessage) { #if !TARGET_API_MAC_CARBON if (event->message & resumeFlag) LoadScrap(); else UnloadScrap(); #endif } } break; case kHighLevelEvent: AEProcessAppleEvent(event); break; default: break; } } void PDC_mac_process_events(int sleepticks) { EventRecord event; Boolean got; RgnHandle rgn; rgn = PDC_mouse_rgn; got = WaitNextEvent(everyEvent, &event, sleepticks, rgn); if (got) dispatch_event(&event); while (EventAvail(everyEvent, &event)) { got = WaitNextEvent(everyEvent, &event, 0, rgn); if (!got) break; dispatch_event(&event); } } void PDC_set_keyboard_binary(bool on) { INTENTIONALLY_UNUSED_PARAMETER(on); PDC_LOG(("PDC_set_keyboard_binary() - called\n")); } bool PDC_check_key(void) { PDC_check_for_blinking(); PDC_mac_process_events(0); if (queue_has_key()) return TRUE; return FALSE; } int PDC_get_key(void) { int key; if (!queue_has_key()) PDC_mac_process_events(GetCaretTime()); key = pop_key(); return key; } void PDC_flushinp(void) { PDC_LOG(("PDC_flushinp() - called\n")); PDC_key_queue_head = 0; PDC_key_queue_tail = 0; while (_get_mouse_event(&SP->mouse_status)) ; FlushEvents(keyDownMask | keyUpMask | autoKeyMask | mDownMask | mUpMask, 0); } bool PDC_has_mouse(void) { return TRUE; } int PDC_mouse_set(void) { PDC_mac_reset_mouse_rgn(); return OK; } int PDC_modifiers_set(void) { return OK; } \ No newline at end of file +#include "pdcmac.h" +#include +#include +#include +#include + +int PDC_key_queue[PDC_KEY_QUEUE_SIZE]; +int PDC_key_queue_head = 0; +int PDC_key_queue_tail = 0; + +static int last_mouse_button = 0; +static Point last_mouse_local; +static int prev_special_key = -1; + +static const struct +{ + unsigned char keycode; + unsigned char numkeypad; + unsigned short normal; + unsigned short shifted; + unsigned short control; + unsigned short alt; +} key_table[] = +{ + { 0x7B, 0, KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT }, + { 0x7C, 0, KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT }, + { 0x7E, 0, KEY_UP, KEY_SUP, CTL_UP, ALT_UP }, + { 0x7D, 0, KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN }, + { 0x73, 0, KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME }, + { 0x77, 0, KEY_END, KEY_SEND, CTL_END, ALT_END }, + { 0x74, 0, KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP }, + { 0x79, 0, KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN }, + { 0x72, 0, KEY_IC, KEY_SIC, CTL_INS, ALT_INS }, + { 0x75, 0, KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL }, + { 0x33, 0, 0x08, 0x08, CTL_BKSP, ALT_BKSP }, + { 0x30, 0, 0x09, KEY_BTAB, CTL_TAB, ALT_TAB }, + { 0x35, 0, 0x1B, 0x1B, 0x1B, ALT_ESC }, + { 0x24, 0, 0x0D, 0x0D, 0x0D, 0x0D }, + { 0x4C, 1, PADENTER, PADENTER, CTL_PADENTER, ALT_PADENTER }, + { 0x45, 1, PADPLUS, '+', CTL_PADPLUS, ALT_PADPLUS }, + { 0x4E, 1, PADMINUS, '-', CTL_PADMINUS, ALT_PADMINUS }, + { 0x43, 1, PADSTAR, '*', CTL_PADSTAR, ALT_PADSTAR }, + { 0x4B, 1, PADSLASH, '/', CTL_PADSLASH, ALT_PADSLASH }, + { 0x41, 1, PADSTOP, '.', CTL_PADSTOP, ALT_PADSTOP }, + { 0x52, 1, PAD0, '0', CTL_PAD0, ALT_PAD0 }, + { 0x53, 1, KEY_C1, '1', CTL_PAD1, ALT_PAD1 }, + { 0x54, 1, KEY_C2, '2', CTL_PAD2, ALT_PAD2 }, + { 0x55, 1, KEY_C3, '3', CTL_PAD3, ALT_PAD3 }, + { 0x56, 1, KEY_B1, '4', CTL_PAD4, ALT_PAD4 }, + { 0x57, 1, KEY_B2, '5', CTL_PAD5, ALT_PAD5 }, + { 0x58, 1, KEY_B3, '6', CTL_PAD6, ALT_PAD6 }, + { 0x59, 1, KEY_A1, '7', CTL_PAD7, ALT_PAD7 }, + { 0x5B, 1, KEY_A2, '8', CTL_PAD8, ALT_PAD8 }, + { 0x5C, 1, KEY_A3, '9', CTL_PAD9, ALT_PAD9 }, + { 0x47, 1, KEY_CLEAR, KEY_CLEAR, KEY_CLEAR, KEY_CLEAR }, + { 0x7A, 0, KEY_F(1), KEY_F(13), KEY_F(25), KEY_F(37) }, + { 0x78, 0, KEY_F(2), KEY_F(14), KEY_F(26), KEY_F(38) }, + { 0x63, 0, KEY_F(3), KEY_F(15), KEY_F(27), KEY_F(39) }, + { 0x76, 0, KEY_F(4), KEY_F(16), KEY_F(28), KEY_F(40) }, + { 0x60, 0, KEY_F(5), KEY_F(17), KEY_F(29), KEY_F(41) }, + { 0x61, 0, KEY_F(6), KEY_F(18), KEY_F(30), KEY_F(42) }, + { 0x62, 0, KEY_F(7), KEY_F(19), KEY_F(31), KEY_F(43) }, + { 0x64, 0, KEY_F(8), KEY_F(20), KEY_F(32), KEY_F(44) }, + { 0x65, 0, KEY_F(9), KEY_F(21), KEY_F(33), KEY_F(45) }, + { 0x6D, 0, KEY_F(10), KEY_F(22), KEY_F(34), KEY_F(46) }, + { 0x67, 0, KEY_F(11), KEY_F(23), KEY_F(35), KEY_F(47) }, + { 0x6F, 0, KEY_F(12), KEY_F(24), KEY_F(36), KEY_F(48) }, + { 0x69, 0, KEY_F(13), KEY_F(25), KEY_F(37), KEY_F(49) }, + { 0x6B, 0, KEY_F(14), KEY_F(26), KEY_F(38), KEY_F(50) }, + { 0x71, 0, KEY_F(15), KEY_F(27), KEY_F(39), KEY_F(51) }, + { 0, 0, 0, 0, 0, 0 } +}; + +void PDC_mac_add_key(int key) +{ + int next; + + if (!key) + return; + next = PDC_key_queue_tail + 1; + if (next >= PDC_KEY_QUEUE_SIZE) + next = 0; + if (next == PDC_key_queue_head) + return; + if (key == KEY_RESIZE) + { + int i; + + i = PDC_key_queue_head; + while (i != PDC_key_queue_tail) + { + if (PDC_key_queue[i] == KEY_RESIZE) + return; + i++; + if (i >= PDC_KEY_QUEUE_SIZE) + i = 0; + } + if (SP) + SP->resized = TRUE; + } + PDC_key_queue[PDC_key_queue_tail] = key; + PDC_key_queue_tail = next; +} + +static int queue_has_key(void) +{ + if (PDC_key_queue_head != PDC_key_queue_tail) + return 1; + return 0; +} + +static int pop_key(void) +{ + int key; + + if (PDC_key_queue_head == PDC_key_queue_tail) + return -1; + key = PDC_key_queue[PDC_key_queue_head]; + PDC_key_queue_head++; + if (PDC_key_queue_head >= PDC_KEY_QUEUE_SIZE) + PDC_key_queue_head = 0; + if (key == KEY_MOUSE) + _get_mouse_event(&SP->mouse_status); + return key; +} + +static unsigned long modifiers_from_event(const EventRecord *event) +{ + unsigned long mods; + + mods = 0; + if (event->modifiers & shiftKey) + mods |= PDC_KEY_MODIFIER_SHIFT; + if (event->modifiers & controlKey) + mods |= PDC_KEY_MODIFIER_CONTROL; + if (event->modifiers & optionKey) + mods |= PDC_KEY_MODIFIER_ALT; + if (event->modifiers & cmdKey) + mods |= PDC_KEY_MODIFIER_SUPER; + if (event->modifiers & alphaLock) + mods |= PDC_KEY_MODIFIER_CAPSLOCK; + return mods; +} + +static int mouse_modifs(const EventRecord *event) +{ + int mods; + + mods = 0; + if (event->modifiers & shiftKey) + mods |= BUTTON_SHIFT; + if (event->modifiers & controlKey) + mods |= BUTTON_CONTROL; + if (event->modifiers & optionKey) + mods |= BUTTON_ALT; + return mods; +} + +static int mouse_button_from_event(const EventRecord *event) +{ + if (event->modifiers & controlKey) + return 2; + if (event->modifiers & optionKey) + return 1; + return 0; +} + +static void local_mouse(const EventRecord *event, Point *local) +{ + *local = event->where; + PDC_mac_set_port(); + GlobalToLocal(local); +} + +static void queue_mouse(int button, int event_type, const EventRecord *event) +{ + Point local; + int x; + int y; + + local_mouse(event, &local); + last_mouse_local = local; + x = local.h / PDC_font_width; + y = local.v / PDC_font_height; + if (x < 0) + x = 0; + if (y < 0) + y = 0; + if (SP && x >= SP->cols) + x = SP->cols - 1; + if (SP && y >= SP->lines) + y = SP->lines - 1; + _add_raw_mouse_event(button, event_type, mouse_modifs(event), x, y); + if (_get_mouse_event(NULL)) + PDC_mac_add_key(KEY_MOUSE); +} + +static int lookup_special(unsigned char keycode, unsigned long modifiers) +{ + int i; + + for (i = 0; key_table[i].normal; i++) + { + if (key_table[i].keycode != keycode) + continue; + if (modifiers & PDC_KEY_MODIFIER_SHIFT) + return key_table[i].shifted; + if (modifiers & PDC_KEY_MODIFIER_CONTROL) + return key_table[i].control; + if (modifiers & PDC_KEY_MODIFIER_ALT) + return key_table[i].alt; + return key_table[i].normal; + } + return 0; +} + +static int translate_key(const EventRecord *event) +{ + unsigned char keycode; + unsigned char charcode; + unsigned long modifiers; + int key; + + keycode = (unsigned char)((event->message & keyCodeMask) >> 8); + charcode = (unsigned char)(event->message & charCodeMask); + modifiers = modifiers_from_event(event); + SP->key_modifiers = modifiers; + if (event->what == autoKey) + SP->key_modifiers |= PDC_KEY_MODIFIER_REPEAT; + if ((event->modifiers & cmdKey) && charcode == 'q') + { + key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); + if (!key) + exit(0); + return key; + } + if ((event->modifiers & cmdKey) && charcode == 'c') + { + key = PDC_get_function_key(FUNCTION_KEY_COPY); + if (key) + return key; + return 3; + } + if ((event->modifiers & cmdKey) && charcode == 'v') + { + key = PDC_get_function_key(FUNCTION_KEY_PASTE); + if (key) + return key; + return 22; + } + if ((event->modifiers & cmdKey) && (charcode == '+' || charcode == '=')) + { + key = PDC_get_function_key(FUNCTION_KEY_ENLARGE_FONT); + if (key) + return key; + PDC_font_size += 2; + if (PDC_font_size > 48) + PDC_font_size = 48; + PDC_mac_apply_font(); + PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 1); + return -1; + } + if ((event->modifiers & cmdKey) && charcode == '-') + { + key = PDC_get_function_key(FUNCTION_KEY_SHRINK_FONT); + if (key) + return key; + PDC_font_size -= 2; + if (PDC_font_size < 6) + PDC_font_size = 6; + PDC_mac_apply_font(); + PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 1); + return -1; + } + key = lookup_special(keycode, modifiers); + if (key) + return key; + if (event->modifiers & cmdKey) + return -1; + if (charcode >= 32) + { +#ifdef PDC_WIDE + return (int)PDC_macroman_to_unicode(charcode); +#else + return (int)charcode; +#endif + } + if (charcode > 0) + return (int)charcode; + return -1; +} + +static void handle_key(EventRecord *event) +{ + int key; + + if (event->modifiers & cmdKey) + { + long menuresult; + + menuresult = MenuKey((short)(event->message & charCodeMask)); + if (HiWord(menuresult)) + { + PDC_mac_handle_menu(menuresult); + return; + } + } + if (event->what == keyUp) + { + unsigned char keycode; + + keycode = (unsigned char)((event->message & keyCodeMask) >> 8); + if (SP && SP->return_key_modifiers) + { + if (keycode == 0x38 || keycode == 0x3C) + PDC_mac_add_key(KEY_SHIFT_L); + else if (keycode == 0x3B || keycode == 0x3E) + PDC_mac_add_key(KEY_CONTROL_L); + else if (keycode == 0x3A || keycode == 0x3D) + PDC_mac_add_key(KEY_ALT_L); + } + prev_special_key = -1; + return; + } + key = translate_key(event); + if (key == 3 && SP && !SP->raw_inp) + exit(0); + if (key > 0) + { + if (prev_special_key == key) + SP->key_modifiers |= PDC_KEY_MODIFIER_REPEAT; + prev_special_key = key; + PDC_mac_add_key(key); + } +} + +static void handle_content_click(EventRecord *event, int pressed) +{ + int button; + + if (pressed) + { + button = mouse_button_from_event(event); + last_mouse_button = button; + queue_mouse(button, BUTTON_PRESSED, event); + } + else + { + button = last_mouse_button; + queue_mouse(button, BUTTON_RELEASED, event); + } +} + +static void handle_mouse_moved(EventRecord *event) +{ + Point local; + int x; + int y; + + if (!SP || !SP->_trap_mbe) + { + PDC_mac_reset_mouse_rgn(); + return; + } + local_mouse(event, &local); + if (local.h == last_mouse_local.h && local.v == last_mouse_local.v) + { + PDC_mac_reset_mouse_rgn(); + return; + } + last_mouse_local = local; + x = local.h / PDC_font_width; + y = local.v / PDC_font_height; + _add_raw_mouse_event(last_mouse_button, BUTTON_MOVED, mouse_modifs(event), x, y); + PDC_mac_add_key(KEY_MOUSE); + PDC_mac_reset_mouse_rgn(); +} + +static void dispatch_event(EventRecord *event) +{ + WindowPtr which; + short part; + + switch (event->what) + { + case mouseDown: + part = FindWindow(event->where, &which); + if (part == inMenuBar) + { + PDC_mac_handle_menu(MenuSelect(event->where)); + break; + } +#if !TARGET_API_MAC_CARBON + if (part == inSysWindow) + { + SystemClick(event, which); + break; + } +#endif + if (which != PDC_window) + { + if (which) + SelectWindow(which); + break; + } + if (part == inDrag) + PDC_mac_drag(event); + else if (part == inGrow) + PDC_mac_grow(event); + else if (part == inGoAway) + PDC_mac_goaway(event); + else if (part == inZoomIn || part == inZoomOut) + PDC_mac_zoom(event, part); + else if (part == inContent) + { + SelectWindow(PDC_window); + handle_content_click(event, 1); + } + break; + case mouseUp: + handle_content_click(event, 0); + break; + case keyDown: + case autoKey: + case keyUp: + handle_key(event); + break; + case updateEvt: + if ((WindowPtr)event->message == PDC_window) + PDC_mac_redraw(); + break; + case activateEvt: + if ((WindowPtr)event->message == PDC_window) + { + PDC_mac_set_port(); + DrawGrowIcon(PDC_window); + } + break; + case osEvt: + { + unsigned char kind; + + kind = (unsigned char)((event->message >> 24) & 0xFF); + if (kind == mouseMovedMessage) + handle_mouse_moved(event); + else if (kind == suspendResumeMessage) + { +#if !TARGET_API_MAC_CARBON + if (event->message & resumeFlag) + LoadScrap(); + else + UnloadScrap(); +#endif + } + } + break; + case kHighLevelEvent: + AEProcessAppleEvent(event); + break; + default: + break; + } +} + +void PDC_mac_process_events(int sleepticks) +{ + EventRecord event; + Boolean got; + RgnHandle rgn; + + rgn = PDC_mouse_rgn; + got = WaitNextEvent(everyEvent, &event, sleepticks, rgn); + if (got) + dispatch_event(&event); + while (EventAvail(everyEvent, &event)) + { + got = WaitNextEvent(everyEvent, &event, 0, rgn); + if (!got) + break; + dispatch_event(&event); + } +} + +void PDC_set_keyboard_binary(bool on) +{ + INTENTIONALLY_UNUSED_PARAMETER(on); + PDC_LOG(("PDC_set_keyboard_binary() - called\n")); +} + +bool PDC_check_key(void) +{ + PDC_check_for_blinking(); + PDC_mac_process_events(0); + if (queue_has_key()) + return TRUE; + return FALSE; +} + +int PDC_get_key(void) +{ + int key; + + if (!queue_has_key()) + PDC_mac_process_events(GetCaretTime()); + key = pop_key(); + return key; +} + +void PDC_flushinp(void) +{ + PDC_LOG(("PDC_flushinp() - called\n")); + PDC_key_queue_head = 0; + PDC_key_queue_tail = 0; + while (_get_mouse_event(&SP->mouse_status)) + ; + FlushEvents(keyDownMask | keyUpMask | autoKeyMask | mDownMask | mUpMask, 0); +} + +bool PDC_has_mouse(void) +{ + return TRUE; +} + +int PDC_mouse_set(void) +{ + PDC_mac_reset_mouse_rgn(); + return OK; +} + +int PDC_modifiers_set(void) +{ + return OK; +} diff --git a/mac/pdcmac.h b/mac/pdcmac.h index 7553ead7..db59bfce 100644 --- a/mac/pdcmac.h +++ b/mac/pdcmac.h @@ -1 +1,145 @@ -#ifndef PDC_MAC_H #define PDC_MAC_H 1 #ifndef TARGET_API_MAC_CARBON # ifdef TARGET_CARBON # define TARGET_API_MAC_CARBON TARGET_CARBON # else # define TARGET_API_MAC_CARBON 0 # endif #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #undef MOUSE_MOVED #include #ifndef kScrapFlavorTypeText #define kScrapFlavorTypeText 'TEXT' #endif #ifndef zoomDocProc #define zoomDocProc 8 #endif #ifndef monaco #define monaco 4 #endif #ifndef bold #define bold 1 #endif #ifndef italic #define italic 2 #endif #ifndef everyEvent #define everyEvent 0xFFFF #endif #ifndef mouseMovedMessage #define mouseMovedMessage 0xFA #endif #ifndef suspendResumeMessage #define suspendResumeMessage 1 #endif #ifndef resumeFlag #define resumeFlag 1 #endif #ifndef kHighLevelEvent #define kHighLevelEvent 23 #endif #ifndef gestaltAppleEventsPresent #define gestaltAppleEventsPresent 0 #endif #ifndef noTypeErr #define noTypeErr -204 #endif #ifndef memFullErr #define memFullErr -108 #endif #ifndef charCodeMask #define charCodeMask 0x000000FF #endif #ifndef keyCodeMask #define keyCodeMask 0x0000FF00 #endif #ifndef activeFlag #define activeFlag 0x0001 #endif #define PDC_KEY_QUEUE_SIZE 64 extern WindowPtr PDC_window; extern int PDC_rows; extern int PDC_cols; extern int PDC_font_width; extern int PDC_font_height; extern int PDC_font_ascent; extern int PDC_font_size; extern int PDC_key_queue[PDC_KEY_QUEUE_SIZE]; extern int PDC_key_queue_head; extern int PDC_key_queue_tail; extern RgnHandle PDC_mouse_rgn; extern int PDC_min_lines; extern int PDC_max_lines; extern int PDC_min_cols; extern int PDC_max_cols; #define PDC_MENU_APPLE 128 #define PDC_MENU_FILE 129 #define PDC_MENU_EDIT 130 #define PDC_ITEM_QUIT 1 #define PDC_ITEM_CUT 1 #define PDC_ITEM_COPY 2 #define PDC_ITEM_PASTE 3 #define PDC_ITEM_CLEAR 4 void PDC_mac_set_port(void); void PDC_mac_port_bounds(Rect *bounds); void PDC_mac_invalidate(const Rect *bounds); void PDC_mac_invalidate_all(void); void PDC_mac_cell_rect(int row, int col, Rect *cell); void PDC_mac_add_key(int key); void PDC_mac_process_events(int sleepticks); void PDC_mac_apply_font(void); void PDC_mac_reset_mouse_rgn(void); void PDC_mac_drag(EventRecord *event); void PDC_mac_grow(EventRecord *event); void PDC_mac_zoom(EventRecord *event, short part); void PDC_mac_goaway(EventRecord *event); void PDC_mac_redraw(void); void PDC_mac_handle_menu(long menuresult); void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize); unsigned short PDC_macroman_to_unicode(unsigned char ch); unsigned char PDC_unicode_to_macroman(unsigned long code); void PDC_check_for_blinking(void); #endif \ No newline at end of file +#ifndef PDC_MAC_H +#define PDC_MAC_H 1 + +#ifndef TARGET_API_MAC_CARBON +# ifdef TARGET_CARBON +# define TARGET_API_MAC_CARBON TARGET_CARBON +# else +# define TARGET_API_MAC_CARBON 0 +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef MOUSE_MOVED +#include + +#ifndef kScrapFlavorTypeText +#define kScrapFlavorTypeText 'TEXT' +#endif + +#ifndef zoomDocProc +#define zoomDocProc 8 +#endif + +#ifndef monaco +#define monaco 4 +#endif + +#ifndef bold +#define bold 1 +#endif + +#ifndef italic +#define italic 2 +#endif + +#ifndef everyEvent +#define everyEvent 0xFFFF +#endif + +#ifndef mouseMovedMessage +#define mouseMovedMessage 0xFA +#endif + +#ifndef suspendResumeMessage +#define suspendResumeMessage 1 +#endif + +#ifndef resumeFlag +#define resumeFlag 1 +#endif + +#ifndef kHighLevelEvent +#define kHighLevelEvent 23 +#endif + +#ifndef gestaltAppleEventsPresent +#define gestaltAppleEventsPresent 0 +#endif + +#ifndef noTypeErr +#define noTypeErr -204 +#endif + +#ifndef memFullErr +#define memFullErr -108 +#endif + +#ifndef charCodeMask +#define charCodeMask 0x000000FF +#endif + +#ifndef keyCodeMask +#define keyCodeMask 0x0000FF00 +#endif + +#ifndef activeFlag +#define activeFlag 0x0001 +#endif + +#define PDC_KEY_QUEUE_SIZE 64 + +extern WindowPtr PDC_window; +extern int PDC_rows; +extern int PDC_cols; +extern int PDC_font_width; +extern int PDC_font_height; +extern int PDC_font_ascent; +extern int PDC_font_size; +extern int PDC_key_queue[PDC_KEY_QUEUE_SIZE]; +extern int PDC_key_queue_head; +extern int PDC_key_queue_tail; +extern RgnHandle PDC_mouse_rgn; +extern int PDC_min_lines; +extern int PDC_max_lines; +extern int PDC_min_cols; +extern int PDC_max_cols; + +#define PDC_MENU_APPLE 128 +#define PDC_MENU_FILE 129 +#define PDC_MENU_EDIT 130 +#define PDC_ITEM_QUIT 1 +#define PDC_ITEM_CUT 1 +#define PDC_ITEM_COPY 2 +#define PDC_ITEM_PASTE 3 +#define PDC_ITEM_CLEAR 4 + +void PDC_mac_set_port(void); +void PDC_mac_port_bounds(Rect *bounds); +void PDC_mac_invalidate(const Rect *bounds); +void PDC_mac_invalidate_all(void); +void PDC_mac_cell_rect(int row, int col, Rect *cell); +void PDC_mac_add_key(int key); +void PDC_mac_process_events(int sleepticks); +void PDC_mac_apply_font(void); +void PDC_mac_reset_mouse_rgn(void); +void PDC_mac_drag(EventRecord *event); +void PDC_mac_grow(EventRecord *event); +void PDC_mac_zoom(EventRecord *event, short part); +void PDC_mac_goaway(EventRecord *event); +void PDC_mac_redraw(void); +void PDC_mac_handle_menu(long menuresult); +void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize); +unsigned short PDC_macroman_to_unicode(unsigned char ch); +unsigned char PDC_unicode_to_macroman(unsigned long code); + +void PDC_check_for_blinking(void); + +#endif diff --git a/mac/pdcscrn.c b/mac/pdcscrn.c index b867c071..3ed52bcd 100644 --- a/mac/pdcscrn.c +++ b/mac/pdcscrn.c @@ -1 +1,577 @@ -#include "pdcmac.h" #include #include #include #include #if UNIVERSAL_INTERFACES_VERSION >= 0x0340 #define AEEVENTCBPARAM3 long #else #define AEEVENTCBPARAM3 UInt32 #endif WindowPtr PDC_window = NULL; int PDC_rows = 25; int PDC_cols = 80; int PDC_font_width = 6; int PDC_font_height = 12; int PDC_font_ascent = 9; int PDC_font_size = 12; RgnHandle PDC_mouse_rgn = NULL; int PDC_min_lines = 2; int PDC_max_lines = 200; int PDC_min_cols = 2; int PDC_max_cols = 300; static int toolbox_ready = 0; static int initial_rows = 0; static int initial_cols = 0; static MenuHandle apple_menu; static MenuHandle file_menu; static MenuHandle edit_menu; static void c_to_pstr(const char *src, Str255 dst) { unsigned int length; unsigned int i; length = 0; while (src[length] != 0 && length < 255) length++; dst[0] = (unsigned char)length; for (i = 0; i < length; i++) dst[i + 1] = (unsigned char)src[i]; } void PDC_mac_set_port(void) { if (!PDC_window) return; #if TARGET_API_MAC_CARBON SetPortWindowPort(PDC_window); #else SetPort((GrafPtr)PDC_window); #endif } void PDC_mac_port_bounds(Rect *bounds) { #if TARGET_API_MAC_CARBON || ACCESSOR_CALLS_ARE_FUNCTIONS GetWindowPortBounds(PDC_window, bounds); #else *bounds = PDC_window->portRect; #endif } void PDC_mac_invalidate(const Rect *bounds) { PDC_mac_set_port(); #if TARGET_API_MAC_CARBON InvalWindowRect(PDC_window, (Rect *)bounds); #else InvalRect((Rect *)bounds); #endif } void PDC_mac_invalidate_all(void) { Rect bounds; PDC_mac_port_bounds(&bounds); PDC_mac_invalidate(&bounds); } void PDC_mac_cell_rect(int row, int col, Rect *cell) { cell->left = (short)(col * PDC_font_width); cell->top = (short)(row * PDC_font_height); cell->right = (short)(cell->left + PDC_font_width); cell->bottom = (short)(cell->top + PDC_font_height); } void PDC_mac_reset_mouse_rgn(void) { Point pt; Rect r; if (!PDC_mouse_rgn) return; #if TARGET_API_MAC_CARBON GetGlobalMouse(&pt); #else GetMouse(&pt); PDC_mac_set_port(); LocalToGlobal(&pt); #endif SetRect(&r, pt.h, pt.v, pt.h + 1, pt.v + 1); RectRgn(PDC_mouse_rgn, &r); } void PDC_mac_apply_font(void) { FontInfo info; PDC_mac_set_port(); TextFont(monaco); TextFace(0); TextSize(PDC_font_size); GetFontInfo(&info); PDC_font_ascent = info.ascent; PDC_font_height = info.ascent + info.descent + info.leading; PDC_font_width = CharWidth('M'); if (PDC_font_width < 1) PDC_font_width = CharWidth('W'); if (PDC_font_width < 1) PDC_font_width = PDC_font_size / 2 + 1; if (PDC_font_height < 1) PDC_font_height = PDC_font_size + 2; } static void screen_work_rect(Rect *bounds) { #if TARGET_API_MAC_CARBON BitMap screenbits; GetQDGlobalsScreenBits(&screenbits); *bounds = screenbits.bounds; #else *bounds = qd.screenBits.bounds; #endif bounds->top = (short)(bounds->top + GetMBarHeight()); } void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize) { int rows; int cols; Rect limits; cols = pixelwidth / PDC_font_width; rows = pixelheight / PDC_font_height; if (cols < PDC_min_cols) cols = PDC_min_cols; if (rows < PDC_min_lines) rows = PDC_min_lines; if (cols > PDC_max_cols) cols = PDC_max_cols; if (rows > PDC_max_lines) rows = PDC_max_lines; if (cols < 2) cols = 2; if (rows < 2) rows = 2; SizeWindow(PDC_window, (short)(cols * PDC_font_width), (short)(rows * PDC_font_height), TRUE); if (PDC_cols != cols || PDC_rows != rows) { PDC_cols = cols; PDC_rows = rows; if (queue_resize) PDC_mac_add_key(KEY_RESIZE); } PDC_mac_port_bounds(&limits); PDC_mac_invalidate(&limits); PDC_mac_set_port(); DrawGrowIcon(PDC_window); } void PDC_mac_drag(EventRecord *event) { Rect screen; screen_work_rect(&screen); DragWindow(PDC_window, event->where, &screen); } void PDC_mac_grow(EventRecord *event) { Rect limits; long grow; SetRect(&limits, (short)(PDC_min_cols * PDC_font_width), (short)(PDC_min_lines * PDC_font_height), (short)(PDC_max_cols * PDC_font_width), (short)(PDC_max_lines * PDC_font_height)); grow = GrowWindow(PDC_window, event->where, &limits); if (grow) PDC_mac_adjust_size(LoWord(grow), HiWord(grow), 1); } void PDC_mac_zoom(EventRecord *event, short part) { Rect bounds; if (!TrackBox(PDC_window, event->where, part)) return; ZoomWindow(PDC_window, part, TRUE); PDC_mac_port_bounds(&bounds); PDC_mac_adjust_size(bounds.right - bounds.left, bounds.bottom - bounds.top, 1); } void PDC_mac_goaway(EventRecord *event) { int key; if (!TrackGoAway(PDC_window, event->where)) return; key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); if (!key) exit(0); PDC_mac_add_key(key); } void PDC_mac_redraw(void) { Rect bounds; int y; BeginUpdate(PDC_window); PDC_mac_set_port(); PDC_mac_port_bounds(&bounds); EraseRect(&bounds); if (curscr && SP) { int cols; cols = SP->cols; if (cols > PDC_cols) cols = PDC_cols; for (y = 0; y < SP->lines && y < PDC_rows; y++) { if (curscr->_y[y]) PDC_transform_line(y, 0, cols, curscr->_y[y]); } } DrawGrowIcon(PDC_window); EndUpdate(PDC_window); } void PDC_mac_handle_menu(long menuresult) { short menuid; short item; int key; menuid = HiWord(menuresult); item = LoWord(menuresult); if (menuid == PDC_MENU_FILE && item == PDC_ITEM_QUIT) { key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); if (!key) exit(0); PDC_mac_add_key(key); } else if (menuid == PDC_MENU_EDIT) { if (item == PDC_ITEM_COPY) { key = PDC_get_function_key(FUNCTION_KEY_COPY); if (!key) key = 3; PDC_mac_add_key(key); } else if (item == PDC_ITEM_PASTE) { key = PDC_get_function_key(FUNCTION_KEY_PASTE); if (!key) key = 22; PDC_mac_add_key(key); } else if (item == PDC_ITEM_CLEAR) PDC_clearclipboard(); } #if !TARGET_API_MAC_CARBON else if (menuid == PDC_MENU_APPLE && item > 1) { Str255 name; GetMenuItemText(apple_menu, item, name); OpenDeskAcc(name); } #endif HiliteMenu(0); } static pascal OSErr ae_quit(const AppleEvent *evt, AppleEvent *reply, AEEVENTCBPARAM3 refcon) { int key; INTENTIONALLY_UNUSED_PARAMETER(evt); INTENTIONALLY_UNUSED_PARAMETER(reply); INTENTIONALLY_UNUSED_PARAMETER(refcon); key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); if (!key) exit(0); PDC_mac_add_key(key); return noErr; } static void init_toolbox(void) { if (toolbox_ready) return; #if TARGET_API_MAC_CARBON InitCursor(); #else MaxApplZone(); MoreMasters(); MoreMasters(); InitGraf(&qd.thePort); InitFonts(); FlushEvents(everyEvent, 0); InitWindows(); InitMenus(); TEInit(); InitDialogs(NULL); InitCursor(); #endif toolbox_ready = 1; } static void init_menus(void) { Str255 title; title[0] = 1; title[1] = 0x14; apple_menu = NewMenu(PDC_MENU_APPLE, title); c_to_pstr("About PDCursesMod", title); AppendMenu(apple_menu, title); #if !TARGET_API_MAC_CARBON c_to_pstr("(-", title); AppendMenu(apple_menu, title); AppendResMenu(apple_menu, 'DRVR'); #endif c_to_pstr("File", title); file_menu = NewMenu(PDC_MENU_FILE, title); c_to_pstr("Quit/Q", title); AppendMenu(file_menu, title); c_to_pstr("Edit", title); edit_menu = NewMenu(PDC_MENU_EDIT, title); c_to_pstr("Cut/X;Copy/C;Paste/V;Clear", title); AppendMenu(edit_menu, title); InsertMenu(apple_menu, 0); InsertMenu(file_menu, 0); InsertMenu(edit_menu, 0); DrawMenuBar(); } static void install_apple_events(void) { #if TARGET_API_MAC_CARBON AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(ae_quit), 0, FALSE); #else { long attr; if (Gestalt(gestaltAppleEventsAttr, &attr) == noErr) { if (attr & (1L << gestaltAppleEventsPresent)) AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(ae_quit), 0, FALSE); } } #endif } static WindowPtr create_window(void) { Rect screen; Rect bounds; Str255 title; int width; int height; int left; int top; WindowPtr window; screen_work_rect(&screen); width = PDC_cols * PDC_font_width; height = PDC_rows * PDC_font_height; if (width > screen.right - screen.left - 8) width = screen.right - screen.left - 8; if (height > screen.bottom - screen.top - 8) height = screen.bottom - screen.top - 8; left = screen.left + (screen.right - screen.left - width) / 2; top = screen.top + 16; SetRect(&bounds, (short)left, (short)top, (short)(left + width), (short)(top + height)); c_to_pstr("PDCursesMod", title); window = NewCWindow(NULL, &bounds, title, FALSE, zoomDocProc, (WindowPtr)-1L, TRUE, 0); return window; } void PDC_scr_close(void) { PDC_LOG(("PDC_scr_close() - called\n")); } void PDC_scr_free(void) { PDC_free_palette(); if (PDC_window) { DisposeWindow(PDC_window); PDC_window = NULL; } if (PDC_mouse_rgn) { DisposeRgn(PDC_mouse_rgn); PDC_mouse_rgn = NULL; } #ifdef USING_COMBINING_CHARACTER_SCHEME PDC_expand_combined_characters(0, NULL); #endif } int PDC_scr_open(void) { const char *env; PDC_LOG(("PDC_scr_open() - called\n")); if (!SP) return ERR; if (PDC_init_palette()) return ERR; init_toolbox(); env = getenv("PDC_FONT_SIZE"); if (env) PDC_font_size = atoi(env); if (PDC_font_size < 6) PDC_font_size = 12; env = getenv("PDC_LINES"); if (env) PDC_rows = atoi(env); env = getenv("PDC_COLS"); if (env) PDC_cols = atoi(env); if (initial_rows > 1) PDC_rows = initial_rows; if (initial_cols > 1) PDC_cols = initial_cols; if (PDC_rows < 2) PDC_rows = 25; if (PDC_cols < 2) PDC_cols = 80; if (!PDC_window) { PDC_font_width = PDC_font_size / 2 + 1; PDC_font_height = PDC_font_size + 3; PDC_font_ascent = PDC_font_size - 2; PDC_window = create_window(); if (!PDC_window) return ERR; init_menus(); install_apple_events(); PDC_mouse_rgn = NewRgn(); ShowWindow(PDC_window); SelectWindow(PDC_window); PDC_mac_set_port(); PDC_mac_apply_font(); PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 0); PDC_mac_reset_mouse_rgn(); } SP->mouse_wait = PDC_CLICK_PERIOD; SP->audible = TRUE; SP->mono = FALSE; SP->orig_attr = TRUE; SP->orig_fore = COLOR_WHITE; SP->orig_back = COLOR_BLACK; SP->termattrs = A_COLOR | A_UNDERLINE | A_LEFT | A_RIGHT | A_REVERSE | A_STRIKEOUT | A_TOP | A_BLINK | A_DIM | A_BOLD | A_ITALIC; SP->lines = PDC_rows; SP->cols = PDC_cols; COLORS = 256 + (256 * 256 * 256); PDC_reset_prog_mode(); return OK; } int PDC_resize_screen(int nlines, int ncols) { if (!stdscr) { if (nlines > 1) initial_rows = nlines; if (ncols > 1) initial_cols = ncols; if (nlines > 1) PDC_rows = nlines; if (ncols > 1) PDC_cols = ncols; return OK; } if (nlines > 1 && ncols > 1) PDC_mac_adjust_size(ncols * PDC_font_width, nlines * PDC_font_height, 0); return OK; } void PDC_reset_prog_mode(void) { PDC_LOG(("PDC_reset_prog_mode() - called.\n")); if (PDC_window) { ShowWindow(PDC_window); SelectWindow(PDC_window); PDC_mac_set_port(); } } void PDC_reset_shell_mode(void) { PDC_LOG(("PDC_reset_shell_mode() - called.\n")); } void PDC_restore_screen_mode(int i) { INTENTIONALLY_UNUSED_PARAMETER(i); } void PDC_save_screen_mode(int i) { INTENTIONALLY_UNUSED_PARAMETER(i); } void PDC_set_resize_limits(const int new_min_lines, const int new_max_lines, const int new_min_cols, const int new_max_cols) { PDC_min_lines = new_min_lines; PDC_max_lines = new_max_lines; PDC_min_cols = new_min_cols; PDC_max_cols = new_max_cols; if (PDC_min_lines < 2) PDC_min_lines = 2; if (PDC_min_cols < 2) PDC_min_cols = 2; } bool PDC_can_change_color(void) { return TRUE; } int PDC_color_content(int color, int *red, int *green, int *blue) { const PACKED_RGB col = PDC_get_palette_entry(color); *red = DIVROUND(Get_RValue(col) * 1000, 255); *green = DIVROUND(Get_GValue(col) * 1000, 255); *blue = DIVROUND(Get_BValue(col) * 1000, 255); return OK; } int PDC_init_color(int color, int red, int green, int blue) { const PACKED_RGB new_rgb = PACK_RGB(DIVROUND(red * 255, 1000), DIVROUND(green * 255, 1000), DIVROUND(blue * 255, 1000)); if (!PDC_set_palette_entry(color, new_rgb)) { if (curscr) curscr->_clear = TRUE; } return OK; } \ No newline at end of file +#include "pdcmac.h" +#include +#include +#include +#include + +#if UNIVERSAL_INTERFACES_VERSION >= 0x0340 + #define AEEVENTCBPARAM3 long +#else + #define AEEVENTCBPARAM3 UInt32 +#endif + +WindowPtr PDC_window = NULL; +int PDC_rows = 25; +int PDC_cols = 80; +int PDC_font_width = 6; +int PDC_font_height = 12; +int PDC_font_ascent = 9; +int PDC_font_size = 12; +RgnHandle PDC_mouse_rgn = NULL; +int PDC_min_lines = 2; +int PDC_max_lines = 200; +int PDC_min_cols = 2; +int PDC_max_cols = 300; + +static int toolbox_ready = 0; +static int initial_rows = 0; +static int initial_cols = 0; +static MenuHandle apple_menu; +static MenuHandle file_menu; +static MenuHandle edit_menu; + +static void c_to_pstr(const char *src, Str255 dst) +{ + unsigned int length; + unsigned int i; + + length = 0; + while (src[length] != 0 && length < 255) + length++; + dst[0] = (unsigned char)length; + for (i = 0; i < length; i++) + dst[i + 1] = (unsigned char)src[i]; +} + +void PDC_mac_set_port(void) +{ + if (!PDC_window) + return; +#if TARGET_API_MAC_CARBON + SetPortWindowPort(PDC_window); +#else + SetPort((GrafPtr)PDC_window); +#endif +} + +void PDC_mac_port_bounds(Rect *bounds) +{ +#if TARGET_API_MAC_CARBON || ACCESSOR_CALLS_ARE_FUNCTIONS + GetWindowPortBounds(PDC_window, bounds); +#else + *bounds = PDC_window->portRect; +#endif +} + +void PDC_mac_invalidate(const Rect *bounds) +{ + PDC_mac_set_port(); +#if TARGET_API_MAC_CARBON + InvalWindowRect(PDC_window, (Rect *)bounds); +#else + InvalRect((Rect *)bounds); +#endif +} + +void PDC_mac_invalidate_all(void) +{ + Rect bounds; + + PDC_mac_port_bounds(&bounds); + PDC_mac_invalidate(&bounds); +} + +void PDC_mac_cell_rect(int row, int col, Rect *cell) +{ + cell->left = (short)(col * PDC_font_width); + cell->top = (short)(row * PDC_font_height); + cell->right = (short)(cell->left + PDC_font_width); + cell->bottom = (short)(cell->top + PDC_font_height); +} + +void PDC_mac_reset_mouse_rgn(void) +{ + Point pt; + Rect r; + + if (!PDC_mouse_rgn) + return; +#if TARGET_API_MAC_CARBON + GetGlobalMouse(&pt); +#else + GetMouse(&pt); + PDC_mac_set_port(); + LocalToGlobal(&pt); +#endif + SetRect(&r, pt.h, pt.v, pt.h + 1, pt.v + 1); + RectRgn(PDC_mouse_rgn, &r); +} + +void PDC_mac_apply_font(void) +{ + FontInfo info; + + PDC_mac_set_port(); + TextFont(monaco); + TextFace(0); + TextSize(PDC_font_size); + GetFontInfo(&info); + PDC_font_ascent = info.ascent; + PDC_font_height = info.ascent + info.descent + info.leading; + PDC_font_width = CharWidth('M'); + if (PDC_font_width < 1) + PDC_font_width = CharWidth('W'); + if (PDC_font_width < 1) + PDC_font_width = PDC_font_size / 2 + 1; + if (PDC_font_height < 1) + PDC_font_height = PDC_font_size + 2; +} + +static void screen_work_rect(Rect *bounds) +{ +#if TARGET_API_MAC_CARBON + BitMap screenbits; + + GetQDGlobalsScreenBits(&screenbits); + *bounds = screenbits.bounds; +#else + *bounds = qd.screenBits.bounds; +#endif + bounds->top = (short)(bounds->top + GetMBarHeight()); +} + +void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize) +{ + int rows; + int cols; + Rect limits; + + cols = pixelwidth / PDC_font_width; + rows = pixelheight / PDC_font_height; + if (cols < PDC_min_cols) + cols = PDC_min_cols; + if (rows < PDC_min_lines) + rows = PDC_min_lines; + if (cols > PDC_max_cols) + cols = PDC_max_cols; + if (rows > PDC_max_lines) + rows = PDC_max_lines; + if (cols < 2) + cols = 2; + if (rows < 2) + rows = 2; + SizeWindow(PDC_window, (short)(cols * PDC_font_width), + (short)(rows * PDC_font_height), TRUE); + if (PDC_cols != cols || PDC_rows != rows) + { + PDC_cols = cols; + PDC_rows = rows; + if (queue_resize) + PDC_mac_add_key(KEY_RESIZE); + } + PDC_mac_port_bounds(&limits); + PDC_mac_invalidate(&limits); + PDC_mac_set_port(); + DrawGrowIcon(PDC_window); +} + +void PDC_mac_drag(EventRecord *event) +{ + Rect screen; + + screen_work_rect(&screen); + DragWindow(PDC_window, event->where, &screen); +} + +void PDC_mac_grow(EventRecord *event) +{ + Rect limits; + long grow; + + SetRect(&limits, + (short)(PDC_min_cols * PDC_font_width), + (short)(PDC_min_lines * PDC_font_height), + (short)(PDC_max_cols * PDC_font_width), + (short)(PDC_max_lines * PDC_font_height)); + grow = GrowWindow(PDC_window, event->where, &limits); + if (grow) + PDC_mac_adjust_size(LoWord(grow), HiWord(grow), 1); +} + +void PDC_mac_zoom(EventRecord *event, short part) +{ + Rect bounds; + + if (!TrackBox(PDC_window, event->where, part)) + return; + ZoomWindow(PDC_window, part, TRUE); + PDC_mac_port_bounds(&bounds); + PDC_mac_adjust_size(bounds.right - bounds.left, bounds.bottom - bounds.top, 1); +} + +void PDC_mac_goaway(EventRecord *event) +{ + int key; + + if (!TrackGoAway(PDC_window, event->where)) + return; + key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); + if (!key) + exit(0); + PDC_mac_add_key(key); +} + +void PDC_mac_redraw(void) +{ + Rect bounds; + int y; + + BeginUpdate(PDC_window); + PDC_mac_set_port(); + PDC_mac_port_bounds(&bounds); + EraseRect(&bounds); + if (curscr && SP) + { + int cols; + + cols = SP->cols; + if (cols > PDC_cols) + cols = PDC_cols; + for (y = 0; y < SP->lines && y < PDC_rows; y++) + { + if (curscr->_y[y]) + PDC_transform_line(y, 0, cols, curscr->_y[y]); + } + } + DrawGrowIcon(PDC_window); + EndUpdate(PDC_window); +} + +void PDC_mac_handle_menu(long menuresult) +{ + short menuid; + short item; + int key; + + menuid = HiWord(menuresult); + item = LoWord(menuresult); + if (menuid == PDC_MENU_FILE && item == PDC_ITEM_QUIT) + { + key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); + if (!key) + exit(0); + PDC_mac_add_key(key); + } + else if (menuid == PDC_MENU_EDIT) + { + if (item == PDC_ITEM_COPY) + { + key = PDC_get_function_key(FUNCTION_KEY_COPY); + if (!key) + key = 3; + PDC_mac_add_key(key); + } + else if (item == PDC_ITEM_PASTE) + { + key = PDC_get_function_key(FUNCTION_KEY_PASTE); + if (!key) + key = 22; + PDC_mac_add_key(key); + } + else if (item == PDC_ITEM_CLEAR) + PDC_clearclipboard(); + } +#if !TARGET_API_MAC_CARBON + else if (menuid == PDC_MENU_APPLE && item > 1) + { + Str255 name; + + GetMenuItemText(apple_menu, item, name); + OpenDeskAcc(name); + } +#endif + HiliteMenu(0); +} + +static pascal OSErr ae_quit(const AppleEvent *evt, AppleEvent *reply, + AEEVENTCBPARAM3 refcon) +{ + int key; + + INTENTIONALLY_UNUSED_PARAMETER(evt); + INTENTIONALLY_UNUSED_PARAMETER(reply); + INTENTIONALLY_UNUSED_PARAMETER(refcon); + key = PDC_get_function_key(FUNCTION_KEY_SHUT_DOWN); + if (!key) + exit(0); + PDC_mac_add_key(key); + return noErr; +} + +static void init_toolbox(void) +{ + if (toolbox_ready) + return; +#if TARGET_API_MAC_CARBON + InitCursor(); +#else + MaxApplZone(); + MoreMasters(); + MoreMasters(); + InitGraf(&qd.thePort); + InitFonts(); + FlushEvents(everyEvent, 0); + InitWindows(); + InitMenus(); + TEInit(); + InitDialogs(NULL); + InitCursor(); +#endif + toolbox_ready = 1; +} + +static void init_menus(void) +{ + Str255 title; + + title[0] = 1; + title[1] = 0x14; + apple_menu = NewMenu(PDC_MENU_APPLE, title); + c_to_pstr("About PDCursesMod", title); + AppendMenu(apple_menu, title); +#if !TARGET_API_MAC_CARBON + c_to_pstr("(-", title); + AppendMenu(apple_menu, title); + AppendResMenu(apple_menu, 'DRVR'); +#endif + c_to_pstr("File", title); + file_menu = NewMenu(PDC_MENU_FILE, title); + c_to_pstr("Quit/Q", title); + AppendMenu(file_menu, title); + c_to_pstr("Edit", title); + edit_menu = NewMenu(PDC_MENU_EDIT, title); + c_to_pstr("Cut/X;Copy/C;Paste/V;Clear", title); + AppendMenu(edit_menu, title); + InsertMenu(apple_menu, 0); + InsertMenu(file_menu, 0); + InsertMenu(edit_menu, 0); + DrawMenuBar(); +} + +static void install_apple_events(void) +{ +#if TARGET_API_MAC_CARBON + AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, + NewAEEventHandlerUPP(ae_quit), 0, FALSE); +#else + { + long attr; + + if (Gestalt(gestaltAppleEventsAttr, &attr) == noErr) + { + if (attr & (1L << gestaltAppleEventsPresent)) + AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, + NewAEEventHandlerUPP(ae_quit), 0, FALSE); + } + } +#endif +} + +static WindowPtr create_window(void) +{ + Rect screen; + Rect bounds; + Str255 title; + int width; + int height; + int left; + int top; + WindowPtr window; + + screen_work_rect(&screen); + width = PDC_cols * PDC_font_width; + height = PDC_rows * PDC_font_height; + if (width > screen.right - screen.left - 8) + width = screen.right - screen.left - 8; + if (height > screen.bottom - screen.top - 8) + height = screen.bottom - screen.top - 8; + left = screen.left + (screen.right - screen.left - width) / 2; + top = screen.top + 16; + SetRect(&bounds, (short)left, (short)top, (short)(left + width), (short)(top + height)); + c_to_pstr("PDCursesMod", title); + window = NewCWindow(NULL, &bounds, title, FALSE, zoomDocProc, + (WindowPtr)-1L, TRUE, 0); + return window; +} + +void PDC_scr_close(void) +{ + PDC_LOG(("PDC_scr_close() - called\n")); +} + +void PDC_scr_free(void) +{ + PDC_free_palette(); + if (PDC_window) + { + DisposeWindow(PDC_window); + PDC_window = NULL; + } + if (PDC_mouse_rgn) + { + DisposeRgn(PDC_mouse_rgn); + PDC_mouse_rgn = NULL; + } +#ifdef USING_COMBINING_CHARACTER_SCHEME + PDC_expand_combined_characters(0, NULL); +#endif +} + +int PDC_scr_open(void) +{ + const char *env; + + PDC_LOG(("PDC_scr_open() - called\n")); + if (!SP) + return ERR; + if (PDC_init_palette()) + return ERR; + init_toolbox(); + env = getenv("PDC_FONT_SIZE"); + if (env) + PDC_font_size = atoi(env); + if (PDC_font_size < 6) + PDC_font_size = 12; + env = getenv("PDC_LINES"); + if (env) + PDC_rows = atoi(env); + env = getenv("PDC_COLS"); + if (env) + PDC_cols = atoi(env); + if (initial_rows > 1) + PDC_rows = initial_rows; + if (initial_cols > 1) + PDC_cols = initial_cols; + if (PDC_rows < 2) + PDC_rows = 25; + if (PDC_cols < 2) + PDC_cols = 80; + if (!PDC_window) + { + PDC_font_width = PDC_font_size / 2 + 1; + PDC_font_height = PDC_font_size + 3; + PDC_font_ascent = PDC_font_size - 2; + PDC_window = create_window(); + if (!PDC_window) + return ERR; + init_menus(); + install_apple_events(); + PDC_mouse_rgn = NewRgn(); + ShowWindow(PDC_window); + SelectWindow(PDC_window); + PDC_mac_set_port(); + PDC_mac_apply_font(); + PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 0); + PDC_mac_reset_mouse_rgn(); + } + SP->mouse_wait = PDC_CLICK_PERIOD; + SP->audible = TRUE; + SP->mono = FALSE; + SP->orig_attr = TRUE; + SP->orig_fore = COLOR_WHITE; + SP->orig_back = COLOR_BLACK; + SP->termattrs = A_COLOR | A_UNDERLINE | A_LEFT | A_RIGHT | A_REVERSE + | A_STRIKEOUT | A_TOP | A_BLINK | A_DIM | A_BOLD | A_ITALIC; + SP->lines = PDC_rows; + SP->cols = PDC_cols; + COLORS = 256 + (256 * 256 * 256); + PDC_reset_prog_mode(); + return OK; +} + +int PDC_resize_screen(int nlines, int ncols) +{ + if (!stdscr) + { + if (nlines > 1) + initial_rows = nlines; + if (ncols > 1) + initial_cols = ncols; + if (nlines > 1) + PDC_rows = nlines; + if (ncols > 1) + PDC_cols = ncols; + return OK; + } + if (nlines > 1 && ncols > 1) + PDC_mac_adjust_size(ncols * PDC_font_width, nlines * PDC_font_height, 0); + return OK; +} + +void PDC_reset_prog_mode(void) +{ + PDC_LOG(("PDC_reset_prog_mode() - called.\n")); + if (PDC_window) + { + ShowWindow(PDC_window); + SelectWindow(PDC_window); + PDC_mac_set_port(); + } +} + +void PDC_reset_shell_mode(void) +{ + PDC_LOG(("PDC_reset_shell_mode() - called.\n")); +} + +void PDC_restore_screen_mode(int i) +{ + INTENTIONALLY_UNUSED_PARAMETER(i); +} + +void PDC_save_screen_mode(int i) +{ + INTENTIONALLY_UNUSED_PARAMETER(i); +} + +void PDC_set_resize_limits(const int new_min_lines, const int new_max_lines, + const int new_min_cols, const int new_max_cols) +{ + PDC_min_lines = new_min_lines; + PDC_max_lines = new_max_lines; + PDC_min_cols = new_min_cols; + PDC_max_cols = new_max_cols; + if (PDC_min_lines < 2) + PDC_min_lines = 2; + if (PDC_min_cols < 2) + PDC_min_cols = 2; +} + +bool PDC_can_change_color(void) +{ + return TRUE; +} + +int PDC_color_content(int color, int *red, int *green, int *blue) +{ + const PACKED_RGB col = PDC_get_palette_entry(color); + + *red = DIVROUND(Get_RValue(col) * 1000, 255); + *green = DIVROUND(Get_GValue(col) * 1000, 255); + *blue = DIVROUND(Get_BValue(col) * 1000, 255); + return OK; +} + +int PDC_init_color(int color, int red, int green, int blue) +{ + const PACKED_RGB new_rgb = PACK_RGB(DIVROUND(red * 255, 1000), + DIVROUND(green * 255, 1000), + DIVROUND(blue * 255, 1000)); + + if (!PDC_set_palette_entry(color, new_rgb)) + { + if (curscr) + curscr->_clear = TRUE; + } + return OK; +} diff --git a/mac/pdcsetsc.c b/mac/pdcsetsc.c index 3eaf3c2d..30db5302 100644 --- a/mac/pdcsetsc.c +++ b/mac/pdcsetsc.c @@ -1 +1,61 @@ -#include "pdcmac.h" int PDC_curs_set(int visibility) { int ret_vis; PDC_LOG(("PDC_curs_set() - called: visibility=%d\n", visibility)); ret_vis = SP->visibility; SP->visibility = visibility; PDC_gotoyx(SP->cursrow, SP->curscol); return ret_vis; } void PDC_set_title(const char *title) { Str255 pname; PDC_LOG(("PDC_set_title() - called:<%s>\n", title)); if (!PDC_window) return; { unsigned int length; unsigned int i; length = 0; while (title[length] != 0 && length < 255) length++; pname[0] = (unsigned char)length; for (i = 0; i < length; i++) pname[i + 1] = (unsigned char)title[i]; } SetWTitle(PDC_window, pname); } static int reset_attr(attr_t attr, bool attron) { attr_t prev; if (!SP) return ERR; prev = SP->termattrs; if (attron) SP->termattrs |= attr; else SP->termattrs &= ~attr; if (prev != SP->termattrs && curscr) curscr->_clear = TRUE; return OK; } int PDC_set_blink(bool blinkon) { if (SP && SP->color_started) COLORS = 256 + (256 * 256 * 256); return reset_attr(A_BLINK, blinkon); } int PDC_set_bold(bool boldon) { return reset_attr(A_BOLD, boldon); } \ No newline at end of file +#include "pdcmac.h" + +int PDC_curs_set(int visibility) +{ + int ret_vis; + + PDC_LOG(("PDC_curs_set() - called: visibility=%d\n", visibility)); + ret_vis = SP->visibility; + SP->visibility = visibility; + PDC_gotoyx(SP->cursrow, SP->curscol); + return ret_vis; +} + +void PDC_set_title(const char *title) +{ + Str255 pname; + + PDC_LOG(("PDC_set_title() - called:<%s>\n", title)); + if (!PDC_window) + return; + { + unsigned int length; + unsigned int i; + + length = 0; + while (title[length] != 0 && length < 255) + length++; + pname[0] = (unsigned char)length; + for (i = 0; i < length; i++) + pname[i + 1] = (unsigned char)title[i]; + } + SetWTitle(PDC_window, pname); +} + +static int reset_attr(attr_t attr, bool attron) +{ + attr_t prev; + + if (!SP) + return ERR; + prev = SP->termattrs; + if (attron) + SP->termattrs |= attr; + else + SP->termattrs &= ~attr; + if (prev != SP->termattrs && curscr) + curscr->_clear = TRUE; + return OK; +} + +int PDC_set_blink(bool blinkon) +{ + if (SP && SP->color_started) + COLORS = 256 + (256 * 256 * 256); + return reset_attr(A_BLINK, blinkon); +} + +int PDC_set_bold(bool boldon) +{ + return reset_attr(A_BOLD, boldon); +} diff --git a/mac/pdcutil.c b/mac/pdcutil.c index 05b543e1..664a7d52 100644 --- a/mac/pdcutil.c +++ b/mac/pdcutil.c @@ -1 +1,34 @@ -#include "pdcmac.h" void PDC_beep(void) { PDC_LOG(("PDC_beep() - called\n")); SysBeep(1); } void PDC_napms(int ms) { long start; long waitticks; PDC_LOG(("PDC_napms() - called: ms=%d\n", ms)); if (ms <= 0) return; waitticks = ((long)ms * 60L + 999L) / 1000L; if (waitticks < 1) waitticks = 1; start = TickCount(); PDC_check_for_blinking(); while (TickCount() - start < waitticks) { PDC_mac_process_events(1); PDC_check_for_blinking(); } } const char *PDC_sysname(void) { return "Mac"; } enum PDC_port PDC_port_val = PDC_PORT_MAC; \ No newline at end of file +#include "pdcmac.h" + +void PDC_beep(void) +{ + PDC_LOG(("PDC_beep() - called\n")); + SysBeep(1); +} + +void PDC_napms(int ms) +{ + long start; + long waitticks; + + PDC_LOG(("PDC_napms() - called: ms=%d\n", ms)); + if (ms <= 0) + return; + waitticks = ((long)ms * 60L + 999L) / 1000L; + if (waitticks < 1) + waitticks = 1; + start = TickCount(); + PDC_check_for_blinking(); + while (TickCount() - start < waitticks) + { + PDC_mac_process_events(1); + PDC_check_for_blinking(); + } +} + +const char *PDC_sysname(void) +{ + return "Mac"; +} + +enum PDC_port PDC_port_val = PDC_PORT_MAC; From ff10f36d1349f8cb2a5cea5cbe08ff741886a239 Mon Sep 17 00:00:00 2001 From: RandoOnSteam Date: Fri, 25 Sep 2026 02:42:19 -0700 Subject: [PATCH 3/6] (Not finished addressing pull request yet) Fix mac newlines. Add README.md to mac. Add some comments. Remove forced Carbon compilation from CMake; leftover artifact from debugging --- mac/CMakeLists.txt | 30 +++++++++++++++- mac/README.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++ mac/pdcurses.r | 24 ++++++++++++- mac/pdcutil.c | 5 ++- pdcurses/getch.c | 4 +-- 5 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 mac/README.md diff --git a/mac/CMakeLists.txt b/mac/CMakeLists.txt index d282b7c5..af7c2110 100644 --- a/mac/CMakeLists.txt +++ b/mac/CMakeLists.txt @@ -1 +1,29 @@ -cmake_minimum_required(VERSION 3.11) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "MinSizeRel" CACHE STRING "Choose the type of build, options are: Debug, Release, or MinSizeRel." FORCE) message(STATUS "No build type specified, defaulting to MinSizeRel.") endif() PROJECT(mac VERSION "${PROJECT_VERSION}" LANGUAGES C) add_definitions(-DTARGET_API_MAC_CARBON=1) INCLUDE(project_common) demo_app(../demos calendar) demo_app(../demos firework) demo_app(../demos init_col) demo_app(../demos mbrot) demo_app(../demos newtest) demo_app(../demos ozdemo) demo_app(../demos picsview) demo_app(../demos ptest) demo_app(../demos rain) demo_app(../demos speed) demo_app(../demos test_pan) demo_app(../demos testcurs) demo_app(../demos version) demo_app(../demos widetest) demo_app(../demos worm) demo_app(../demos xmas) SET(CPACK_COMPONENTS_ALL applications) \ No newline at end of file +cmake_minimum_required(VERSION 3.11) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "MinSizeRel" CACHE STRING "Choose the type of build, options are: Debug, Release, or MinSizeRel." FORCE) + message(STATUS "No build type specified, defaulting to MinSizeRel.") +endif() + +PROJECT(mac VERSION "${PROJECT_VERSION}" LANGUAGES C) + +INCLUDE(project_common) + +demo_app(../demos calendar) +demo_app(../demos firework) +demo_app(../demos init_col) +demo_app(../demos mbrot) +demo_app(../demos newtest) +demo_app(../demos ozdemo) +demo_app(../demos picsview) +demo_app(../demos ptest) +demo_app(../demos rain) +demo_app(../demos speed) +demo_app(../demos test_pan) +demo_app(../demos testcurs) +demo_app(../demos version) +demo_app(../demos widetest) +demo_app(../demos worm) +demo_app(../demos xmas) + +SET(CPACK_COMPONENTS_ALL applications) diff --git a/mac/README.md b/mac/README.md new file mode 100644 index 00000000..4bc7fa58 --- /dev/null +++ b/mac/README.md @@ -0,0 +1,85 @@ +PDCursesMod for Macintosh Classic/Carbon +========================================= + +This directory contains PDCursesMod source code files +specific to the Macintosh classic/carbon graphics mode +(Macintosh classic has no command line, so this is the only +mode there). This will work with System 7 and early OSX with +CarbonLib on either 68k or PowerPC. + +Building +-------- + +- You can cross-compile with Retro68 using CMake. If you + are running Macintosh in an emulator this is probably the + most convenient way to compile PDCursesMod. + +- A CodeWarrior 8 file is included for native compilation + and debugging. The non-CMake options include: + + pdcursescw8mac - Macintosh CodeWarrior 8 (non-Pro) project file + pdcursescw6win.mcp - Windows CodeWarrior 6 Pro project file + +- The CodeWarrior project files include only the library itself. + If you want compile a demo, test, or your own application either + add it as a target to the project or make your own project file + and add PDCursesMod as a library. + +- If making an application include pdcurses.r or your own resource file. + +- As mentioned above this port supports several architectures: + + 68k - Builds for early Macintosh Classic non-PowerPC + PowerPC - Builds for Macintosh Classic PowerPC + FAT - Builds for Macintosh Classic 68k/PowerPC hybrid + Carbon - Builds for Macintosh Carbon 1.0 + +- Carbon requires System 8+ with the CarbonLib extension on + Macintosh Classic or early PowerPC-based Mac OSX. + +Retro68 CMake Information +------------------------------ + +Using Retro68 with CMake generally requires its own cmake +toolchain file. Typically you'd have this already set up. For +example if Retro68 was setup in /home/user/Retro68-build your +toolchain would look something like: + + if(RETROPOWERPCOPT OR RETROCARBONOPT) + set(CMAKE_AR /home/user/Retro68-build/toolchain/bin/powerpc-apple-macos-ar) + set(CMAKE_RANLIB /home/user/Retro68-build/toolchain/bin/powerpc-apple-macos-ranlib) + set(CMAKE_LINKER /home/user/Retro68-build/toolchain/bin/powerpc-apple-macos-ld) + set(CMAKE_C_COMPILER /home/user/Retro68-build/toolchain/bin/powerpc-apple-macos-gcc) + set(CMAKE_CXX_COMPILER /home/user/Retro68-build/toolchain/bin/powerpc-apple-macos-g++) + if(RETROCARBONOPT) + set(CMAKE_EXE_LINKER_FLAGS_INIT "-carbon") + add_definitions(-DTARGET_API_MAC_CARBON=1) + set(CMAKE_SYSTEM_NAME RetroCarbon) + else() + set(CMAKE_SYSTEM_NAME RetroPPC) + endif() + else() + set(CMAKE_AR /home/user/Retro68-build/toolchain/bin/m68k-apple-macos-ar) + set(CMAKE_RANLIB /home/user/Retro68-build/toolchain/bin/m68k-apple-macos-ranlib) + set(CMAKE_LINKER /home/user/Retro68-build/toolchain/bin/m68k-apple-macos-ld) + set(CMAKE_C_COMPILER /home/user/Retro68-build/toolchain/bin/m68k-apple-macos-gcc) + set(CMAKE_CXX_COMPILER /home/user/Retro68-build/toolchain/bin/m68k-apple-macos-g++) + set(CMAKE_SYSTEM_NAME Retro68) + endif() + + set(REZ /home/user/Retro68-build/toolchain/bin/Rez) + +Once you have that set up you'd either pass it to the commandline or +add it to the cmake files via: + + set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/retro68-gcc-toolchain.cmake) + +Distribution Status +------------------- + +The files in this directory are released to the Public Domain. + +Acknowledgements +---------------- + +Structure based on the Win32 GUI port by Bill Gray. diff --git a/mac/pdcurses.r b/mac/pdcurses.r index 9cb1e21f..082a369b 100644 --- a/mac/pdcurses.r +++ b/mac/pdcurses.r @@ -1 +1,23 @@ -#include "Types.r" resource 'SIZE' (-1) { reserved, acceptSuspendResumeEvents, reserved, canBackground, doesActivateOnFGSwitch, backgroundAndForeground, dontGetFrontClicks, ignoreChildDiedEvents, is32BitCompatible, isHighLevelEventAware, onlyLocalHLEvents, notStationeryAware, dontUseTextEditServices, reserved, reserved, reserved, 2048 * 1024, 512 * 1024 }; \ No newline at end of file +#include "Types.r" + +resource 'SIZE' (-1) +{ + reserved, + acceptSuspendResumeEvents, + reserved, + canBackground, + doesActivateOnFGSwitch, + backgroundAndForeground, + dontGetFrontClicks, + ignoreChildDiedEvents, + is32BitCompatible, + isHighLevelEventAware, + onlyLocalHLEvents, + notStationeryAware, + dontUseTextEditServices, + reserved, + reserved, + reserved, + 2048 * 1024, + 512 * 1024 +}; diff --git a/mac/pdcutil.c b/mac/pdcutil.c index 664a7d52..cf03291c 100644 --- a/mac/pdcutil.c +++ b/mac/pdcutil.c @@ -14,13 +14,16 @@ void PDC_napms(int ms) PDC_LOG(("PDC_napms() - called: ms=%d\n", ms)); if (ms <= 0) return; + /* milliseconds->TickCount() ticks calculation (/ 16.6~), + while adding just under a tick to round up */ waitticks = ((long)ms * 60L + 999L) / 1000L; if (waitticks < 1) waitticks = 1; start = TickCount(); PDC_check_for_blinking(); while (TickCount() - start < waitticks) - { + { /* PDC_mac_process_events() calls WaitNextEvent() which will yield to + other threads and avoid spinning the CPU */ PDC_mac_process_events(1); PDC_check_for_blinking(); } diff --git a/pdcurses/getch.c b/pdcurses/getch.c index 2cd5e7d8..b33917ab 100644 --- a/pdcurses/getch.c +++ b/pdcurses/getch.c @@ -485,8 +485,8 @@ long PDC_millisecs( void) #elif defined(macintosh) #include long PDC_millisecs( void) -{ - return (((long)TickCount()) * 1000) / 60; +{ /* TickCount() is in 60th of a second, or 16.6~ milliseconds per tick */ + return (((long)TickCount()) * 1000) / 60; /* ~= TickCount() * 16.6~ */ } #else /* neither gettimeofday() or clock_gettime() available */ From c598270fc6f70e1a501747b64ca0c764346f50f5 Mon Sep 17 00:00:00 2001 From: RandoOnSteam Date: Fri, 25 Sep 2026 04:47:51 -0700 Subject: [PATCH 4/6] ----Mac fixes for tests------- Reserve PDC_MAC_GROW_MARGIN so grow box can show up Queue a mouse key event for each real mouse move so "getmouse failed" isn't an issue Don't ignore click-wait timing Don't produce an extra released event on mouse up after dragging window or using menu Host of text displaying unicode fixes so all macroman characters can show; only those supported by the font can show though FUNCTION_KEY_ABORT now works correctly Only event poll once per tick for performance reasons Retro68 fix for getch() CMake enhancements for Retro68 demos/testcurs.c get_wstr cast fix as it returns an empty string on Retro68 PPC --- CMakeLists.txt | 4 + cmake/project_common.cmake | 10 +- demos/testcurs.c | 6 +- mac/CMakeLists.txt | 12 + mac/README.md | 6 +- mac/pdcdisp.c | 628 ++++++++++++++++++++++++++++--------- mac/pdckbd.c | 106 +++++-- mac/pdcmac.h | 11 +- mac/pdcscrn.c | 30 +- mac/pdcursescw6win.mcp | Bin 268637 -> 268637 bytes pdcurses/getch.c | 20 +- 11 files changed, 634 insertions(+), 199 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 14d3c313..433823fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,10 @@ elseif(PDC_OS2_BUILD) # currently requires a unique toolchain file add_subdirectory(os2) +elseif(CMAKE_SYSTEM_NAME MATCHES "^Retro") + + add_subdirectory(mac) + else() add_subdirectory(ncurses) diff --git a/cmake/project_common.cmake b/cmake/project_common.cmake index 48e4f09d..789d834f 100644 --- a/cmake/project_common.cmake +++ b/cmake/project_common.cmake @@ -128,7 +128,14 @@ macro (demo_app dir targ) set(src_files ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/${targ}.c) endif() - add_executable(${bin_name} ${ARGV2} ${src_files}) + if(CMAKE_SYSTEM_NAME MATCHES "^Retro") + set(bin_name ${targ}) + add_application(${bin_name} ${src_files} ${PDC_MAC_RESOURCES}) + add_dependencies(${bin_name} ${PROJECT_NAME}_resources) + else() + add_executable(${bin_name} ${ARGV2} ${src_files}) + set_target_properties(${bin_name} PROPERTIES OUTPUT_NAME ${targ}) + endif() target_link_libraries(${bin_name} PRIVATE ${PDCURSE_PROJ} ${EXTRA_LIBS}) if((${PROJECT_NAME} STREQUAL "wincon") OR (${PROJECT_NAME} STREQUAL "wingui") OR (${PROJECT_NAME} STREQUAL "vt")) @@ -136,7 +143,6 @@ macro (demo_app dir targ) endif() add_dependencies(${bin_name} ${PDCURSE_PROJ}) - set_target_properties(${bin_name} PROPERTIES OUTPUT_NAME ${targ}) install(TARGETS ${bin_name} RUNTIME DESTINATION ${PDCURSES_DIST}/bin/${PROJECT_NAME} COMPONENT applications) endmacro () diff --git a/demos/testcurs.c b/demos/testcurs.c index bfb8ba8b..0a360e8b 100644 --- a/demos/testcurs.c +++ b/demos/testcurs.c @@ -1918,6 +1918,7 @@ void colorTest(WINDOW *win) #if HAVE_WIDE void wideTest(WINDOW *win) { + wint_t input[513]; wchar_t tmp[513]; size_t i; @@ -1930,7 +1931,10 @@ void wideTest(WINDOW *win) echo(); - get_wstr((wint_t *)tmp); + get_wstr(input); + for (i = 0; input[i]; i++) + tmp[i] = (wchar_t)input[i]; + tmp[i] = 0; addstr("\n\n String:\n\n "); addwstr(tmp); addstr("\n\n\n Hex:\n\n "); diff --git a/mac/CMakeLists.txt b/mac/CMakeLists.txt index af7c2110..b5325bfd 100644 --- a/mac/CMakeLists.txt +++ b/mac/CMakeLists.txt @@ -9,6 +9,18 @@ PROJECT(mac VERSION "${PROJECT_VERSION}" LANGUAGES C) INCLUDE(project_common) +target_include_directories(${PDCURSE_PROJ} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../common) + +if(CMAKE_SYSTEM_NAME MATCHES "^Retro") + set(PDC_MAC_RESOURCES ${CMAKE_CURRENT_BINARY_DIR}/pdcurses.rsrc.bin) + set(PDC_MAC_REZ_INCLUDES ${REZ_INCLUDE_PATH}) + list(TRANSFORM PDC_MAC_REZ_INCLUDES PREPEND -I) + add_custom_command(OUTPUT ${PDC_MAC_RESOURCES} + COMMAND ${REZ} ${CMAKE_CURRENT_SOURCE_DIR}/pdcurses.r ${PDC_MAC_REZ_INCLUDES} -o ${PDC_MAC_RESOURCES} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/pdcurses.r) + add_custom_target(${PROJECT_NAME}_resources DEPENDS ${PDC_MAC_RESOURCES}) +endif() + demo_app(../demos calendar) demo_app(../demos firework) demo_app(../demos init_col) diff --git a/mac/README.md b/mac/README.md index 4bc7fa58..55e6acf6 100644 --- a/mac/README.md +++ b/mac/README.md @@ -21,9 +21,9 @@ Building pdcursescw6win.mcp - Windows CodeWarrior 6 Pro project file - The CodeWarrior project files include only the library itself. - If you want compile a demo, test, or your own application either - add it as a target to the project or make your own project file - and add PDCursesMod as a library. + If you want compile a demo, test, or your own application, + either add it as a target to the project or make your own + project file and add PDCursesMod as a library. - If making an application include pdcurses.r or your own resource file. diff --git a/mac/pdcdisp.c b/mac/pdcdisp.c index 7122e3a0..8b9758b2 100644 --- a/mac/pdcdisp.c +++ b/mac/pdcdisp.c @@ -1,11 +1,7 @@ #include "pdcmac.h" #include -#ifdef PDC_WIDE #define USE_UNICODE_ACS_CHARS 1 -#else -#define USE_UNICODE_ACS_CHARS 0 -#endif #include #include @@ -15,6 +11,11 @@ #define PACK_RGB(red, green, blue) ((PACKED_RGB)(red) | ((PACKED_RGB)(green) << 8) | ((PACKED_RGB)(blue) << 16)) #endif +#define BOX_LIGHT 1 +#define BOX_HEAVY 2 +#define BOX_DOUBLE 3 +#define BOX_ARMS(up, down, left, right) (((up) << 6) | ((down) << 4) | ((left) << 2) | (right)) + static void packed_to_rgb(PACKED_RGB packed, RGBColor *color) { unsigned int red; @@ -35,175 +36,494 @@ static void fill_rect(Rect *cell, const RGBColor *color) PaintRect(cell); } -static int is_hline(unsigned long ch) +static int box_arms(unsigned long ch) { - if (ch == 0x2500 || ch == 0x2501 || ch == 0x2550) - return 1; - if (ch == 0xC4 || ch == 0xCD) - return 1; + static const struct + { + unsigned short code; + unsigned char arms; + } box_table[] = + { + { 0x2500, BOX_ARMS(0, 0, 1, 1) }, { 0x2501, BOX_ARMS(0, 0, 2, 2) }, + { 0x2502, BOX_ARMS(1, 1, 0, 0) }, { 0x2503, BOX_ARMS(2, 2, 0, 0) }, + { 0x250C, BOX_ARMS(0, 1, 0, 1) }, { 0x250F, BOX_ARMS(0, 2, 0, 2) }, + { 0x2510, BOX_ARMS(0, 1, 1, 0) }, { 0x2513, BOX_ARMS(0, 2, 2, 0) }, + { 0x2514, BOX_ARMS(1, 0, 0, 1) }, { 0x2517, BOX_ARMS(2, 0, 0, 2) }, + { 0x2518, BOX_ARMS(1, 0, 1, 0) }, { 0x251B, BOX_ARMS(2, 0, 2, 0) }, + { 0x251C, BOX_ARMS(1, 1, 0, 1) }, { 0x2523, BOX_ARMS(2, 2, 0, 2) }, + { 0x2524, BOX_ARMS(1, 1, 1, 0) }, { 0x252B, BOX_ARMS(2, 2, 2, 0) }, + { 0x252C, BOX_ARMS(0, 1, 1, 1) }, { 0x2533, BOX_ARMS(0, 2, 2, 2) }, + { 0x2534, BOX_ARMS(1, 0, 1, 1) }, { 0x253B, BOX_ARMS(2, 0, 2, 2) }, + { 0x253C, BOX_ARMS(1, 1, 1, 1) }, { 0x254B, BOX_ARMS(2, 2, 2, 2) }, + { 0x2550, BOX_ARMS(0, 0, 3, 3) }, { 0x2551, BOX_ARMS(3, 3, 0, 0) }, + { 0x2552, BOX_ARMS(0, 1, 0, 3) }, { 0x2553, BOX_ARMS(0, 3, 0, 1) }, + { 0x2554, BOX_ARMS(0, 3, 0, 3) }, { 0x2555, BOX_ARMS(0, 1, 3, 0) }, + { 0x2556, BOX_ARMS(0, 3, 1, 0) }, { 0x2557, BOX_ARMS(0, 3, 3, 0) }, + { 0x2558, BOX_ARMS(1, 0, 0, 3) }, { 0x2559, BOX_ARMS(3, 0, 0, 1) }, + { 0x255A, BOX_ARMS(3, 0, 0, 3) }, { 0x255B, BOX_ARMS(1, 0, 3, 0) }, + { 0x255C, BOX_ARMS(3, 0, 1, 0) }, { 0x255D, BOX_ARMS(3, 0, 3, 0) }, + { 0x255E, BOX_ARMS(1, 1, 0, 3) }, { 0x255F, BOX_ARMS(3, 3, 0, 1) }, + { 0x2560, BOX_ARMS(3, 3, 0, 3) }, { 0x2561, BOX_ARMS(1, 1, 3, 0) }, + { 0x2562, BOX_ARMS(3, 3, 1, 0) }, { 0x2563, BOX_ARMS(3, 3, 3, 0) }, + { 0x2564, BOX_ARMS(0, 1, 3, 3) }, { 0x2565, BOX_ARMS(0, 3, 1, 1) }, + { 0x2566, BOX_ARMS(0, 3, 3, 3) }, { 0x2567, BOX_ARMS(1, 0, 3, 3) }, + { 0x2568, BOX_ARMS(3, 0, 1, 1) }, { 0x2569, BOX_ARMS(3, 0, 3, 3) }, + { 0x256A, BOX_ARMS(1, 1, 3, 3) }, { 0x256B, BOX_ARMS(3, 3, 1, 1) }, + { 0x256C, BOX_ARMS(3, 3, 3, 3) }, { 0x256D, BOX_ARMS(0, 1, 0, 1) }, + { 0x256E, BOX_ARMS(0, 1, 1, 0) }, { 0x256F, BOX_ARMS(1, 0, 1, 0) }, + { 0x2570, BOX_ARMS(1, 0, 0, 1) } + }; + int i; + + if (ch < 0x2500 || ch > 0x2570) + return 0; + for (i = 0; i < (int)(sizeof(box_table) / sizeof(box_table[0])); i++) + if (box_table[i].code == ch) + return box_table[i].arms; return 0; } -static int is_vline(unsigned long ch) +static void box_line(int x1, int y1, int x2, int y2, int weight) { - if (ch == 0x2502 || ch == 0x2503 || ch == 0x2551) - return 1; - if (ch == 0xB3 || ch == 0xBA) - return 1; - return 0; + if (weight == BOX_HEAVY) + PenSize(2, 2); + MoveTo(x1, y1); + LineTo(x2, y2); + PenSize(1, 1); } -static int box_mask(unsigned long ch) +static int box_single_end(int weight_here, int weight_opposite, int both_across, + int center, int nearline, int farline, int across_double) { - int mask; - - mask = 0; - if (ch == 0x250C || ch == 0x250F || ch == 0x2554 || ch == 0xDA || ch == 0xC9) - mask = 2 | 8; - else if (ch == 0x2510 || ch == 0x2513 || ch == 0x2557 || ch == 0xBF || ch == 0xBB) - mask = 2 | 4; - else if (ch == 0x2514 || ch == 0x2517 || ch == 0x255A || ch == 0xC0 || ch == 0xC8) - mask = 1 | 8; - else if (ch == 0x2518 || ch == 0x251B || ch == 0x255D || ch == 0xD9 || ch == 0xBC) - mask = 1 | 4; - else if (ch == 0x251C || ch == 0x2523 || ch == 0x2560 || ch == 0xC3 || ch == 0xCC) - mask = 1 | 2 | 8; - else if (ch == 0x2524 || ch == 0x252B || ch == 0x2563 || ch == 0xB4 || ch == 0xB9) - mask = 1 | 2 | 4; - else if (ch == 0x252C || ch == 0x2533 || ch == 0x2566 || ch == 0xC2 || ch == 0xCB) - mask = 2 | 4 | 8; - else if (ch == 0x2534 || ch == 0x253B || ch == 0x2569 || ch == 0xC1 || ch == 0xCA) - mask = 1 | 4 | 8; - else if (ch == 0x253C || ch == 0x254B || ch == 0x256C || ch == 0xC5 || ch == 0xCE) - mask = 1 | 2 | 4 | 8; - return mask; + if (!across_double) + return center; + if (both_across && !weight_opposite) + return nearline; + if (weight_here) + return farline; + return center; } -static int draw_graphic(unsigned long ch, Rect *cell, const RGBColor *fg) +static void draw_box(int arms, const Rect *cell) { + int up; + int down; + int left; + int right; int midx; int midy; - int mask; + int top; + int bottom; + int leftx; + int rightx; + int vdouble; + int hdouble; + up = (arms >> 6) & 3; + down = (arms >> 4) & 3; + left = (arms >> 2) & 3; + right = arms & 3; midx = (cell->left + cell->right) / 2; midy = (cell->top + cell->bottom) / 2; - RGBForeColor(fg); - PenNormal(); - PenSize(1, 1); - if (ch == 0x2588 || ch == 0xDB) + top = cell->top; + bottom = cell->bottom - 1; + leftx = cell->left; + rightx = cell->right - 1; + vdouble = up == BOX_DOUBLE || down == BOX_DOUBLE; + hdouble = left == BOX_DOUBLE || right == BOX_DOUBLE; + if ((vdouble || hdouble) + && (!up || up == BOX_DOUBLE) && (!down || down == BOX_DOUBLE) + && (!left || left == BOX_DOUBLE) && (!right || right == BOX_DOUBLE)) { - PaintRect(cell); - return 1; + if (up) + { + box_line(midx - 1, top, midx - 1, midy - 1, BOX_LIGHT); + box_line(midx + 1, top, midx + 1, midy - 1, BOX_LIGHT); + } + else + box_line(midx - 1, midy - 1, midx + 1, midy - 1, BOX_LIGHT); + if (down) + { + box_line(midx - 1, midy + 1, midx - 1, bottom, BOX_LIGHT); + box_line(midx + 1, midy + 1, midx + 1, bottom, BOX_LIGHT); + } + else + box_line(midx - 1, midy + 1, midx + 1, midy + 1, BOX_LIGHT); + if (left) + { + box_line(leftx, midy - 1, midx - 1, midy - 1, BOX_LIGHT); + box_line(leftx, midy + 1, midx - 1, midy + 1, BOX_LIGHT); + } + else + box_line(midx - 1, midy - 1, midx - 1, midy + 1, BOX_LIGHT); + if (right) + { + box_line(midx + 1, midy - 1, rightx, midy - 1, BOX_LIGHT); + box_line(midx + 1, midy + 1, rightx, midy + 1, BOX_LIGHT); + } + else + box_line(midx + 1, midy - 1, midx + 1, midy + 1, BOX_LIGHT); + return; } - if (ch == 0x2580 || ch == 0xDF) + if (up == BOX_DOUBLE || down == BOX_DOUBLE) { - Rect half; - - half = *cell; - half.bottom = midy; - PaintRect(&half); - return 1; + if (up) + { + box_line(midx - 1, top, midx - 1, midy, BOX_LIGHT); + box_line(midx + 1, top, midx + 1, midy, BOX_LIGHT); + } + if (down) + { + box_line(midx - 1, midy, midx - 1, bottom, BOX_LIGHT); + box_line(midx + 1, midy, midx + 1, bottom, BOX_LIGHT); + } } - if (ch == 0x2584 || ch == 0xDC) + else { - Rect half; - - half = *cell; - half.top = midy; - PaintRect(&half); - return 1; + if (up) + box_line(midx, top, midx, box_single_end(up, down, left && right, + midy, midy - 1, midy + 1, hdouble), up); + if (down) + box_line(midx, box_single_end(down, up, left && right, + midy, midy + 1, midy - 1, hdouble), midx, bottom, down); } - if (ch == 0x258C || ch == 0xDD) + if (left == BOX_DOUBLE || right == BOX_DOUBLE) { - Rect half; + if (left) + { + box_line(leftx, midy - 1, midx, midy - 1, BOX_LIGHT); + box_line(leftx, midy + 1, midx, midy + 1, BOX_LIGHT); + } + if (right) + { + box_line(midx, midy - 1, rightx, midy - 1, BOX_LIGHT); + box_line(midx, midy + 1, rightx, midy + 1, BOX_LIGHT); + } + } + else + { + if (left) + box_line(leftx, midy, box_single_end(left, right, up && down, + midx, midx - 1, midx + 1, vdouble), midy, left); + if (right) + box_line(box_single_end(right, left, up && down, + midx, midx + 1, midx - 1, vdouble), midy, rightx, midy, right); + } +} - half = *cell; - half.right = midx; - PaintRect(&half); - return 1; +static void draw_small_pair(const Rect *cell, char first, char second) +{ + int size; + + size = PDC_font_size / 2 + 1; + TextSize(size); + MoveTo(cell->left, cell->top + size); + DrawChar(first); + if (second) + { + MoveTo(cell->right - CharWidth(second), cell->bottom - 1); + DrawChar(second); } - if (ch == 0x2590 || ch == 0xDE) + TextSize(PDC_font_size); +} + +static void draw_face(const Rect *cell, int filled, const RGBColor *bg) +{ + Rect face; + Rect eye; + int diameter; + int midx; + int midy; + + diameter = cell->right - cell->left - 1; + midx = (cell->left + cell->right) / 2; + midy = (cell->top + cell->bottom) / 2; + SetRect(&face, midx - diameter / 2, midy - diameter / 2, + midx - diameter / 2 + diameter, midy - diameter / 2 + diameter); + if (filled) { - Rect half; + PaintOval(&face); + RGBForeColor(bg); + } + else + FrameOval(&face); + SetRect(&eye, face.left + 2, face.top + 2, face.left + 3, face.top + 3); + PaintRect(&eye); + OffsetRect(&eye, diameter - 5, 0); + PaintRect(&eye); + MoveTo(face.left + 2, face.bottom - 3); + LineTo(face.right - 3, face.bottom - 3); +} - half = *cell; - half.left = midx; - PaintRect(&half); +static int draw_graphic(unsigned long ch, Rect *cell, const RGBColor *fg, const RGBColor *bg) +{ + int midx; + int midy; + int arms; + Rect shape; + + midx = (cell->left + cell->right) / 2; + midy = (cell->top + cell->bottom) / 2; + RGBForeColor(fg); + PenNormal(); + arms = box_arms(ch); + if (arms) + { + draw_box(arms, cell); return 1; } - if (ch == 0x2591 || ch == 0xB0 || ch == 0x2592 || ch == 0xB1 - || ch == 0x2593 || ch == 0xB2) + shape = *cell; + switch (ch) { -#if TARGET_API_MAC_CARBON - Pattern pat; + case 0x2588: + PaintRect(cell); + return 1; + case 0x2580: + shape.bottom = midy; + PaintRect(&shape); + return 1; + case 0x2584: + shape.top = midy; + PaintRect(&shape); + return 1; + case 0x258C: + shape.right = midx; + PaintRect(&shape); + return 1; + case 0x2590: + shape.left = midx; + PaintRect(&shape); + return 1; + case 0x2591: + case 0x2592: + case 0x2593: + { + Pattern pat; - if (ch == 0x2591 || ch == 0xB0) - GetQDGlobalsLightGray(&pat); - else if (ch == 0x2593 || ch == 0xB2) - GetQDGlobalsDarkGray(&pat); - else - GetQDGlobalsGray(&pat); - PenPat(&pat); +#if TARGET_API_MAC_CARBON + if (ch == 0x2591) + GetQDGlobalsLightGray(&pat); + else if (ch == 0x2593) + GetQDGlobalsDarkGray(&pat); + else + GetQDGlobalsGray(&pat); #else - if (ch == 0x2591 || ch == 0xB0) - PenPat(&qd.ltGray); - else if (ch == 0x2593 || ch == 0xB2) - PenPat(&qd.dkGray); - else - PenPat(&qd.gray); + if (ch == 0x2591) + pat = qd.ltGray; + else if (ch == 0x2593) + pat = qd.dkGray; + else + pat = qd.gray; #endif - PaintRect(cell); - PenNormal(); + PenPat(&pat); + PaintRect(cell); + PenNormal(); + } return 1; - } - if (is_hline(ch)) - { + case 0x23BA: + case 0x23BB: + case 0x23BC: + case 0x23BD: + shape.top = cell->top + (int)(ch - 0x23BA) * (cell->bottom - cell->top - 1) / 3; + MoveTo(cell->left, shape.top); + LineTo(cell->right - 1, shape.top); + return 1; + case 0x25A0: + InsetRect(&shape, (cell->right - cell->left) / 4, (cell->bottom - cell->top) / 3); + PaintRect(&shape); + return 1; + case 0x25CB: + SetRect(&shape, cell->left + 1, midy - (cell->right - cell->left) / 2 + 1, + cell->right - 1, midy + (cell->right - cell->left) / 2 - 1); + FrameOval(&shape); + return 1; + case 0x263A: + draw_face(cell, 0, bg); + return 1; + case 0x263B: + draw_face(cell, 1, bg); + return 1; + case 0x263C: + SetRect(&shape, midx - 2, midy - 2, midx + 3, midy + 3); + FrameOval(&shape); + MoveTo(midx, midy - 5); + LineTo(midx, midy + 5); MoveTo(cell->left, midy); LineTo(cell->right - 1, midy); return 1; + case 0x2310: + MoveTo(cell->right - 2, midy); + LineTo(cell->left + 1, midy); + LineTo(cell->left + 1, midy + (cell->bottom - cell->top) / 5); + return 1; + case 0x00B2: + draw_small_pair(cell, '2', 0); + return 1; + case 0x207F: + draw_small_pair(cell, 'n', 0); + return 1; + case 0x00BD: + draw_small_pair(cell, '1', '2'); + return 1; + case 0x00BC: + draw_small_pair(cell, '1', '4'); + return 1; + case 0x20A7: + draw_small_pair(cell, 'P', 't'); + return 1; } - if (is_vline(ch)) + return 0; +} + +static unsigned char unicode_to_symbol(unsigned long ch) +{ + static const struct { - MoveTo(midx, cell->top); - LineTo(midx, cell->bottom - 1); - return 1; + unsigned short code; + unsigned char symbol; + } symbol_table[] = + { + { 0x2190, 0xAC }, { 0x2191, 0xAD }, + { 0x2192, 0xAE }, { 0x2193, 0xAF }, { 0x2219, 0xB7 }, { 0x2229, 0xC7 }, + { 0x2261, 0xBA }, { 0x2320, 0xF3 }, { 0x2321, 0xF5 }, { 0x25C6, 0xA8 }, + { 0x2660, 0xAA }, { 0x2663, 0xA7 }, { 0x2665, 0xA9 }, { 0x2666, 0xA8 } + }; + static const char greek_upper[] = "ABGDEZHQIKLMNXOPR STUFCYW"; + static const char greek_lower[] = "abgdezhqiklmnxoprVstufcyw"; + static const char greek_accented_upper[] = "A EHI O UW"; + static const char greek_accented_lower[] = "aehi"; + static const char greek_accented_final[] = "iuouw"; + int i; + + if (ch >= 0x0386 && ch <= 0x038F && greek_accented_upper[ch - 0x0386] != ' ') + return (unsigned char)greek_accented_upper[ch - 0x0386]; + if (ch >= 0x03AC && ch <= 0x03AF) + return (unsigned char)greek_accented_lower[ch - 0x03AC]; + if (ch >= 0x03CA && ch <= 0x03CE) + return (unsigned char)greek_accented_final[ch - 0x03CA]; + if (ch >= 0x0391 && ch <= 0x03A9 && ch != 0x03A2) + return (unsigned char)greek_upper[ch - 0x0391]; + if (ch >= 0x03B1 && ch <= 0x03C9) + return (unsigned char)greek_lower[ch - 0x03B1]; + for (i = 0; i < (int)(sizeof(symbol_table) / sizeof(symbol_table[0])); i++) + if (symbol_table[i].code == ch) + return symbol_table[i].symbol; + return 0; +} + +static void draw_symbol(unsigned char code, const Rect *cell) +{ + int cellwidth; + int width; + + cellwidth = cell->right - cell->left; + TextFont(kFontIDSymbol); + width = CharWidth(code); + if (width > cellwidth) + { + TextSize((short)(PDC_font_size * cellwidth / width)); + width = CharWidth(code); } - mask = box_mask(ch); - if (mask) + MoveTo(cell->left + (cellwidth - width) / 2, cell->top + PDC_font_ascent); + DrawChar(code); + TextFont(monaco); + TextSize(PDC_font_size); +} + +static void draw_text_glyph(unsigned long ch, int unicode, const Rect *cell) +{ + unsigned char code; + + code = (unsigned char)ch; + if (unicode && ch >= 0x80) { - if (mask & 1) + code = PDC_unicode_to_macroman(ch); + if (code == '?') { - MoveTo(midx, cell->top); - LineTo(midx, midy); - } - if (mask & 2) - { - MoveTo(midx, midy); - LineTo(midx, cell->bottom - 1); - } - if (mask & 4) - { - MoveTo(cell->left, midy); - LineTo(midx, midy); - } - if (mask & 8) - { - MoveTo(midx, midy); - LineTo(cell->right - 1, midy); + unsigned char symbolcode; + + symbolcode = unicode_to_symbol(ch); + if (symbolcode) + { + draw_symbol(symbolcode, cell); + return; + } } - return 1; } - if (ch == 0x25C6 || ch == 0x2666 || ch == 0x04) + if (code < 32) + code = (unsigned char)' '; + MoveTo(cell->left, cell->top + PDC_font_ascent); + DrawChar(code); +} + +#ifdef USING_COMBINING_CHARACTER_SCHEME +static unsigned char compose_macroman(unsigned long base, unsigned long mark) +{ + static const struct { - MoveTo(midx, cell->top + 1); - LineTo(cell->right - 2, midy); - LineTo(midx, cell->bottom - 2); - LineTo(cell->left + 1, midy); - LineTo(midx, cell->top + 1); - return 1; + unsigned char base; + unsigned char mark; + unsigned char macroman; + } compose_table[] = + { + { 'A', 0x08, 0x80 }, { 'A', 0x0A, 0x81 }, { 'C', 0x27, 0x82 }, { 'E', 0x01, 0x83 }, + { 'N', 0x03, 0x84 }, { 'O', 0x08, 0x85 }, { 'U', 0x08, 0x86 }, { 'a', 0x01, 0x87 }, + { 'a', 0x00, 0x88 }, { 'a', 0x02, 0x89 }, { 'a', 0x08, 0x8A }, { 'a', 0x03, 0x8B }, + { 'a', 0x0A, 0x8C }, { 'c', 0x27, 0x8D }, { 'e', 0x01, 0x8E }, { 'e', 0x00, 0x8F }, + { 'e', 0x02, 0x90 }, { 'e', 0x08, 0x91 }, { 'i', 0x01, 0x92 }, { 'i', 0x00, 0x93 }, + { 'i', 0x02, 0x94 }, { 'i', 0x08, 0x95 }, { 'n', 0x03, 0x96 }, { 'o', 0x01, 0x97 }, + { 'o', 0x00, 0x98 }, { 'o', 0x02, 0x99 }, { 'o', 0x08, 0x9A }, { 'o', 0x03, 0x9B }, + { 'u', 0x01, 0x9C }, { 'u', 0x00, 0x9D }, { 'u', 0x02, 0x9E }, { 'u', 0x08, 0x9F }, + { 'A', 0x00, 0xCB }, { 'A', 0x03, 0xCC }, { 'O', 0x03, 0xCD }, { 'y', 0x08, 0xD8 }, + { 'Y', 0x08, 0xD9 }, { 'A', 0x02, 0xE5 }, { 'E', 0x02, 0xE6 }, { 'A', 0x01, 0xE7 }, + { 'E', 0x08, 0xE8 }, { 'E', 0x00, 0xE9 }, { 'I', 0x01, 0xEA }, { 'I', 0x02, 0xEB }, + { 'I', 0x08, 0xEC }, { 'I', 0x00, 0xED }, { 'O', 0x01, 0xEE }, { 'O', 0x02, 0xEF }, + { 'O', 0x00, 0xF1 }, { 'U', 0x01, 0xF2 }, { 'U', 0x02, 0xF3 }, { 'U', 0x00, 0xF4 } + }; + int i; + + if (base > 0x7F || mark < 0x300 || mark > 0x327) + return 0; + for (i = 0; i < (int)(sizeof(compose_table) / sizeof(compose_table[0])); i++) + if (compose_table[i].base == base && compose_table[i].mark == mark - 0x300) + return compose_table[i].macroman; + return 0; +} + +static unsigned char combining_accent(unsigned long mark) +{ + switch (mark) + { + case 0x300: + return 0x60; + case 0x301: + return 0xAB; + case 0x302: + return 0xF6; + case 0x303: + return 0xF7; + case 0x304: + return 0xF8; + case 0x306: + return 0xF9; + case 0x307: + return 0xFA; + case 0x308: + return 0xAC; + case 0x30A: + return 0xFB; + case 0x30B: + return 0xFD; + case 0x30C: + return 0xFF; + case 0x327: + return 0xFC; + case 0x328: + return 0xFE; } return 0; } +#endif static void draw_cursor_shape(Rect *cell, const RGBColor *fg) { @@ -241,13 +561,6 @@ static void draw_cursor_shape(Rect *cell, const RGBColor *fg) } } -static unsigned char char_to_mac(unsigned long ch) -{ - if (ch < 0x100) - return (unsigned char)ch; - return PDC_unicode_to_macroman(ch); -} - void PDC_transform_line(int lineno, int x, int len, const chtype *srcp) { int i; @@ -271,13 +584,45 @@ void PDC_transform_line(int lineno, int x, int len, const chtype *srcp) Rect r; Style face; attr_t sysattrs; + int unicode; +#ifdef USING_COMBINING_CHARACTER_SCHEME + cchar_t marks[4]; + int markcount; + int mark; +#endif cell = srcp[i]; sysattrs = SP->termattrs; +#ifdef PDC_WIDE + unicode = 1; +#else + unicode = 0; +#endif if (_is_altcharset(cell)) + { ch = (unsigned long)acs_map[cell & 0x7f]; + unicode = 1; + } else ch = (unsigned long)(cell & A_CHARTEXT); +#ifdef USING_COMBINING_CHARACTER_SCHEME + markcount = 0; + while (ch > MAX_UNICODE) + { + cchar_t added; + + ch = (unsigned long)PDC_expand_combined_characters((cchar_t)ch, &added); + if (markcount < 4) + marks[markcount++] = added; + } + if (ch == DUMMY_CHAR_NEXT_TO_FULLWIDTH) + ch = (unsigned long)' '; + if (markcount == 1 && compose_macroman(ch, (unsigned long)marks[0])) + { + ch = (unsigned long)PDC_macroman_to_unicode(compose_macroman(ch, (unsigned long)marks[0])); + markcount = 0; + } +#endif if ((cell & A_BLINK) && SP->blink_state && (sysattrs & A_BLINK)) ch = (unsigned long)' '; PDC_get_rgb_values(cell, &fgpacked, &bgpacked); @@ -298,16 +643,19 @@ void PDC_transform_line(int lineno, int x, int len, const chtype *srcp) if ((cell & A_ITALIC) && (sysattrs & A_ITALIC)) face |= italic; TextFace(face); - if (!draw_graphic(ch, &r, &fg)) + if (!unicode || !draw_graphic(ch, &r, &fg, &bg)) { - unsigned char drawn; - - drawn = char_to_mac(ch); - if (drawn < 32) - drawn = (unsigned char)' '; - MoveTo(r.left, r.top + PDC_font_ascent); - DrawChar(drawn); + RGBForeColor(&fg); + draw_text_glyph(ch, unicode, &r); } +#ifdef USING_COMBINING_CHARACTER_SCHEME + for (mark = markcount - 1; mark >= 0; mark--) + if (combining_accent((unsigned long)marks[mark])) + { + MoveTo(r.left, r.top + PDC_font_ascent); + DrawChar(combining_accent((unsigned long)marks[mark])); + } +#endif if (cell & (A_UNDERLINE | A_TOP | A_LEFT | A_RIGHT | A_STRIKEOUT)) { RGBColor linec; diff --git a/mac/pdckbd.c b/mac/pdckbd.c index 0fb1a952..8ac7f5d7 100644 --- a/mac/pdckbd.c +++ b/mac/pdckbd.c @@ -8,8 +8,10 @@ int PDC_key_queue[PDC_KEY_QUEUE_SIZE]; int PDC_key_queue_head = 0; int PDC_key_queue_tail = 0; -static int last_mouse_button = 0; +static int held_mouse_button = -1; static Point last_mouse_local; +static long mouse_wait_until = 0; +static unsigned long last_event_tick = 0; static int prev_special_key = -1; static const struct @@ -172,6 +174,48 @@ static void local_mouse(const EventRecord *event, Point *local) GlobalToLocal(local); } +static void announce_mouse_events(void) +{ + int announced; + int i; + + mouse_wait_until = 0; + announced = 0; + for (i = PDC_key_queue_head; i != PDC_key_queue_tail; ) + { + if (PDC_key_queue[i] == KEY_MOUSE) + announced++; + i++; + if (i >= PDC_KEY_QUEUE_SIZE) + i = 0; + } + while (announced < _mlist_count) + { + PDC_mac_add_key(KEY_MOUSE); + announced++; + } +} + +static void check_mouse_wait(void) +{ + if (mouse_wait_until && PDC_millisecs() - mouse_wait_until >= 0) + announce_mouse_events(); +} + +static void mouse_cell(const Point *local, int *x, int *y) +{ + *x = local->h / PDC_font_width; + *y = local->v / PDC_font_height; + if (*x < 0) + *x = 0; + if (*y < 0) + *y = 0; + if (SP && *x >= SP->cols) + *x = SP->cols - 1; + if (SP && *y >= SP->lines) + *y = SP->lines - 1; +} + static void queue_mouse(int button, int event_type, const EventRecord *event) { Point local; @@ -180,19 +224,12 @@ static void queue_mouse(int button, int event_type, const EventRecord *event) local_mouse(event, &local); last_mouse_local = local; - x = local.h / PDC_font_width; - y = local.v / PDC_font_height; - if (x < 0) - x = 0; - if (y < 0) - y = 0; - if (SP && x >= SP->cols) - x = SP->cols - 1; - if (SP && y >= SP->lines) - y = SP->lines - 1; - _add_raw_mouse_event(button, event_type, mouse_modifs(event), x, y); - if (_get_mouse_event(NULL)) - PDC_mac_add_key(KEY_MOUSE); + mouse_cell(&local, &x, &y); + if (_add_raw_mouse_event(button, event_type, mouse_modifs(event), x, y) + && SP->mouse_wait > 0) + mouse_wait_until = PDC_millisecs() + SP->mouse_wait; + else + announce_mouse_events(); } static int lookup_special(unsigned char keycode, unsigned long modifiers) @@ -257,7 +294,7 @@ static int translate_key(const EventRecord *event) if (PDC_font_size > 48) PDC_font_size = 48; PDC_mac_apply_font(); - PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 1); + PDC_mac_adjust_cells(PDC_cols, PDC_rows, 1); return -1; } if ((event->modifiers & cmdKey) && charcode == '-') @@ -269,7 +306,7 @@ static int translate_key(const EventRecord *event) if (PDC_font_size < 6) PDC_font_size = 6; PDC_mac_apply_font(); - PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 1); + PDC_mac_adjust_cells(PDC_cols, PDC_rows, 1); return -1; } key = lookup_special(keycode, modifiers); @@ -325,6 +362,8 @@ static void handle_key(EventRecord *event) key = translate_key(event); if (key == 3 && SP && !SP->raw_inp) exit(0); + if (key > 0 && key == PDC_get_function_key(FUNCTION_KEY_ABORT)) + exit(-1); if (key > 0) { if (prev_special_key == key) @@ -340,13 +379,13 @@ static void handle_content_click(EventRecord *event, int pressed) if (pressed) { - button = mouse_button_from_event(event); - last_mouse_button = button; - queue_mouse(button, BUTTON_PRESSED, event); + held_mouse_button = mouse_button_from_event(event); + queue_mouse(held_mouse_button, BUTTON_PRESSED, event); } - else + else if (held_mouse_button >= 0) { - button = last_mouse_button; + button = held_mouse_button; + held_mouse_button = -1; queue_mouse(button, BUTTON_RELEASED, event); } } @@ -354,6 +393,7 @@ static void handle_content_click(EventRecord *event, int pressed) static void handle_mouse_moved(EventRecord *event) { Point local; + int button; int x; int y; @@ -369,10 +409,13 @@ static void handle_mouse_moved(EventRecord *event) return; } last_mouse_local = local; - x = local.h / PDC_font_width; - y = local.v / PDC_font_height; - _add_raw_mouse_event(last_mouse_button, BUTTON_MOVED, mouse_modifs(event), x, y); - PDC_mac_add_key(KEY_MOUSE); + mouse_cell(&local, &x, &y); + button = 0; + if (held_mouse_button >= 0) + button = held_mouse_button; + _add_raw_mouse_event(button, BUTTON_MOVED, mouse_modifs(event), x, y); + if (!mouse_wait_until) + announce_mouse_events(); PDC_mac_reset_mouse_rgn(); } @@ -489,8 +532,16 @@ void PDC_set_keyboard_binary(bool on) bool PDC_check_key(void) { + unsigned long tick; + PDC_check_for_blinking(); - PDC_mac_process_events(0); + tick = TickCount(); + if (tick != last_event_tick) + { + last_event_tick = tick; + PDC_mac_process_events(0); + } + check_mouse_wait(); if (queue_has_key()) return TRUE; return FALSE; @@ -502,6 +553,7 @@ int PDC_get_key(void) if (!queue_has_key()) PDC_mac_process_events(GetCaretTime()); + check_mouse_wait(); key = pop_key(); return key; } @@ -511,6 +563,8 @@ void PDC_flushinp(void) PDC_LOG(("PDC_flushinp() - called\n")); PDC_key_queue_head = 0; PDC_key_queue_tail = 0; + mouse_wait_until = 0; + held_mouse_button = -1; while (_get_mouse_event(&SP->mouse_status)) ; FlushEvents(keyDownMask | keyUpMask | autoKeyMask | mDownMask | mUpMask, 0); diff --git a/mac/pdcmac.h b/mac/pdcmac.h index db59bfce..3e4b1527 100644 --- a/mac/pdcmac.h +++ b/mac/pdcmac.h @@ -1,12 +1,8 @@ #ifndef PDC_MAC_H #define PDC_MAC_H 1 -#ifndef TARGET_API_MAC_CARBON -# ifdef TARGET_CARBON -# define TARGET_API_MAC_CARBON TARGET_CARBON -# else -# define TARGET_API_MAC_CARBON 0 -# endif +#if !defined(TARGET_API_MAC_CARBON) && defined(TARGET_CARBON) +# define TARGET_API_MAC_CARBON TARGET_CARBON #endif #include @@ -34,6 +30,8 @@ #define kScrapFlavorTypeText 'TEXT' #endif +#define PDC_MAC_GROW_MARGIN 15 + #ifndef zoomDocProc #define zoomDocProc 8 #endif @@ -137,6 +135,7 @@ void PDC_mac_goaway(EventRecord *event); void PDC_mac_redraw(void); void PDC_mac_handle_menu(long menuresult); void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize); +void PDC_mac_adjust_cells(int cols, int rows, int queue_resize); unsigned short PDC_macroman_to_unicode(unsigned char ch); unsigned char PDC_unicode_to_macroman(unsigned long code); diff --git a/mac/pdcscrn.c b/mac/pdcscrn.c index 3ed52bcd..9de0ae4b 100644 --- a/mac/pdcscrn.c +++ b/mac/pdcscrn.c @@ -146,8 +146,8 @@ void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize) int cols; Rect limits; - cols = pixelwidth / PDC_font_width; - rows = pixelheight / PDC_font_height; + cols = (pixelwidth - PDC_MAC_GROW_MARGIN) / PDC_font_width; + rows = (pixelheight - PDC_MAC_GROW_MARGIN) / PDC_font_height; if (cols < PDC_min_cols) cols = PDC_min_cols; if (rows < PDC_min_lines) @@ -160,8 +160,8 @@ void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize) cols = 2; if (rows < 2) rows = 2; - SizeWindow(PDC_window, (short)(cols * PDC_font_width), - (short)(rows * PDC_font_height), TRUE); + SizeWindow(PDC_window, (short)(cols * PDC_font_width + PDC_MAC_GROW_MARGIN), + (short)(rows * PDC_font_height + PDC_MAC_GROW_MARGIN), TRUE); if (PDC_cols != cols || PDC_rows != rows) { PDC_cols = cols; @@ -175,6 +175,12 @@ void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize) DrawGrowIcon(PDC_window); } +void PDC_mac_adjust_cells(int cols, int rows, int queue_resize) +{ + PDC_mac_adjust_size(cols * PDC_font_width + PDC_MAC_GROW_MARGIN, + rows * PDC_font_height + PDC_MAC_GROW_MARGIN, queue_resize); +} + void PDC_mac_drag(EventRecord *event) { Rect screen; @@ -189,10 +195,10 @@ void PDC_mac_grow(EventRecord *event) long grow; SetRect(&limits, - (short)(PDC_min_cols * PDC_font_width), - (short)(PDC_min_lines * PDC_font_height), - (short)(PDC_max_cols * PDC_font_width), - (short)(PDC_max_lines * PDC_font_height)); + (short)(PDC_min_cols * PDC_font_width + PDC_MAC_GROW_MARGIN), + (short)(PDC_min_lines * PDC_font_height + PDC_MAC_GROW_MARGIN), + (short)(PDC_max_cols * PDC_font_width + PDC_MAC_GROW_MARGIN), + (short)(PDC_max_lines * PDC_font_height + PDC_MAC_GROW_MARGIN)); grow = GrowWindow(PDC_window, event->where, &limits); if (grow) PDC_mac_adjust_size(LoWord(grow), HiWord(grow), 1); @@ -389,8 +395,8 @@ static WindowPtr create_window(void) WindowPtr window; screen_work_rect(&screen); - width = PDC_cols * PDC_font_width; - height = PDC_rows * PDC_font_height; + width = PDC_cols * PDC_font_width + PDC_MAC_GROW_MARGIN; + height = PDC_rows * PDC_font_height + PDC_MAC_GROW_MARGIN; if (width > screen.right - screen.left - 8) width = screen.right - screen.left - 8; if (height > screen.bottom - screen.top - 8) @@ -471,7 +477,7 @@ int PDC_scr_open(void) SelectWindow(PDC_window); PDC_mac_set_port(); PDC_mac_apply_font(); - PDC_mac_adjust_size(PDC_cols * PDC_font_width, PDC_rows * PDC_font_height, 0); + PDC_mac_adjust_cells(PDC_cols, PDC_rows, 0); PDC_mac_reset_mouse_rgn(); } SP->mouse_wait = PDC_CLICK_PERIOD; @@ -504,7 +510,7 @@ int PDC_resize_screen(int nlines, int ncols) return OK; } if (nlines > 1 && ncols > 1) - PDC_mac_adjust_size(ncols * PDC_font_width, nlines * PDC_font_height, 0); + PDC_mac_adjust_cells(ncols, nlines, 0); return OK; } diff --git a/mac/pdcursescw6win.mcp b/mac/pdcursescw6win.mcp index 3b022b3409afb7f8ee2635f27b3f247782088dc1..827aedead090a2a2dc937897c58163d022b2dd2f 100644 GIT binary patch delta 3302 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 199309L) \ +#if defined( macintosh) + #define HAVE_TICKCOUNT +#elif defined( _POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L) \ && (!defined( __MINGW32__) || defined( CLOCK_REALTIME)) /* only newer MinGW environments have clock_gettime and those have CLOCK_REALTIME as a macro */ @@ -464,7 +466,14 @@ use clock_gettime() or gettimeofday() when available. */ #define HAVE_GETTIMEOFDAY #endif -#if defined( HAVE_CLOCK_GETTIME) +#if defined( HAVE_TICKCOUNT) +#include +long PDC_millisecs( void) +{ + return( (long)(((unsigned long)TickCount( ) * 50UL) / 3UL)); +} + +#elif defined( HAVE_CLOCK_GETTIME) long PDC_millisecs( void) { struct timespec t; @@ -482,13 +491,6 @@ long PDC_millisecs( void) return( t.tv_sec * 1000 + t.tv_usec / 1000); } -#elif defined(macintosh) -#include -long PDC_millisecs( void) -{ /* TickCount() is in 60th of a second, or 16.6~ milliseconds per tick */ - return (((long)TickCount()) * 1000) / 60; /* ~= TickCount() * 16.6~ */ -} - #else /* neither gettimeofday() or clock_gettime() available */ #include From 1d9b6514c55139556b92d01e3e587bc71490bac3 Mon Sep 17 00:00:00 2001 From: RandoOnSteam Date: Fri, 25 Sep 2026 16:01:41 -0700 Subject: [PATCH 5/6] Fix an edge case where sometimes the 15 grow pixels are white instead of black when resizing from smaller to larger Prevent overflow in ticks<->milliseconds calculation Native codewarrior edge case fix for its erase enum in system headers Rejigger native codewarrior project a tad to be compressed so resources carry over --- mac/README.md | 18 +++++++++++++----- mac/pdcdisp.c | 13 +++++++++++++ mac/pdckbd.c | 6 +++++- mac/pdcmac.h | 11 +++++++++++ mac/pdcscrn.c | 27 ++++++++++++++++++++++++--- mac/pdcursescw8mac | Bin 223034 -> 0 bytes mac/pdcursescw8mac.sit | Bin 0 -> 62877 bytes mac/pdcutil.c | 27 ++++++++++++++++++--------- pdcurses/debug.c | 2 +- pdcurses/getch.c | 8 ++++++-- 10 files changed, 91 insertions(+), 21 deletions(-) delete mode 100644 mac/pdcursescw8mac create mode 100644 mac/pdcursescw8mac.sit diff --git a/mac/README.md b/mac/README.md index 55e6acf6..93c86a2b 100644 --- a/mac/README.md +++ b/mac/README.md @@ -10,16 +10,24 @@ CarbonLib on either 68k or PowerPC. Building -------- -- You can cross-compile with Retro68 using CMake. If you - are running Macintosh in an emulator this is probably the - most convenient way to compile PDCursesMod. +- You can cross-compile with Retro68 using CMake. This is + the main way to do it as you get a modern compiler with + modern optimizations. Some Linux distros have a package + for Retro68, but for those that don't there are a couple + options: + + 1) The main Retro68 repo at https://github.com/autc04/Retro68/ + 2) Matthewdeaves's fork at https://github.com/matthewdeaves/Retro68 which includes a more hands-free setup script - A CodeWarrior 8 file is included for native compilation and debugging. The non-CMake options include: - pdcursescw8mac - Macintosh CodeWarrior 8 (non-Pro) project file + pdcursescw8mac.sit - Macintosh CodeWarrior 8 (non-Pro) 68k project file pdcursescw6win.mcp - Windows CodeWarrior 6 Pro project file - + +- Use Stuffit Expander to extract the native Macintosh CodeWarrior 8 + project. It is compressed to preserve its resources. + - The CodeWarrior project files include only the library itself. If you want compile a demo, test, or your own application, either add it as a target to the project or make your own diff --git a/mac/pdcdisp.c b/mac/pdcdisp.c index 8b9758b2..c42defac 100644 --- a/mac/pdcdisp.c +++ b/mac/pdcdisp.c @@ -561,6 +561,19 @@ static void draw_cursor_shape(Rect *cell, const RGBColor *fg) } } +void PDC_mac_default_background(RGBColor *color) +{ + PACKED_RGB fgpacked; + PACKED_RGB bgpacked; + + bgpacked = PACK_RGB(0, 0, 0); + if (SP && SP->pairs_allocated > 0) + PDC_get_rgb_values((chtype)0, &fgpacked, &bgpacked); + if (bgpacked == (PACKED_RGB)-1) + bgpacked = PACK_RGB(0, 0, 0); + packed_to_rgb(bgpacked, color); +} + void PDC_transform_line(int lineno, int x, int len, const chtype *srcp) { int i; diff --git a/mac/pdckbd.c b/mac/pdckbd.c index 8ac7f5d7..4e0d45a1 100644 --- a/mac/pdckbd.c +++ b/mac/pdckbd.c @@ -2,7 +2,11 @@ #include #include #include -#include +#if defined(__MWERKS__) +#include "::common:mouse.c" +#else +#include "../common/mouse.c" +#endif int PDC_key_queue[PDC_KEY_QUEUE_SIZE]; int PDC_key_queue_head = 0; diff --git a/mac/pdcmac.h b/mac/pdcmac.h index 3e4b1527..b9acdbe8 100644 --- a/mac/pdcmac.h +++ b/mac/pdcmac.h @@ -5,6 +5,7 @@ # define TARGET_API_MAC_CARBON TARGET_CARBON #endif +#define erase PDC_mac_qd_erase /* CW8 non-Pro has erase as an enum */ #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#undef erase #undef MOUSE_MOVED #include @@ -36,6 +38,14 @@ #define zoomDocProc 8 #endif +#if !defined(NewAEEventHandlerUPP) && defined(NewAEEventHandlerProc) +#define NewAEEventHandlerUPP NewAEEventHandlerProc +#endif + +#ifndef kFontIDSymbol +#define kFontIDSymbol 23 +#endif + #ifndef monaco #define monaco 4 #endif @@ -136,6 +146,7 @@ void PDC_mac_redraw(void); void PDC_mac_handle_menu(long menuresult); void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize); void PDC_mac_adjust_cells(int cols, int rows, int queue_resize); +void PDC_mac_default_background(RGBColor *color); unsigned short PDC_macroman_to_unicode(unsigned char ch); unsigned char PDC_unicode_to_macroman(unsigned long code); diff --git a/mac/pdcscrn.c b/mac/pdcscrn.c index 9de0ae4b..9517cbf2 100644 --- a/mac/pdcscrn.c +++ b/mac/pdcscrn.c @@ -140,6 +140,25 @@ static void screen_work_rect(Rect *bounds) bounds->top = (short)(bounds->top + GetMBarHeight()); } +static void paint_margins(void) +{ + Rect bounds; + Rect strip; + RGBColor background; + + PDC_mac_set_port(); + PDC_mac_port_bounds(&bounds); + PDC_mac_default_background(&background); + RGBForeColor(&background); + strip = bounds; + strip.left = (short)(bounds.right - PDC_MAC_GROW_MARGIN); + PaintRect(&strip); + strip = bounds; + strip.top = (short)(bounds.bottom - PDC_MAC_GROW_MARGIN); + PaintRect(&strip); + DrawGrowIcon(PDC_window); +} + void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize) { int rows; @@ -171,8 +190,8 @@ void PDC_mac_adjust_size(int pixelwidth, int pixelheight, int queue_resize) } PDC_mac_port_bounds(&limits); PDC_mac_invalidate(&limits); - PDC_mac_set_port(); - DrawGrowIcon(PDC_window); + if (SP) + paint_margins(); } void PDC_mac_adjust_cells(int cols, int rows, int queue_resize) @@ -248,8 +267,10 @@ void PDC_mac_redraw(void) if (curscr->_y[y]) PDC_transform_line(y, 0, cols, curscr->_y[y]); } + paint_margins(); } - DrawGrowIcon(PDC_window); + else + DrawGrowIcon(PDC_window); EndUpdate(PDC_window); } diff --git a/mac/pdcursescw8mac b/mac/pdcursescw8mac deleted file mode 100644 index 565b7c694b20737ad747934c48978a00ed407ffa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 223034 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

k%B;fRgVH35J(Fm7-(-%f~ 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 z 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 literal 0 HcmV?d00001 diff --git a/mac/pdcutil.c b/mac/pdcutil.c index cf03291c..6025c26b 100644 --- a/mac/pdcutil.c +++ b/mac/pdcutil.c @@ -8,20 +8,29 @@ void PDC_beep(void) void PDC_napms(int ms) { - long start; - long waitticks; + unsigned long start; + unsigned long waitticks; + unsigned long fiftieths; + unsigned long remainder; PDC_LOG(("PDC_napms() - called: ms=%d\n", ms)); if (ms <= 0) return; - /* milliseconds->TickCount() ticks calculation (/ 16.6~), - while adding just under a tick to round up */ - waitticks = ((long)ms * 60L + 999L) / 1000L; - if (waitticks < 1) - waitticks = 1; - start = TickCount(); + /* milliseconds->TickCount() ticks calculation + to prevent overflow and be reasonably performant */ + fiftieths = (unsigned long)ms / 50UL; + remainder = ((unsigned long)ms + - ((fiftieths << 5) + (fiftieths << 4) + (fiftieths << 1))) * 3UL; + waitticks = fiftieths * 3UL; + if (remainder > 100UL) + waitticks += 3UL; + else if (remainder > 50UL) + waitticks += 2UL; + else if (remainder) + waitticks += 1UL; + start = (unsigned long)TickCount(); PDC_check_for_blinking(); - while (TickCount() - start < waitticks) + while ((unsigned long)TickCount() - start < waitticks) { /* PDC_mac_process_events() calls WaitNextEvent() which will yield to other threads and avoid spinning the CPU */ PDC_mac_process_events(1); diff --git a/pdcurses/debug.c b/pdcurses/debug.c index dacd5f85..15fa8a16 100644 --- a/pdcurses/debug.c +++ b/pdcurses/debug.c @@ -56,7 +56,7 @@ debug #include #include -#if !defined(macintosh) +#if !defined(macintosh) && !(defined(__MWERKS__) && (defined(__MC68K__) || defined(__POWERPC__))) #include #endif #include diff --git a/pdcurses/getch.c b/pdcurses/getch.c index 6bf92382..68209f4b 100644 --- a/pdcurses/getch.c +++ b/pdcurses/getch.c @@ -451,7 +451,7 @@ use clock_gettime() or gettimeofday() when available. */ #endif #endif -#if defined( macintosh) +#if defined( macintosh) || (defined( __MWERKS__) && (defined( __MC68K__) || defined( __POWERPC__))) #define HAVE_TICKCOUNT #elif defined( _POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L) \ && (!defined( __MINGW32__) || defined( CLOCK_REALTIME)) @@ -467,10 +467,14 @@ use clock_gettime() or gettimeofday() when available. */ #endif #if defined( HAVE_TICKCOUNT) +#define erase PDC_mac_qd_erase #include +#undef erase long PDC_millisecs( void) { - return( (long)(((unsigned long)TickCount( ) * 50UL) / 3UL)); + const unsigned long ticks = (unsigned long)TickCount( ); + + return( (long)(ticks * 16UL + (ticks * 2UL) / 3UL)); } #elif defined( HAVE_CLOCK_GETTIME) From 50ade74522319026b79b7c51a30ccdb424588418 Mon Sep 17 00:00:00 2001 From: RandoOnSteam Date: Fri, 25 Sep 2026 16:06:05 -0700 Subject: [PATCH 6/6] remove windows codewarrior project as requested --- mac/README.md | 1 - mac/pdcursescw6win.mcp | Bin 268637 -> 0 bytes 2 files changed, 1 deletion(-) delete mode 100644 mac/pdcursescw6win.mcp diff --git a/mac/README.md b/mac/README.md index 93c86a2b..5342ab57 100644 --- a/mac/README.md +++ b/mac/README.md @@ -23,7 +23,6 @@ Building and debugging. The non-CMake options include: pdcursescw8mac.sit - Macintosh CodeWarrior 8 (non-Pro) 68k project file - pdcursescw6win.mcp - Windows CodeWarrior 6 Pro project file - Use Stuffit Expander to extract the native Macintosh CodeWarrior 8 project. It is compressed to preserve its resources. diff --git a/mac/pdcursescw6win.mcp b/mac/pdcursescw6win.mcp deleted file mode 100644 index 827aedead090a2a2dc937897c58163d022b2dd2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 268637 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