X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/379836ca8d2a2260899cbbd84d273ddf3e044f74..b537dd42c1da03890c832e94a4f47369ca3d99af:/mac/macterm.c diff --git a/mac/macterm.c b/mac/macterm.c index 3de1d582..b24e3d46 100644 --- a/mac/macterm.c +++ b/mac/macterm.c @@ -1,4 +1,4 @@ -/* $Id: macterm.c,v 1.31 2003/01/02 00:33:40 ben Exp $ */ +/* $Id: macterm.c,v 1.52 2003/01/18 20:09:21 ben Exp $ */ /* * Copyright (c) 1999 Simon Tatham * Copyright (c) 1999, 2002 Ben Harris @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -46,9 +47,7 @@ #include #include #include -#include #include -#include #include #include @@ -62,7 +61,6 @@ #include "putty.h" #include "charset.h" #include "mac.h" -#include "storage.h" #include "terminal.h" #define NCOLOURS (lenof(((Config *)0)->colours)) @@ -109,65 +107,11 @@ static RoutineDescriptor do_text_for_device_upp = #define do_text_for_device_upp do_text_for_device #endif /* not TARGET_RT_MAC_CFM */ -static void inbuf_putc(Session *s, int c) { - char ch = c; - - from_backend(s->term, 0, &ch, 1); -} - -static void inbuf_putstr(Session *s, const char *c) { - - from_backend(s->term, 0, (char *)c, strlen(c)); -} - -static void display_resource(Session *s, unsigned long type, short id) { - Handle h; - int len; - char *t; - - h = GetResource(type, id); - if (h == NULL) - fatalbox("Can't get test resource"); - len = GetResourceSizeOnDisk(h); - DetachResource(h); - HNoPurge(h); - HLock(h); - t = *h; - from_backend(s->term, 0, t, len); - term_out(s->term); - DisposeHandle(h); -} - -void mac_opensession(void) { - Session *s; - StandardFileReply sfr; - static const OSType sftypes[] = { 'Sess', 0, 0, 0 }; - void *sesshandle; - - s = smalloc(sizeof(*s)); - memset(s, 0, sizeof(*s)); - - 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); - s->back = &loop_backend; - mac_startsession(s); - return; - - fail: - sfree(s); - return; -} - void mac_startsession(Session *s) { - UInt32 starttime; - char msg[128]; + char *errmsg; + init_ucs(s); /* XXX: Own storage management? */ if (HAVE_COLOR_QD()) s->window = GetNewCWindow(wTerminal, NULL, (WindowPtr)-1); @@ -175,13 +119,25 @@ void mac_startsession(Session *s) s->window = GetNewWindow(wTerminal, NULL, (WindowPtr)-1); SetWRefCon(s->window, (long)s); s->scrollbar = GetNewControl(cVScroll, s->window); - s->term = term_init(&s->cfg, s); + s->term = term_init(&s->cfg, &s->ucsdata, s); - s->logctx = log_init(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, &s->cfg); 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, s->cfg.host, + s->cfg.port, &s->realhost, s->cfg.tcp_nodelay); + if (errmsg != NULL) + fatalbox("%s", errmsg); s->back->provide_logctx(s->backhandle, s->logctx); + set_title(s, s->realhost); term_provide_resize_fn(s->term, s->back->size, s->backhandle); @@ -191,19 +147,47 @@ void mac_startsession(Session *s) 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); - sprintf(msg, "Elapsed ticks: %d\015\012", TickCount() - starttime); - inbuf_putstr(s, msg); - term_out(s->term); + s->next = sesslist; + s->prev = &sesslist; + if (s->next != NULL) + s->next->prev = &s->next; + sesslist = s; +} + +/* + * Try to work out a horizontal scaling factor for the current font + * that will give a chracter width of wantwidth. Return it in numer + * and denom (suitable for passing to StdText()). + */ +static void mac_workoutfontscale(Session *s, int wantwidth, + Point *numerp, Point *denomp) +{ + Point numer, denom, tmpnumer, tmpdenom; + int gotwidth, i; + const char text = 'W'; + FontInfo fi; + + numer.v = denom.v = 1; /* always */ + numer.h = denom.h = 1; + for (i = 0; i < 3; i++) { + tmpnumer = numer; + tmpdenom = denom; + if (s->window->grafProcs != NULL) + gotwidth = InvokeQDTxMeasUPP(1, &text, &tmpnumer, &tmpdenom, &fi, + s->window->grafProcs->txMeasProc); + else + gotwidth = StdTxMeas(1, &text, &tmpnumer, &tmpdenom, &fi); + /* The result of StdTxMeas must be scaled by the factors it returns. */ + gotwidth = FixRound(FixMul(gotwidth << 16, + FixRatio(tmpnumer.h, tmpdenom.h))); + if (gotwidth == wantwidth) + break; + numer.h *= wantwidth; + denom.h *= gotwidth; + } + *numerp = numer; + *denomp = denom; } static UnicodeToTextFallbackUPP uni_to_font_fallback_upp; @@ -215,7 +199,7 @@ static void mac_initfont(Session *s) { OptionBits fbflags; SetPort(s->window); - macfont[0] = sprintf((char *)&macfont[1], "%s", s->cfg.font); + c2pstrcpy(macfont, s->cfg.font); GetFNum(macfont, &s->fontnum); TextFont(s->fontnum); TextFace(s->cfg.fontisbold ? bold : 0); @@ -225,6 +209,14 @@ static void mac_initfont(Session *s) { s->font_ascent = fi.ascent; s->font_leading = fi.leading; s->font_height = s->font_ascent + fi.descent + s->font_leading; + mac_workoutfontscale(s, s->font_width, + &s->font_stdnumer, &s->font_stddenom); + mac_workoutfontscale(s, s->font_width * 2, + &s->font_widenumer, &s->font_widedenom); + TextSize(s->cfg.fontheight * 2); + mac_workoutfontscale(s, s->font_width * 2, + &s->font_bignumer, &s->font_bigdenom); + TextSize(s->cfg.fontheight); if (!s->cfg.bold_colour) { TextFace(bold); s->font_boldadjust = s->font_width - CharWidth('W'); @@ -281,6 +273,18 @@ static pascal OSStatus uni_to_font_fallback(UniChar *ucp, return noErr; } +/* + * Called every time round the event loop. + */ +void mac_pollterm(void) +{ + Session *s; + + for (s = sesslist; s != NULL; s = s->next) { + term_out(s->term); + term_update(s->term); + } +} /* * To be called whenever the window size changes. @@ -336,7 +340,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); @@ -396,6 +400,9 @@ void mac_adjusttermmenus(WindowPtr window) { long offset; s = (Session *)GetWRefCon(window); + menu = GetMenuHandle(mFile); + DisableItem(menu, iSave); /* XXX enable if modified */ + EnableItem(menu, iSaveAs); menu = GetMenuHandle(mEdit); EnableItem(menu, 0); DisableItem(menu, iUndo); @@ -792,7 +799,7 @@ void request_paste(void *frontend) static struct { Rect msgrect; Point msgorigin; - Point startmouse; + Point zeromouse; Session *s; char oldmsg[20]; } growterm_state; @@ -810,7 +817,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); @@ -848,29 +857,47 @@ static pascal void mac_growtermdraghook(void) GrafPtr portsave; Point mouse; char buf[20]; + unsigned char pbuf[20]; 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) return; strcpy(growterm_state.oldmsg, buf); - c2pstr(buf); + c2pstrcpy(pbuf, buf); GetPort(&portsave); SetPort(growterm_state.s->window); EraseRect(&growterm_state.msgrect); MoveTo(growterm_state.msgorigin.h, growterm_state.msgorigin.v); - DrawString((StringPtr)buf); + DrawString(pbuf); SetPort(portsave); } +void mac_closeterm(WindowPtr window) +{ + Session *s = (Session *)GetWRefCon(window); + + /* XXX warn on close */ + HideWindow(s->window); + *s->prev = s->next; + s->next->prev = s->prev; + ldisc_free(s->ldisc); + s->back->free(s->backhandle); + log_free(s->logctx); + if (s->uni_to_font != NULL) + DisposeUnicodeToTextInfo(&s->uni_to_font); + term_free(s->term); + DisposeWindow(s->window); + DisposePalette(s->palette); + sfree(s); +} + void mac_activateterm(WindowPtr window, Boolean active) { Session *s; @@ -956,23 +983,29 @@ void do_text(Context ctx, int x, int y, char *text, int len, Session *s = ctx; int style = 0; struct do_text_args a; - RgnHandle textrgn; + RgnHandle textrgn, saveclip; char mactextbuf[1024]; UniChar unitextbuf[1024]; wchar_t *unitextptr; - int i; + int i, fontwidth; ByteCount iread, olen; OSStatus err; assert(len <= 1024); SetPort(s->window); - + + fontwidth = s->font_width; + if ((lattr & LATTR_MODE) != LATTR_NORM) + fontwidth *= 2; + /* First check this text is relevant */ a.textrect.top = y * s->font_height; a.textrect.bottom = (y + 1) * s->font_height; - a.textrect.left = x * s->font_width; - a.textrect.right = (x + len) * s->font_width; + a.textrect.left = x * fontwidth; + a.textrect.right = (x + len) * fontwidth; + if (a.textrect.right > s->term->cols * s->font_width) + a.textrect.right = s->term->cols * s->font_width; if (!RectInRgn(&a.textrect, s->window->visRgn)) return; @@ -1000,7 +1033,24 @@ void do_text(Context ctx, int x, int y, char *text, int len, a.len = olen; a.attr = attr; a.lattr = lattr; - a.numer.h = a.numer.v = a.denom.h = a.denom.v = 1; + switch (lattr & LATTR_MODE) { + case LATTR_NORM: + TextSize(s->cfg.fontheight); + a.numer = s->font_stdnumer; + a.denom = s->font_stddenom; + break; + case LATTR_WIDE: + TextSize(s->cfg.fontheight); + a.numer = s->font_widenumer; + a.denom = s->font_widedenom; + break; + case LATTR_TOP: + case LATTR_BOT: + TextSize(s->cfg.fontheight * 2); + a.numer = s->font_bignumer; + a.denom = s->font_bigdenom; + break; + } SetPort(s->window); TextFont(s->fontnum); if (s->cfg.fontisbold || (attr & ATTR_BOLD) && !s->cfg.bold_colour) @@ -1008,7 +1058,6 @@ void do_text(Context ctx, int x, int y, char *text, int len, if (attr & ATTR_UNDER) style |= underline; TextFace(style); - TextSize(s->cfg.fontheight); TextMode(srcOr); if (HAVE_COLOR_QD()) if (style & bold) { @@ -1018,12 +1067,17 @@ void do_text(Context ctx, int x, int y, char *text, int len, SpaceExtra(0); CharExtra(0); } + saveclip = NewRgn(); + GetClip(saveclip); + ClipRect(&a.textrect); textrgn = NewRgn(); RectRgn(textrgn, &a.textrect); if (HAVE_COLOR_QD()) DeviceLoop(textrgn, &do_text_for_device_upp, (long)&a, 0); else do_text_for_device(1, 0, NULL, (long)&a); + SetClip(saveclip); + DisposeRgn(saveclip); DisposeRgn(textrgn); /* Tell the window manager about it in case this isn't an update */ ValidRect(&a.textrect); @@ -1079,7 +1133,19 @@ static pascal void do_text_for_device(short depth, short devflags, } EraseRect(&a->textrect); - MoveTo(a->textrect.left, a->textrect.top + a->s->font_ascent); + switch (a->lattr & LATTR_MODE) { + case LATTR_NORM: + case LATTR_WIDE: + MoveTo(a->textrect.left, a->textrect.top + a->s->font_ascent); + break; + case LATTR_TOP: + MoveTo(a->textrect.left, a->textrect.top + a->s->font_ascent * 2); + break; + case LATTR_BOT: + MoveTo(a->textrect.left, + a->textrect.top - a->s->font_height + a->s->font_ascent * 2); + break; + } /* FIXME: Sort out bold width adjustments on Original QuickDraw. */ if (a->s->window->grafProcs != NULL) InvokeQDTextUPP(a->len, a->text, a->numer, a->denom, @@ -1180,8 +1246,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 @@ -1234,7 +1299,7 @@ void set_title(void *frontend, char *title) { Session *s = frontend; Str255 mactitle; - mactitle[0] = sprintf((char *)&mactitle[1], "%s", title); + c2pstrcpy(mactitle, title); SetWTitle(s->window, mactitle); } @@ -1255,8 +1320,7 @@ void set_raw_mouse_mode(void *frontend, int activate) void request_resize(void *frontend, int w, int h) { Session *s = frontend; - s->term->cols = w; - s->term->rows = h; + term_size(s->term, h, w, s->cfg.savelines); mac_initfont(s); } @@ -1367,9 +1431,12 @@ void get_window_pixels(void *frontend, int *x, int *y) char *get_window_title(void *frontend, int icon) { Session *s = frontend; + Str255 ptitle; + static char title[256]; - /* Erm, we don't save this at the moment */ - return ""; + GetWTitle(s->window, ptitle); + p2cstrcpy(title, ptitle); + return title; } /* @@ -1491,7 +1558,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. */