X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/0c367171f27d25a11f9f9d2a3836f45338eb5178..2beb0fb004d36c0ce0a2db3f00ad145241391ae3:/mac/macterm.c diff --git a/mac/macterm.c b/mac/macterm.c index 23ac22a6..af46d6d3 100644 --- a/mac/macterm.c +++ b/mac/macterm.c @@ -1,4 +1,4 @@ -/* $Id: macterm.c,v 1.22 2002/12/09 23:26:52 ben Exp $ */ +/* $Id: macterm.c,v 1.34 2003/01/05 10:52:56 ben Exp $ */ /* * Copyright (c) 1999 Simon Tatham * Copyright (c) 1999, 2002 Ben Harris @@ -46,8 +46,11 @@ #include #include #include +#include +#include #include #include +#include #include #include @@ -57,7 +60,9 @@ #include "macresid.h" #include "putty.h" +#include "charset.h" #include "mac.h" +#include "storage.h" #include "terminal.h" #define NCOLOURS (lenof(((Config *)0)->colours)) @@ -75,6 +80,10 @@ (y) / s->font_height) static void mac_initfont(Session *); +static pascal OSStatus uni_to_font_fallback(UniChar *, ByteCount, ByteCount *, + TextPtr, ByteCount, ByteCount *, + LogicalAddress *, + ConstUnicodeMappingPtr); static void mac_initpalette(Session *); static void mac_adjustwinbg(Session *); static void mac_adjustsize(Session *, int, int); @@ -113,7 +122,7 @@ static void inbuf_putstr(Session *s, const char *c) { static void display_resource(Session *s, unsigned long type, short id) { Handle h; - int len, i; + int len; char *t; h = GetResource(type, id); @@ -129,19 +138,51 @@ static void display_resource(Session *s, unsigned long type, short id) { DisposeHandle(h); } - -void mac_newsession(void) { +void mac_opensession(void) { Session *s; - UInt32 starttime; - char msg[128]; - OSErr err; + StandardFileReply sfr; + static const OSType sftypes[] = { 'Sess', 0, 0, 0 }; + void *sesshandle; + int i; - /* This should obviously be initialised by other means */ s = smalloc(sizeof(*s)); memset(s, 0, sizeof(*s)); - do_defaults(NULL, &s->cfg); - s->back = &loop_backend; - + + StandardGetFile(NULL, 1, sftypes, &sfr); + if (!sfr.sfGood) goto fail; + + sesshandle = open_settings_r_fsp(&sfr.sfFile); + if (sesshandle == NULL) goto fail; + load_open_settings(sesshandle, TRUE, &s->cfg); + close_settings_r(sesshandle); + + /* + * Select protocol. This is farmed out into a table in a + * separate file to enable an ssh-free variant. + */ + s->back = NULL; + for (i = 0; backends[i].backend != NULL; i++) + if (backends[i].protocol == cfg.protocol) { + s->back = backends[i].backend; + break; + } + if (s->back == NULL) { + fatalbox("Unsupported protocol number found"); + } + mac_startsession(s); + return; + + fail: + sfree(s); + return; +} + +void mac_startsession(Session *s) +{ + UInt32 starttime; + char msg[128]; + char *errmsg; + /* XXX: Own storage management? */ if (HAVE_COLOR_QD()) s->window = GetNewCWindow(wTerminal, NULL, (WindowPtr)-1); @@ -151,10 +192,21 @@ void mac_newsession(void) { s->scrollbar = GetNewControl(cVScroll, s->window); s->term = term_init(&s->cfg, s); + mac_initfont(s); + mac_initpalette(s); + if (HAVE_COLOR_QD()) { + /* Set to FALSE to not get palette updates in the background. */ + SetPalette(s->window, s->palette, TRUE); + ActivatePalette(s->window); + } + s->logctx = log_init(s); term_provide_logctx(s->term, s->logctx); - s->back->init(s->term, &s->backhandle, "localhost", 23, &s->realhost, 0); + errmsg = s->back->init(s->term, &s->backhandle, s->cfg.host, s->cfg.port, + &s->realhost, s->cfg.tcp_nodelay); + if (errmsg != NULL) + inbuf_putstr(s, errmsg); s->back->provide_logctx(s->backhandle, s->logctx); term_provide_resize_fn(s->term, s->back->size, s->backhandle); @@ -165,13 +217,6 @@ void mac_newsession(void) { s->ldisc = ldisc_create(&s->cfg, s->term, s->back, s->backhandle, s); ldisc_send(s->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */ - mac_initfont(s); - mac_initpalette(s); - if (HAVE_COLOR_QD()) { - /* Set to FALSE to not get palette updates in the background. */ - SetPalette(s->window, s->palette, TRUE); - ActivatePalette(s->window); - } ShowWindow(s->window); starttime = TickCount(); display_resource(s, 'pTST', 128); @@ -180,10 +225,14 @@ void mac_newsession(void) { term_out(s->term); } +static UnicodeToTextFallbackUPP uni_to_font_fallback_upp; + static void mac_initfont(Session *s) { Str255 macfont; FontInfo fi; - + TextEncoding enc; + OptionBits fbflags; + SetPort(s->window); macfont[0] = sprintf((char *)&macfont[1], "%s", s->cfg.font); GetFNum(macfont, &s->fontnum); @@ -200,9 +249,58 @@ static void mac_initfont(Session *s) { s->font_boldadjust = s->font_width - CharWidth('W'); } else s->font_boldadjust = 0; + + if (s->uni_to_font != NULL) + DisposeUnicodeToTextInfo(&s->uni_to_font); + if (mac_gestalts.encvvers != 0 && + UpgradeScriptInfoToTextEncoding(kTextScriptDontCare, + kTextLanguageDontCare, + kTextRegionDontCare, macfont, + &enc) == noErr && + CreateUnicodeToTextInfoByEncoding(enc, &s->uni_to_font) == noErr) { + if (uni_to_font_fallback_upp == NULL) + uni_to_font_fallback_upp = + NewUnicodeToTextFallbackProc(&uni_to_font_fallback); + fbflags = kUnicodeFallbackCustomOnly; + if (mac_gestalts.uncvattr & kTECAddFallbackInterruptMask) + fbflags |= kUnicodeFallbackInterruptSafeMask; + if (SetFallbackUnicodeToText(s->uni_to_font, + uni_to_font_fallback_upp, fbflags, NULL) != noErr) { + DisposeUnicodeToTextInfo(&s->uni_to_font); + goto no_encv; + } + } else { + no_encv: + s->uni_to_font = NULL; + s->font_charset = + charset_from_macenc(FontToScript(s->fontnum), + GetScriptManagerVariable(smRegionCode), + mac_gestalts.sysvers, s->cfg.font); + } + mac_adjustsize(s, s->term->rows, s->term->cols); } +static pascal OSStatus uni_to_font_fallback(UniChar *ucp, + ByteCount ilen, ByteCount *iusedp, TextPtr obuf, ByteCount olen, + ByteCount *ousedp, LogicalAddress *cookie, ConstUnicodeMappingPtr mapping) +{ + + if (olen < 1) + return kTECOutputBufferFullStatus; + /* + * What I'd _like_ to do here is to somehow generate the + * missing-character glyph that every font is required to have. + * Unfortunately (and somewhat surprisingly), I can't find any way + * to actually ask for it explicitly. Bah. + */ + *obuf = '.'; + *iusedp = ilen; + *ousedp = 1; + return noErr; +} + + /* * To be called whenever the window size changes. * rows and cols should be desired values. @@ -223,7 +321,6 @@ static void mac_adjustsize(Session *s, int newrows, int newcols) { } static void mac_initpalette(Session *s) { - int i; if (!HAVE_COLOR_QD()) return; @@ -258,7 +355,7 @@ static void mac_adjustwinbg(Session *s) { if (!HAVE_COLOR_QD()) return; -#if TARGET_RT_CFM /* XXX doesn't link (at least for 68k) */ +#if !TARGET_CPU_68K if (mac_gestalts.windattr & gestaltWindowMgrPresent) SetWindowContentColor(s->window, &(*s->palette)->pmInfo[DEFAULT_BG].ciRGB); @@ -714,7 +811,7 @@ void request_paste(void *frontend) static struct { Rect msgrect; Point msgorigin; - Point startmouse; + Point zeromouse; Session *s; char oldmsg[20]; } growterm_state; @@ -732,7 +829,9 @@ void mac_growterm(WindowPtr window, EventRecord *event) { draghooksave = LMGetDragHook(); growterm_state.oldmsg[0] = '\0'; - growterm_state.startmouse = event->where; + growterm_state.zeromouse = event->where; + growterm_state.zeromouse.h -= s->term->cols * s->font_width; + growterm_state.zeromouse.v -= s->term->rows * s->font_height; growterm_state.s = s; GetPort(&portsave); SetPort(s->window); @@ -773,11 +872,9 @@ static pascal void mac_growtermdraghook(void) int newrows, newcols; GetMouse(&mouse); - newrows = (mouse.v - growterm_state.startmouse.v) / s->font_height + - s->term->rows; + newrows = (mouse.v - growterm_state.zeromouse.v) / s->font_height; if (newrows < 1) newrows = 1; - newcols = (mouse.h - growterm_state.startmouse.h) / s->font_width + - s->term->cols; + newcols = (mouse.h - growterm_state.zeromouse.h) / s->font_width; if (newcols < 1) newcols = 1; sprintf(buf, "%dx%d", newcols, newrows); if (strcmp(buf, growterm_state.oldmsg) == 0) @@ -879,6 +976,14 @@ void do_text(Context ctx, int x, int y, char *text, int len, int style = 0; struct do_text_args a; RgnHandle textrgn; + char mactextbuf[1024]; + UniChar unitextbuf[1024]; + wchar_t *unitextptr; + int i; + ByteCount iread, olen; + OSStatus err; + + assert(len <= 1024); SetPort(s->window); @@ -890,9 +995,28 @@ void do_text(Context ctx, int x, int y, char *text, int len, if (!RectInRgn(&a.textrect, s->window->visRgn)) return; + /* Unpack Unicode from the mad format we get passed */ + for (i = 0; i < len; i++) + unitextbuf[i] = (unsigned char)text[i] | (attr & CSET_MASK); + + if (s->uni_to_font != NULL) { + err = ConvertFromUnicodeToText(s->uni_to_font, len * sizeof(UniChar), + unitextbuf, kUnicodeUseFallbacksMask, + 0, NULL, NULL, NULL, + 1024, &iread, &olen, mactextbuf); + if (err != noErr && err != kTECUsedFallbacksStatus) + olen = 0; + } else if (s->font_charset != CS_NONE) { + /* XXX this is bogus if wchar_t and UniChar are different sizes. */ + unitextptr = (wchar_t *)unitextbuf; + olen = charset_from_unicode(&unitextptr, &len, mactextbuf, 1024, + s->font_charset, NULL, ".", 1); + } else + olen = 0; + a.s = s; - a.text = text; - a.len = len; + a.text = mactextbuf; + a.len = olen; a.attr = attr; a.lattr = lattr; a.numer.h = a.numer.v = a.denom.h = a.denom.v = 1; @@ -1075,8 +1199,7 @@ void set_sbar(void *frontend, int total, int start, int page) { (*s->scrollbar)->contrlMin = 0; (*s->scrollbar)->contrlMax = total - page; SetControlValue(s->scrollbar, start); -#if TARGET_RT_CFM - /* XXX: This doesn't link for me. */ +#if !TARGET_CPU_68K if (mac_gestalts.cntlattr & gestaltControlMgrPresent) SetControlViewSize(s->scrollbar, page); #endif @@ -1386,7 +1509,7 @@ void do_scroll(void *frontend, int topline, int botline, int lines) { void logevent(void *frontend, char *str) { - /* XXX Do something */ + fprintf(stderr, "%s\n", str); } /* Dummy routine, only required in plink. */