X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/37ea5668ad31c1ae5427fa5fa0fae7143d5e6ddf..39934deb5202149f98198c111a35c21cb4d0d0f8:/mac/macterm.c diff --git a/mac/macterm.c b/mac/macterm.c index 76439fbc..5831cd26 100644 --- a/mac/macterm.c +++ b/mac/macterm.c @@ -1,4 +1,4 @@ -/* $Id: macterm.c,v 1.60 2003/01/28 00:35:54 ben Exp $ */ +/* $Id$ */ /* * Copyright (c) 1999 Simon Tatham * Copyright (c) 1999, 2002 Ben Harris @@ -80,7 +80,7 @@ static void mac_initfont(Session *); static pascal OSStatus uni_to_font_fallback(UniChar *, ByteCount, ByteCount *, TextPtr, ByteCount, ByteCount *, - LogicalAddress *, + LogicalAddress, ConstUnicodeMappingPtr); static void mac_initpalette(Session *); static void mac_adjustwinbg(Session *); @@ -90,26 +90,24 @@ static pascal void mac_growtermdraghook(void); static pascal void mac_scrolltracker(ControlHandle, short); static pascal void do_text_for_device(short, short, GDHandle, long); static void text_click(Session *, EventRecord *); +static void mac_activateterm(WindowPtr, EventRecord *); +static void mac_adjusttermcursor(WindowPtr, Point, RgnHandle); +static void mac_adjusttermmenus(WindowPtr); +static void mac_updateterm(WindowPtr); +static void mac_clickterm(WindowPtr, EventRecord *); +static void mac_growterm(WindowPtr, EventRecord *); +static void mac_keyterm(WindowPtr, EventRecord *); +static void mac_menuterm(WindowPtr, short, short); +static void mac_closeterm(WindowPtr); void pre_paint(Session *s); void post_paint(Session *s); -#if TARGET_RT_MAC_CFM -static RoutineDescriptor mac_scrolltracker_upp = - BUILD_ROUTINE_DESCRIPTOR(uppControlActionProcInfo, - (ProcPtr)mac_scrolltracker); -static RoutineDescriptor do_text_for_device_upp = - BUILD_ROUTINE_DESCRIPTOR(uppDeviceLoopDrawingProcInfo, - (ProcPtr)do_text_for_device); -#else /* not TARGET_RT_MAC_CFM */ -#define mac_scrolltracker_upp mac_scrolltracker -#define do_text_for_device_upp do_text_for_device -#endif /* not TARGET_RT_MAC_CFM */ - void mac_startsession(Session *s) { - char *errmsg; + const char *errmsg; int i; + WinInfo *wi; init_ucs(s); @@ -131,7 +129,20 @@ void mac_startsession(Session *s) s->window = GetNewCWindow(wTerminal, NULL, (WindowPtr)-1); else s->window = GetNewWindow(wTerminal, NULL, (WindowPtr)-1); - SetWRefCon(s->window, (long)s); + wi = snew(WinInfo); + memset(wi, 0, sizeof(*wi)); + wi->s = s; + wi->wtype = wTerminal; + wi->activate = &mac_activateterm; + wi->adjustcursor = &mac_adjusttermcursor; + wi->adjustmenus = &mac_adjusttermmenus; + wi->update = &mac_updateterm; + wi->click = &mac_clickterm; + wi->grow = &mac_growterm; + wi->key = &mac_keyterm; + wi->menu = &mac_menuterm; + wi->close = &mac_closeterm; + SetWRefCon(s->window, (long)wi); s->scrollbar = GetNewControl(cVScroll, s->window); s->term = term_init(&s->cfg, &s->ucsdata, s); @@ -143,11 +154,12 @@ void mac_startsession(Session *s) ActivatePalette(s->window); } - s->logctx = log_init(s, &s->cfg); + s->logctx = log_init(s->term, &s->cfg); term_provide_logctx(s->term, s->logctx); - errmsg = s->back->init(s->term, &s->backhandle, &s->cfg, s->cfg.host, - s->cfg.port, &s->realhost, s->cfg.tcp_nodelay); + errmsg = s->back->init(s, &s->backhandle, &s->cfg, s->cfg.host, + s->cfg.port, &s->realhost, s->cfg.tcp_nodelay, + s->cfg.tcp_keepalives); if (errmsg != NULL) fatalbox("%s", errmsg); s->back->provide_logctx(s->backhandle, s->logctx); @@ -181,15 +193,20 @@ static void mac_workoutfontscale(Session *s, int wantwidth, int gotwidth, i; const char text = 'W'; FontInfo fi; +#if TARGET_API_MAC_CARBON + CQDProcsPtr gp = GetPortGrafProcs(GetWindowPort(s->window)); +#else + QDProcsPtr gp = s->window->grafProcs; +#endif 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) + if (gp != NULL) gotwidth = InvokeQDTxMeasUPP(1, &text, &tmpnumer, &tmpdenom, &fi, - s->window->grafProcs->txMeasProc); + gp->txMeasProc); else gotwidth = StdTxMeas(1, &text, &tmpnumer, &tmpdenom, &fi); /* The result of StdTxMeas must be scaled by the factors it returns. */ @@ -206,18 +223,17 @@ static void mac_workoutfontscale(Session *s, int wantwidth, static UnicodeToTextFallbackUPP uni_to_font_fallback_upp; -static void mac_initfont(Session *s) { - Str255 macfont; +static void mac_initfont(Session *s) +{ FontInfo fi; TextEncoding enc; OptionBits fbflags; - SetPort(s->window); - c2pstrcpy(macfont, s->cfg.font); - GetFNum(macfont, &s->fontnum); + SetPort((GrafPtr)GetWindowPort(s->window)); + GetFNum(s->cfg.font.name, &s->fontnum); TextFont(s->fontnum); - TextFace(s->cfg.fontisbold ? bold : 0); - TextSize(s->cfg.fontheight); + TextFace(s->cfg.font.face); + TextSize(s->cfg.font.size); GetFontInfo(&fi); s->font_width = CharWidth('W'); /* Well, it's what NCSA uses. */ s->font_ascent = fi.ascent; @@ -227,10 +243,10 @@ static void mac_initfont(Session *s) { &s->font_stdnumer, &s->font_stddenom); mac_workoutfontscale(s, s->font_width * 2, &s->font_widenumer, &s->font_widedenom); - TextSize(s->cfg.fontheight * 2); + TextSize(s->cfg.font.size * 2); mac_workoutfontscale(s, s->font_width * 2, &s->font_bignumer, &s->font_bigdenom); - TextSize(s->cfg.fontheight); + TextSize(s->cfg.font.size); if (!s->cfg.bold_colour) { TextFace(bold); s->font_boldadjust = s->font_width - CharWidth('W'); @@ -242,12 +258,12 @@ static void mac_initfont(Session *s) { if (mac_gestalts.encvvers != 0 && UpgradeScriptInfoToTextEncoding(kTextScriptDontCare, kTextLanguageDontCare, - kTextRegionDontCare, macfont, + kTextRegionDontCare, s->cfg.font.name, &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); + NewUnicodeToTextFallbackUPP(&uni_to_font_fallback); fbflags = kUnicodeFallbackCustomOnly; if (mac_gestalts.uncvattr & kTECAddFallbackInterruptMask) fbflags |= kUnicodeFallbackInterruptSafeMask; @@ -257,12 +273,15 @@ static void mac_initfont(Session *s) { goto no_encv; } } else { + char cfontname[256]; + no_encv: s->uni_to_font = NULL; + p2cstrcpy(cfontname, s->cfg.font.name); s->font_charset = charset_from_macenc(FontToScript(s->fontnum), GetScriptManagerVariable(smRegionCode), - mac_gestalts.sysvers, s->cfg.font); + mac_gestalts.sysvers, cfontname); } mac_adjustsize(s, s->term->rows, s->term->cols); @@ -270,7 +289,7 @@ static void mac_initfont(Session *s) { static pascal OSStatus uni_to_font_fallback(UniChar *ucp, ByteCount ilen, ByteCount *iusedp, TextPtr obuf, ByteCount olen, - ByteCount *ousedp, LogicalAddress *cookie, ConstUnicodeMappingPtr mapping) + ByteCount *ousedp, LogicalAddress cookie, ConstUnicodeMappingPtr mapping) { if (olen < 1) @@ -295,7 +314,6 @@ void mac_pollterm(void) Session *s; for (s = sesslist; s != NULL; s = s->next) { - term_out(s->term); term_update(s->term); } } @@ -319,7 +337,8 @@ static void mac_adjustsize(Session *s, int newrows, int newcols) { mac_drawgrowicon(s); } -static void mac_initpalette(Session *s) { +static void mac_initpalette(Session *s) +{ if (!HAVE_COLOR_QD()) return; @@ -350,7 +369,8 @@ static void mac_initpalette(Session *s) { * Set the background colour of the window correctly. Should be * called whenever the default background changes. */ -static void mac_adjustwinbg(Session *s) { +static void mac_adjustwinbg(Session *s) +{ if (!HAVE_COLOR_QD()) return; @@ -361,6 +381,7 @@ static void mac_adjustwinbg(Session *s) { else #endif { +#if !TARGET_API_MAC_CARBON if (s->wctab == NULL) s->wctab = (WCTabHandle)NewHandle(sizeof(**s->wctab)); if (s->wctab == NULL) @@ -371,49 +392,79 @@ static void mac_adjustwinbg(Session *s) { (*s->wctab)->ctTable[0].value = wContentColor; (*s->wctab)->ctTable[0].rgb = (*s->palette)->pmInfo[DEFAULT_BG].ciRGB; SetWinColor(s->window, s->wctab); +#endif } } /* * Set the cursor shape correctly */ -void mac_adjusttermcursor(WindowPtr window, Point mouse, RgnHandle cursrgn) { +static void mac_adjusttermcursor(WindowPtr window, Point mouse, + RgnHandle cursrgn) +{ Session *s; ControlHandle control; short part; int x, y; +#if TARGET_API_MAC_CARBON + Cursor arrow; + Rect rect; + RgnHandle visrgn; +#endif - SetPort(window); - s = (Session *)GetWRefCon(window); + SetPort((GrafPtr)GetWindowPort(window)); + s = mac_windowsession(window); GlobalToLocal(&mouse); part = FindControl(mouse, window, &control); if (control == s->scrollbar) { +#if TARGET_API_MAC_CARBON + SetCursor(GetQDGlobalsArrow(&arrow)); + RectRgn(cursrgn, GetControlBounds(s->scrollbar, &rect)); +#else SetCursor(&qd.arrow); RectRgn(cursrgn, &(*s->scrollbar)->contrlRect); - SectRgn(cursrgn, window->visRgn, cursrgn); +#endif } else { x = mouse.h / s->font_width; y = mouse.v / s->font_height; - if (s->raw_mouse) + if (s->raw_mouse) { +#if TARGET_API_MAC_CARBON + SetCursor(GetQDGlobalsArrow(&arrow)); +#else SetCursor(&qd.arrow); - else +#endif + } else SetCursor(*GetCursor(iBeamCursor)); /* Ask for shape changes if we leave this character cell. */ SetRectRgn(cursrgn, x * s->font_width, y * s->font_height, (x + 1) * s->font_width, (y + 1) * s->font_height); - SectRgn(cursrgn, window->visRgn, cursrgn); } +#if TARGET_API_MAC_CARBON + visrgn = NewRgn(); + GetPortVisibleRegion(GetWindowPort(window), visrgn); + SectRgn(cursrgn, visrgn, cursrgn); + DisposeRgn(visrgn); +#else + SectRgn(cursrgn, window->visRgn, cursrgn); +#endif } /* * Enable/disable menu items based on the active terminal window. */ -void mac_adjusttermmenus(WindowPtr window) { +#if TARGET_API_MAC_CARBON +#define DisableItem DisableMenuItem +#define EnableItem EnableMenuItem +#endif +static void mac_adjusttermmenus(WindowPtr window) +{ Session *s; MenuHandle menu; +#if !TARGET_API_MAC_CARBON long offset; +#endif - s = (Session *)GetWRefCon(window); + s = mac_windowsession(window); menu = GetMenuHandle(mFile); DisableItem(menu, iSave); /* XXX enable if modified */ EnableItem(menu, iSaveAs); @@ -426,18 +477,26 @@ void mac_adjusttermmenus(WindowPtr window) { EnableItem(menu, iCopy); else DisableItem(menu, iCopy); - if (GetScrap(NULL, 'TEXT', &offset) == noTypeErr) +#if TARGET_API_MAC_CARBON + if (1) +#else + if (GetScrap(NULL, kScrapFlavorTypeText, &offset) == noTypeErr) +#endif DisableItem(menu, iPaste); else EnableItem(menu, iPaste); DisableItem(menu, iClear); EnableItem(menu, iSelectAll); + menu = GetMenuHandle(mWindow); + EnableItem(menu, 0); + EnableItem(menu, iShowEventLog); } -void mac_menuterm(WindowPtr window, short menu, short item) { +static void mac_menuterm(WindowPtr window, short menu, short item) +{ Session *s; - s = (Session *)GetWRefCon(window); + s = mac_windowsession(window); switch (menu) { case mEdit: switch (item) { @@ -448,17 +507,27 @@ void mac_menuterm(WindowPtr window, short menu, short item) { term_do_paste(s->term); break; } + break; + case mWindow: + switch(item) { + case iShowEventLog: + mac_showeventlog(s); + break; + } + break; } } -void mac_clickterm(WindowPtr window, EventRecord *event) { +static void mac_clickterm(WindowPtr window, EventRecord *event) +{ Session *s; Point mouse; ControlHandle control; int part; + static ControlActionUPP mac_scrolltracker_upp = NULL; - s = (Session *)GetWRefCon(window); - SetPort(window); + s = mac_windowsession(window); + SetPort((GrafPtr)GetWindowPort(window)); mouse = event->where; GlobalToLocal(&mouse); part = FindControl(mouse, window, &control); @@ -472,7 +541,10 @@ void mac_clickterm(WindowPtr window, EventRecord *event) { case kControlDownButtonPart: case kControlPageUpPart: case kControlPageDownPart: - TrackControl(control, mouse, &mac_scrolltracker_upp); + if (mac_scrolltracker_upp == NULL) + mac_scrolltracker_upp = + NewControlActionUPP(&mac_scrolltracker); + TrackControl(control, mouse, mac_scrolltracker_upp); break; } } else { @@ -480,7 +552,8 @@ void mac_clickterm(WindowPtr window, EventRecord *event) { } } -static void text_click(Session *s, EventRecord *event) { +static void text_click(Session *s, EventRecord *event) +{ Point localwhere; int row, col; static UInt32 lastwhen = 0; @@ -488,7 +561,7 @@ static void text_click(Session *s, EventRecord *event) { static int lastrow = -1, lastcol = -1; static Mouse_Action lastact = MA_NOTHING; - SetPort(s->window); + SetPort((GrafPtr)GetWindowPort(s->window)); localwhere = event->where; GlobalToLocal(&localwhere); @@ -531,6 +604,7 @@ static void text_click(Session *s, EventRecord *event) { void write_clip(void *cookie, wchar_t *data, int len, int must_deselect) { +#if !TARGET_API_MAC_CARBON Session *s = cookie; char *mactextbuf; ByteCount iread, olen; @@ -548,14 +622,14 @@ void write_clip(void *cookie, wchar_t *data, int len, int must_deselect) */ if (ZeroScrap() != noErr) return; - PutScrap(len * sizeof(*data), 'utxt', data); + PutScrap(len * sizeof(*data), kScrapFlavorTypeUnicode, data); /* Replace LINE SEPARATORs with CR for TEXT output. */ for (i = 0; i < len; i++) if (data[i] == 0x2028) data[i] = 0x000d; - mactextbuf = smalloc(len); /* XXX DBCS */ + mactextbuf = snewn(len, char); /* XXX DBCS */ if (s->uni_to_font != NULL) { err = ConvertFromUnicodeToText(s->uni_to_font, len * sizeof(UniChar), (UniChar *)data, @@ -570,7 +644,7 @@ void write_clip(void *cookie, wchar_t *data, int len, int must_deselect) s->font_charset, NULL, ".", 1); } else return; - PutScrap(olen, 'TEXT', mactextbuf); + PutScrap(olen, kScrapFlavorTypeText, mactextbuf); sfree(mactextbuf); stsz = offsetof(StScrpRec, scrpStyleTab) + sizeof(ScrpSTElement); @@ -581,15 +655,20 @@ void write_clip(void *cookie, wchar_t *data, int len, int must_deselect) stsc->scrpStyleTab[0].scrpAscent = s->font_ascent; stsc->scrpStyleTab[0].scrpFont = s->fontnum; stsc->scrpStyleTab[0].scrpFace = 0; - stsc->scrpStyleTab[0].scrpSize = s->cfg.fontheight; + stsc->scrpStyleTab[0].scrpSize = s->cfg.font.size; stsc->scrpStyleTab[0].scrpColor.red = 0; stsc->scrpStyleTab[0].scrpColor.green = 0; stsc->scrpStyleTab[0].scrpColor.blue = 0; - PutScrap(stsz, 'styl', stsc); + PutScrap(stsz, kScrapFlavorTypeTextStyle, stsc); sfree(stsc); +#endif } -void get_clip(void *frontend, wchar_t **p, int *lenp) { +void get_clip(void *frontend, wchar_t **p, int *lenp) +{ +#if TARGET_API_MAC_CARBON + *lenp = 0; +#else Session *s = frontend; static Handle h = NULL; static wchar_t *data = NULL; @@ -612,17 +691,18 @@ void get_clip(void *frontend, wchar_t **p, int *lenp) { sfree(data); data = NULL; } else { - if (GetScrap(NULL, 'utxt', &offset) > 0) { + if (GetScrap(NULL, kScrapFlavorTypeUnicode, &offset) > 0) { if (h == NULL) h = NewHandle(0); - *lenp = GetScrap(h, 'utxt', &offset) / sizeof(**p); + *lenp = + GetScrap(h, kScrapFlavorTypeUnicode, &offset) / sizeof(**p); HLock(h); *p = (wchar_t *)*h; - } else if (GetScrap(NULL, 'TEXT', &offset) > 0) { + } else if (GetScrap(NULL, kScrapFlavorTypeText, &offset) > 0) { texth = NewHandle(0); - textlen = GetScrap(texth, 'TEXT', &offset); + textlen = GetScrap(texth, kScrapFlavorTypeText, &offset); HLock(texth); - data = smalloc(textlen * 2); + data = snewn(textlen, wchar_t); /* XXX should use 'styl' scrap if it's there. */ if (mac_gestalts.encvvers != 0 && UpgradeScriptInfoToTextEncoding(smSystemScript, @@ -662,12 +742,18 @@ void get_clip(void *frontend, wchar_t **p, int *lenp) { *lenp = 0; } } +#endif } -static pascal void mac_scrolltracker(ControlHandle control, short part) { +static pascal void mac_scrolltracker(ControlHandle control, short part) +{ Session *s; - s = (Session *)GetWRefCon((*control)->contrlOwner); +#if TARGET_API_MAC_CARBON + s = mac_windowsession(GetControlOwner(control)); +#else + s = mac_windowsession((*control)->contrlOwner); +#endif switch (part) { case kControlUpButtonPart: term_scroll(s->term, 0, -1); @@ -684,11 +770,15 @@ static pascal void mac_scrolltracker(ControlHandle control, short part) { } } -void mac_keyterm(WindowPtr window, EventRecord *event) { - Session *s = (Session *)GetWRefCon(window); +static void mac_keyterm(WindowPtr window, EventRecord *event) +{ + Session *s = mac_windowsession(window); Key_Sym keysym = PK_NULL; unsigned int mods = 0, flags = PKF_NUMLOCK; - wchar_t utxt[1]; + UniChar utxt[1]; + char txt[1]; + size_t len = 0; + ScriptCode key_script; ObscureCursor(); @@ -773,9 +863,52 @@ void mac_keyterm(WindowPtr window, EventRecord *event) { case 0x7E: keysym = PK_UP; break; } - /* XXX Map from key script to Unicode. */ - utxt[0] = event->message & charCodeMask; - term_key(s->term, keysym, utxt, 1, mods, flags); + /* Map from key script to Unicode. */ + txt[0] = event->message & charCodeMask; + key_script = GetScriptManagerVariable(smKeyScript); + + if (mac_gestalts.encvvers != 0) { + static TextToUnicodeInfo key_to_uni = NULL; + static ScriptCode key_to_uni_script; + TextEncoding enc; + ByteCount iread, olen; + OSErr err; + + if (key_to_uni != NULL && key_to_uni_script != key_script) + DisposeTextToUnicodeInfo(&key_to_uni); + if (key_to_uni == NULL || key_to_uni_script != key_script) { + if (UpgradeScriptInfoToTextEncoding(key_script, + kTextLanguageDontCare, + kTextRegionDontCare, NULL, + &enc) == noErr && + CreateTextToUnicodeInfoByEncoding(enc, &key_to_uni) == noErr) + key_to_uni_script = key_script; + else + key_to_uni = NULL; + } + if (key_to_uni != NULL) { + err = ConvertFromTextToUnicode(key_to_uni, 1, txt, + (kUnicodeKeepInfoMask | + kUnicodeStringUnterminatedMask), + 0, NULL, NULL, NULL, + sizeof(utxt), &iread, &olen, utxt); + if (err == noErr) + len = olen / sizeof(*utxt); + } + } else { + int charset; + char *tptr = txt; + int tlen = 1; + + charset = charset_from_macenc(key_script, + GetScriptManagerVariable(smRegionCode), + mac_gestalts.sysvers, NULL); + if (charset != CS_NONE) { + len = charset_to_unicode(&tptr, &tlen, utxt, sizeof(utxt), charset, + NULL, NULL, 0); + } + } + term_key(s->term, keysym, utxt, len, mods, flags); } void request_paste(void *frontend) @@ -798,17 +931,21 @@ static struct { char oldmsg[20]; } growterm_state; -void mac_growterm(WindowPtr window, EventRecord *event) { +static void mac_growterm(WindowPtr window, EventRecord *event) +{ Rect limits; long grow_result; int newrows, newcols; Session *s; +#if !TARGET_API_MAC_CARBON DragGrayRgnUPP draghooksave; GrafPtr portsave; FontInfo fi; +#endif - s = (Session *)GetWRefCon(window); + s = mac_windowsession(window); +#if !TARGET_API_MAC_CARBON draghooksave = LMGetDragHook(); growterm_state.oldmsg[0] = '\0'; growterm_state.zeromouse = event->where; @@ -827,15 +964,18 @@ void mac_growterm(WindowPtr window, EventRecord *event) { StringWidth("\p99999x99999") + 4, fi.ascent + fi.descent + 4); SetPt(&growterm_state.msgorigin, 2, fi.ascent + 2); LMSetDragHook(NewDragGrayRgnUPP(mac_growtermdraghook)); +#endif SetRect(&limits, s->font_width + 15, s->font_height, SHRT_MAX, SHRT_MAX); grow_result = GrowWindow(window, event->where, &limits); +#if !TARGET_API_MAC_CARBON DisposeDragGrayRgnUPP(LMGetDragHook()); LMSetDragHook(draghooksave); InvalRect(&growterm_state.msgrect); SetPort(portsave); +#endif if (grow_result != 0) { newrows = HiWord(grow_result) / s->font_height; @@ -845,6 +985,7 @@ void mac_growterm(WindowPtr window, EventRecord *event) { } } +#if !TARGET_API_MAC_CARBON static pascal void mac_growtermdraghook(void) { Session *s = growterm_state.s; @@ -872,10 +1013,11 @@ static pascal void mac_growtermdraghook(void) DrawString(pbuf); SetPort(portsave); } +#endif void mac_closeterm(WindowPtr window) { - Session *s = (Session *)GetWRefCon(window); + Session *s = mac_windowsession(window); /* XXX warn on close */ HideWindow(s->window); @@ -887,15 +1029,19 @@ void mac_closeterm(WindowPtr window) if (s->uni_to_font != NULL) DisposeUnicodeToTextInfo(&s->uni_to_font); term_free(s->term); + mac_freeeventlog(s); + sfree((WinInfo *)GetWRefCon(s->window)); DisposeWindow(s->window); DisposePalette(s->palette); sfree(s); } -void mac_activateterm(WindowPtr window, Boolean active) { +static void mac_activateterm(WindowPtr window, EventRecord *event) +{ Session *s; + Boolean active = (event->modifiers & activeFlag) != 0; - s = (Session *)GetWRefCon(window); + s = mac_windowsession(window); s->term->has_focus = active; term_update(s->term); if (active) @@ -910,18 +1056,27 @@ void mac_activateterm(WindowPtr window, Boolean active) { mac_drawgrowicon(s); } -void mac_updateterm(WindowPtr window) { +static void mac_updateterm(WindowPtr window) +{ Session *s; + Rect bbox; +#if TARGET_API_MAC_CARBON + RgnHandle visrgn; +#endif - s = (Session *)GetWRefCon(window); - SetPort(window); + s = mac_windowsession(window); + SetPort((GrafPtr)GetWindowPort(window)); BeginUpdate(window); pre_paint(s); - term_paint(s->term, s, - PTOCC((*window->visRgn)->rgnBBox.left), - PTOCR((*window->visRgn)->rgnBBox.top), - PTOCC((*window->visRgn)->rgnBBox.right), - PTOCR((*window->visRgn)->rgnBBox.bottom), 1); +#if TARGET_API_MAC_CARBON + visrgn = NewRgn(); + GetPortVisibleRegion(GetWindowPort(window), visrgn); + GetRegionBounds(visrgn, &bbox); +#else + bbox = (*window->visRgn)->rgnBBox; +#endif + term_paint(s->term, s, PTOCC(bbox.left), PTOCR(bbox.top), + PTOCC(bbox.right), PTOCR(bbox.bottom), 1); /* Restore default colours in case the Window Manager uses them */ if (HAVE_COLOR_QD()) { PmForeColor(DEFAULT_FG); @@ -931,23 +1086,34 @@ void mac_updateterm(WindowPtr window) { BackColor(blackColor); } if (FrontWindow() != window) +#if TARGET_API_MAC_CARBON + EraseRect(GetControlBounds(s->scrollbar, &bbox)); + UpdateControls(window, visrgn); + DisposeRgn(visrgn); +#else EraseRect(&(*s->scrollbar)->contrlRect); UpdateControls(window, window->visRgn); +#endif mac_drawgrowicon(s); post_paint(s); EndUpdate(window); } -static void mac_drawgrowicon(Session *s) { +static void mac_drawgrowicon(Session *s) +{ Rect clip; RgnHandle savergn; - SetPort(s->window); + SetPort((GrafPtr)GetWindowPort(s->window)); /* * Stop DrawGrowIcon giving us space for a horizontal scrollbar * See Tech Note TB575 for details. */ +#if TARGET_API_MAC_CARBON + GetPortBounds(GetWindowPort(s->window), &clip); +#else clip = s->window->portRect; +#endif clip.left = clip.right - 15; savergn = NewRgn(); GetClip(savergn); @@ -972,22 +1138,31 @@ struct do_text_args { * * x and y are text row and column (zero-based) */ -void do_text(Context ctx, int x, int y, char *text, int len, - unsigned long attr, int lattr) { +void do_text(Context ctx, int x, int y, wchar_t *text, int len, + unsigned long attr, int lattr) +{ Session *s = ctx; - int style = 0; + int style; struct do_text_args a; RgnHandle textrgn, saveclip; +#if TARGET_API_MAC_CARBON + RgnHandle visrgn; +#endif char mactextbuf[1024]; - UniChar unitextbuf[1024]; wchar_t *unitextptr; int i, fontwidth; ByteCount iread, olen; OSStatus err; + static DeviceLoopDrawingUPP do_text_for_device_upp = NULL; assert(len <= 1024); - SetPort(s->window); + /* SGT, 2004-10-14: I don't know how to support combining characters + * on the Mac. Hopefully the first person to fail this assertion will + * know how to do it better than me... */ + assert(!(attr & TATTR_COMBINING)); + + SetPort((GrafPtr)GetWindowPort(s->window)); fontwidth = s->font_width; if ((lattr & LATTR_MODE) != LATTR_NORM) @@ -1000,23 +1175,29 @@ void do_text(Context ctx, int x, int y, char *text, int len, 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 TARGET_API_MAC_CARBON + visrgn = NewRgn(); + GetPortVisibleRegion(GetWindowPort(s->window), visrgn); + if (!RectInRgn(&a.textrect, visrgn)) { + DisposeRgn(visrgn); + return; + } + DisposeRgn(visrgn); +#else 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); +#endif if (s->uni_to_font != NULL) { err = ConvertFromUnicodeToText(s->uni_to_font, len * sizeof(UniChar), - unitextbuf, kUnicodeUseFallbacksMask, + text, 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; + unitextptr = (wchar_t *)text; olen = charset_from_unicode(&unitextptr, &len, mactextbuf, 1024, s->font_charset, NULL, ".", 1); } else @@ -1029,25 +1210,26 @@ void do_text(Context ctx, int x, int y, char *text, int len, a.lattr = lattr; switch (lattr & LATTR_MODE) { case LATTR_NORM: - TextSize(s->cfg.fontheight); + TextSize(s->cfg.font.size); a.numer = s->font_stdnumer; a.denom = s->font_stddenom; break; case LATTR_WIDE: - TextSize(s->cfg.fontheight); + TextSize(s->cfg.font.size); a.numer = s->font_widenumer; a.denom = s->font_widedenom; break; case LATTR_TOP: case LATTR_BOT: - TextSize(s->cfg.fontheight * 2); + TextSize(s->cfg.font.size * 2); a.numer = s->font_bignumer; a.denom = s->font_bigdenom; break; } - SetPort(s->window); + SetPort((GrafPtr)GetWindowPort(s->window)); TextFont(s->fontnum); - if (s->cfg.fontisbold || (attr & ATTR_BOLD) && !s->cfg.bold_colour) + style = s->cfg.font.face; + if ((attr & ATTR_BOLD) && !s->cfg.bold_colour) style |= bold; if (attr & ATTR_UNDER) style |= underline; @@ -1066,23 +1248,34 @@ void do_text(Context ctx, int x, int y, char *text, int len, ClipRect(&a.textrect); textrgn = NewRgn(); RectRgn(textrgn, &a.textrect); - if (HAVE_COLOR_QD()) - DeviceLoop(textrgn, &do_text_for_device_upp, (long)&a, 0); - else + if (HAVE_COLOR_QD()) { + if (do_text_for_device_upp == NULL) + do_text_for_device_upp = + NewDeviceLoopDrawingUPP(&do_text_for_device); + 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 */ +#if TARGET_API_MAC_CARBON + ValidWindowRect(s->window, &a.textrect); +#else ValidRect(&a.textrect); +#endif } static pascal void do_text_for_device(short depth, short devflags, - GDHandle device, long cookie) { - struct do_text_args *a; + GDHandle device, long cookie) +{ + struct do_text_args *a = (struct do_text_args *)cookie; int bgcolour, fgcolour, bright, reverse, tmp; - - a = (struct do_text_args *)cookie; +#if TARGET_API_MAC_CARBON + CQDProcsPtr gp = GetPortGrafProcs(GetWindowPort(a->s->window)); +#else + QDProcsPtr gp = a->s->window->grafProcs; +#endif bright = (a->attr & ATTR_BOLD) && a->s->cfg.bold_colour; reverse = a->attr & ATTR_REVERSE; @@ -1143,9 +1336,8 @@ static pascal void do_text_for_device(short depth, short devflags, 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, - a->s->window->grafProcs->textProc); + if (gp != NULL) + InvokeQDTextUPP(a->len, a->text, a->numer, a->denom, gp->textProc); else StdText(a->len, a->text, a->numer, a->denom); @@ -1174,14 +1366,25 @@ void do_cursor(Context ctx, int x, int y, char *text, int len, * Call from the terminal emulator to get its graphics context. * Should probably be called start_redraw or something. */ -void pre_paint(Session *s) { +void pre_paint(Session *s) +{ GDHandle gdh; Rect myrect, tmprect; +#if TARGET_API_MAC_CARBON + RgnHandle visrgn; +#endif if (HAVE_COLOR_QD()) { s->term->attr_mask = 0; - SetPort(s->window); + SetPort((GrafPtr)GetWindowPort(s->window)); +#if TARGET_API_MAC_CARBON + visrgn = NewRgn(); + GetPortVisibleRegion(GetWindowPort(s->window), visrgn); + GetRegionBounds(visrgn, &myrect); + DisposeRgn(visrgn); +#else myrect = (*s->window->visRgn)->rgnBBox; +#endif LocalToGlobal((Point *)&myrect.top); LocalToGlobal((Point *)&myrect.bottom); for (gdh = GetDeviceList(); @@ -1210,21 +1413,24 @@ void pre_paint(Session *s) { (s->cfg.bold_colour ? ATTR_BOLD : 0)); } -Context get_ctx(void *frontend) { +Context get_ctx(void *frontend) +{ Session *s = frontend; pre_paint(s); return s; } -void free_ctx(Context ctx) { +void free_ctx(Context ctx) +{ } /* * Presumably this does something in Windows */ -void post_paint(Session *s) { +void post_paint(Session *s) +{ } @@ -1235,12 +1441,13 @@ void post_paint(Session *s) { * start is the line number of the top of the display * page is the length of the displayed page */ -void set_sbar(void *frontend, int total, int start, int page) { +void set_sbar(void *frontend, int total, int start, int page) +{ Session *s = frontend; /* We don't redraw until we've set everything up, to avoid glitches */ - (*s->scrollbar)->contrlMin = 0; - (*s->scrollbar)->contrlMax = total - page; + SetControlMinimum(s->scrollbar, 0); + SetControlMaximum(s->scrollbar, total - page); SetControlValue(s->scrollbar, start); #if !TARGET_CPU_68K if (mac_gestalts.cntlattr & gestaltControlMgrPresent) @@ -1291,7 +1498,8 @@ void set_icon(void *frontend, char *icon) { /* * Set the window title */ -void set_title(void *frontend, char *title) { +void set_title(void *frontend, char *title) +{ Session *s = frontend; Str255 mactitle; @@ -1313,9 +1521,24 @@ void set_raw_mouse_mode(void *frontend, int activate) /* * Resize the window at the emulator's request */ -void request_resize(void *frontend, int w, int h) { +void request_resize(void *frontend, int w, int h) +{ Session *s = frontend; - + RgnHandle grayrgn; + Rect graybox; + int wlim, hlim; + + /* Arbitrarily clip to the size of the desktop. */ + grayrgn = GetGrayRgn(); +#if TARGET_API_MAC_CARBON + GetRegionBounds(grayrgn, &graybox); +#else + graybox = (*grayrgn)->rgnBBox; +#endif + wlim = (graybox.right - graybox.left) / s->font_width; + hlim = (graybox.bottom - graybox.top) / s->font_height; + if (w > wlim) w = wlim; + if (h > hlim) h = hlim; term_size(s->term, h, w, s->cfg.savelines); mac_initfont(s); } @@ -1405,9 +1628,15 @@ int is_iconic(void *frontend) void get_window_pos(void *frontend, int *x, int *y) { Session *s = frontend; + Rect rect; - *x = s->window->portRect.left; - *y = s->window->portRect.top; +#if TARGET_API_MAC_CARBON + GetPortBounds(GetWindowPort(s->window), &rect); +#else + rect = s->window->portRect; +#endif + *x = rect.left; + *y = rect.top; } /* @@ -1416,9 +1645,15 @@ void get_window_pos(void *frontend, int *x, int *y) void get_window_pixels(void *frontend, int *x, int *y) { Session *s = frontend; + Rect rect; - *x = s->window->portRect.right - s->window->portRect.left; - *y = s->window->portRect.bottom - s->window->portRect.top; +#if TARGET_API_MAC_CARBON + GetPortBounds(GetWindowPort(s->window), &rect); +#else + rect = s->window->portRect; +#endif + *x = rect.right - rect.left; + *y = rect.bottom - rect.top; } /* @@ -1455,7 +1690,8 @@ static void real_palette_set(Session *s, int n, int r, int g, int b) /* * Set the logical palette. Called by the terminal emulator. */ -void palette_set(void *frontend, int n, int r, int g, int b) { +void palette_set(void *frontend, int n, int r, int g, int b) +{ Session *s = frontend; static const int first[21] = { 0, 2, 4, 6, 8, 10, 12, 14, @@ -1476,7 +1712,8 @@ void palette_set(void *frontend, int n, int r, int g, int b) { /* * Reset to the default palette */ -void palette_reset(void *frontend) { +void palette_reset(void *frontend) +{ Session *s = frontend; /* This maps colour indices in cfg to those used in our palette. */ static const int ww[] = { @@ -1506,15 +1743,16 @@ void palette_reset(void *frontend) { * Scroll the screen. (`lines' is +ve for scrolling forward, -ve * for backward.) */ -void do_scroll(void *frontend, int topline, int botline, int lines) { - Session *s = frontend; +void do_scroll(Context ctx, int topline, int botline, int lines) +{ + Session *s = ctx; Rect r; RgnHandle scrollrgn = NewRgn(); RgnHandle movedupdate = NewRgn(); RgnHandle update = NewRgn(); Point g2l = { 0, 0 }; - SetPort(s->window); + SetPort((GrafPtr)GetWindowPort(s->window)); /* * Work out the part of the update region that will scrolled by @@ -1528,11 +1766,19 @@ void do_scroll(void *frontend, int topline, int botline, int lines) { SetRectRgn(scrollrgn, 0, topline * s->font_height, s->term->cols * s->font_width, (botline - lines + 1) * s->font_height); - CopyRgn(((WindowPeek)s->window)->updateRgn, movedupdate); +#if TARGET_API_MAC_CARBON + GetWindowRegion(s->window, kWindowUpdateRgn, movedupdate); +#else + GetWindowUpdateRgn(s->window, movedupdate); +#endif GlobalToLocal(&g2l); OffsetRgn(movedupdate, g2l.h, g2l.v); /* Convert to local co-ords. */ SectRgn(scrollrgn, movedupdate, movedupdate); /* Clip scrolled section. */ +#if TARGET_API_MAC_CARBON + ValidWindowRgn(s->window, movedupdate); +#else ValidRgn(movedupdate); +#endif OffsetRgn(movedupdate, 0, -lines * s->font_height); /* Scroll it. */ PenNormal(); @@ -1544,19 +1790,19 @@ void do_scroll(void *frontend, int topline, int botline, int lines) { s->term->cols * s->font_width, (botline + 1) * s->font_height); ScrollRect(&r, 0, - lines * s->font_height, update); +#if TARGET_API_MAC_CARBON + InvalWindowRgn(s->window, update); + InvalWindowRgn(s->window, movedupdate); +#else InvalRgn(update); InvalRgn(movedupdate); +#endif DisposeRgn(scrollrgn); DisposeRgn(movedupdate); DisposeRgn(update); } -void logevent(void *frontend, char *str) { - - fprintf(stderr, "%s\n", str); -} - /* Dummy routine, only required in plink. */ void ldisc_update(void *frontend, int echo, int edit) { @@ -1594,13 +1840,20 @@ void frontend_keypress(void *handle) * Ask whether to wipe a session log file before writing to it. * Returns 2 for wipe, 1 for append, 0 for cancel (don't log). */ -int askappend(void *frontend, char *filename) +int askappend(void *frontend, Filename filename) { /* FIXME: not implemented yet. */ return 2; } +int from_backend(void *frontend, int is_stderr, const char *data, int len) +{ + Session *s = frontend; + + return term_data(s->term, is_stderr, data, len); +} + /* * Emacs magic: * Local Variables: