X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/1951eebc43dea8e45a1f745675db63e11624a65b..086efcde067f75f97768e54c251befc9e4ad10ce:/mac/macterm.c diff --git a/mac/macterm.c b/mac/macterm.c index 0ddb789c..23ac22a6 100644 --- a/mac/macterm.c +++ b/mac/macterm.c @@ -1,4 +1,4 @@ -/* $Id: macterm.c,v 1.11 2002/11/24 00:38:44 ben Exp $ */ +/* $Id: macterm.c,v 1.22 2002/12/09 23:26:52 ben Exp $ */ /* * Copyright (c) 1999 Simon Tatham * Copyright (c) 1999, 2002 Ben Harris @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -78,9 +79,9 @@ static void mac_initpalette(Session *); static void mac_adjustwinbg(Session *); static void mac_adjustsize(Session *, int, int); static void mac_drawgrowicon(Session *s); +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 pascal void mac_set_attr_mask(short, short, GDHandle, long); static int mac_keytrans(Session *, EventRecord *, unsigned char *); static void text_click(Session *, EventRecord *); @@ -94,13 +95,9 @@ static RoutineDescriptor mac_scrolltracker_upp = static RoutineDescriptor do_text_for_device_upp = BUILD_ROUTINE_DESCRIPTOR(uppDeviceLoopDrawingProcInfo, (ProcPtr)do_text_for_device); -static RoutineDescriptor mac_set_attr_mask_upp = - BUILD_ROUTINE_DESCRIPTOR(uppDeviceLoopDrawingProcInfo, - (ProcPtr)mac_set_attr_mask); #else /* not TARGET_RT_MAC_CFM */ #define mac_scrolltracker_upp mac_scrolltracker #define do_text_for_device_upp do_text_for_device -#define mac_set_attr_mask_upp mac_set_attr_mask #endif /* not TARGET_RT_MAC_CFM */ static void inbuf_putc(Session *s, int c) { @@ -170,7 +167,6 @@ void mac_newsession(void) { mac_initfont(s); mac_initpalette(s); - s->attr_mask = ATTR_MASK; if (HAVE_COLOR_QD()) { /* Set to FALSE to not get palette updates in the background. */ SetPalette(s->window, s->palette, TRUE); @@ -223,6 +219,7 @@ static void mac_adjustsize(Session *s, int newrows, int newcols) { MoveControl(s->scrollbar, winwidth - 15, -1); SizeControl(s->scrollbar, 16, winheight - 13); ShowControl(s->scrollbar); + mac_drawgrowicon(s); } static void mac_initpalette(Session *s) { @@ -714,15 +711,51 @@ void request_paste(void *frontend) term_do_paste(s->term); } +static struct { + Rect msgrect; + Point msgorigin; + Point startmouse; + Session *s; + char oldmsg[20]; +} growterm_state; + void mac_growterm(WindowPtr window, EventRecord *event) { Rect limits; long grow_result; int newrows, newcols; Session *s; + DragGrayRgnUPP draghooksave; + GrafPtr portsave; + FontInfo fi; s = (Session *)GetWRefCon(window); + + draghooksave = LMGetDragHook(); + growterm_state.oldmsg[0] = '\0'; + growterm_state.startmouse = event->where; + growterm_state.s = s; + GetPort(&portsave); + SetPort(s->window); + BackColor(whiteColor); + ForeColor(blackColor); + TextFont(systemFont); + TextFace(0); + TextSize(12); + GetFontInfo(&fi); + SetRect(&growterm_state.msgrect, 0, 0, + StringWidth("\p99999x99999") + 4, fi.ascent + fi.descent + 4); + SetPt(&growterm_state.msgorigin, 2, fi.ascent + 2); + LMSetDragHook(NewDragGrayRgnUPP(mac_growtermdraghook)); + SetRect(&limits, s->font_width + 15, s->font_height, SHRT_MAX, SHRT_MAX); grow_result = GrowWindow(window, event->where, &limits); + + DisposeDragGrayRgnUPP(LMGetDragHook()); + LMSetDragHook(draghooksave); + InvalRect(&growterm_state.msgrect); + + SetPort(portsave); + if (grow_result != 0) { newrows = HiWord(grow_result) / s->font_height; newcols = (LoWord(grow_result) - 15) / s->font_width; @@ -731,6 +764,35 @@ void mac_growterm(WindowPtr window, EventRecord *event) { } } +static pascal void mac_growtermdraghook(void) +{ + Session *s = growterm_state.s; + GrafPtr portsave; + Point mouse; + char buf[20]; + int newrows, newcols; + + GetMouse(&mouse); + newrows = (mouse.v - growterm_state.startmouse.v) / s->font_height + + s->term->rows; + if (newrows < 1) newrows = 1; + newcols = (mouse.h - growterm_state.startmouse.h) / s->font_width + + s->term->cols; + 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); + + GetPort(&portsave); + SetPort(growterm_state.s->window); + EraseRect(&growterm_state.msgrect); + MoveTo(growterm_state.msgorigin.h, growterm_state.msgorigin.v); + DrawString((StringPtr)buf); + SetPort(portsave); +} + void mac_activateterm(WindowPtr window, Boolean active) { Session *s; @@ -779,25 +841,31 @@ void mac_updateterm(WindowPtr window) { static void mac_drawgrowicon(Session *s) { Rect clip; + RgnHandle savergn; SetPort(s->window); - /* Stop DrawGrowIcon giving us space for a horizontal scrollbar */ - SetRect(&clip, s->window->portRect.right - 15, SHRT_MIN, - SHRT_MAX, SHRT_MAX); + /* + * Stop DrawGrowIcon giving us space for a horizontal scrollbar + * See Tech Note TB575 for details. + */ + clip = s->window->portRect; + clip.left = clip.right - 15; + savergn = NewRgn(); + GetClip(savergn); ClipRect(&clip); DrawGrowIcon(s->window); - clip.left = SHRT_MIN; - ClipRect(&clip); + SetClip(savergn); + DisposeRgn(savergn); } struct do_text_args { Session *s; Rect textrect; - Rect leadrect; char *text; int len; unsigned long attr; int lattr; + Point numer, denom; }; /* @@ -827,12 +895,7 @@ void do_text(Context ctx, int x, int y, char *text, int len, a.len = len; a.attr = attr; a.lattr = lattr; - if (s->font_leading > 0) - SetRect(&a.leadrect, - a.textrect.left, a.textrect.bottom - s->font_leading, - a.textrect.right, a.textrect.bottom); - else - SetRect(&a.leadrect, 0, 0, 0, 0); + a.numer.h = a.numer.v = a.denom.h = a.denom.v = 1; SetPort(s->window); TextFont(s->fontnum); if (s->cfg.fontisbold || (attr & ATTR_BOLD) && !s->cfg.bold_colour) @@ -841,7 +904,7 @@ void do_text(Context ctx, int x, int y, char *text, int len, style |= underline; TextFace(style); TextSize(s->cfg.fontheight); - SetFractEnable(FALSE); /* We want characters on pixel boundaries */ + TextMode(srcOr); if (HAVE_COLOR_QD()) if (style & bold) { SpaceExtra(s->font_boldadjust << 16); @@ -864,58 +927,60 @@ void do_text(Context ctx, int x, int y, char *text, int len, static pascal void do_text_for_device(short depth, short devflags, GDHandle device, long cookie) { struct do_text_args *a; - int bgcolour, fgcolour, bright; + int bgcolour, fgcolour, bright, reverse, tmp; a = (struct do_text_args *)cookie; bright = (a->attr & ATTR_BOLD) && a->s->cfg.bold_colour; + reverse = a->attr & ATTR_REVERSE; - TextMode(a->attr & ATTR_REVERSE ? notSrcCopy : srcCopy); + if (depth == 1 && (a->attr & TATTR_ACTCURS)) + reverse = !reverse; - switch (depth) { - case 1: - /* XXX This should be done with a _little_ more configurability */ - ForeColor(whiteColor); - BackColor(blackColor); - if (a->attr & TATTR_ACTCURS) - TextMode(a->attr & ATTR_REVERSE ? srcCopy : notSrcCopy); - break; - case 2: - if (a->attr & TATTR_ACTCURS) { - PmForeColor(CURSOR_FG); - PmBackColor(CURSOR_BG); - TextMode(srcCopy); + if (HAVE_COLOR_QD()) { + if (depth > 2) { + fgcolour = ((a->attr & ATTR_FGMASK) >> ATTR_FGSHIFT) * 2; + bgcolour = ((a->attr & ATTR_BGMASK) >> ATTR_BGSHIFT) * 2; } else { - PmForeColor(bright ? DEFAULT_FG_BOLD : DEFAULT_FG); - PmBackColor(DEFAULT_BG); + /* + * NB: bold reverse in 2bpp breaks with the usual PuTTY model and + * boldens the background, because that's all we can do. + */ + fgcolour = bright ? DEFAULT_FG_BOLD : DEFAULT_FG; + bgcolour = DEFAULT_BG; } - break; - default: - if (a->attr & TATTR_ACTCURS) { + if (reverse) { + tmp = fgcolour; + fgcolour = bgcolour; + bgcolour = tmp; + } + if (bright && depth > 2) + fgcolour++; + if ((a->attr & TATTR_ACTCURS) && depth > 1) { fgcolour = CURSOR_FG; bgcolour = CURSOR_BG; - TextMode(srcCopy); - } else { - fgcolour = ((a->attr & ATTR_FGMASK) >> ATTR_FGSHIFT) * 2; - bgcolour = ((a->attr & ATTR_BGMASK) >> ATTR_BGSHIFT) * 2; - if (bright) - if (a->attr & ATTR_REVERSE) - bgcolour++; - else - fgcolour++; } PmForeColor(fgcolour); PmBackColor(bgcolour); - break; + } else { /* No Color Quickdraw */ + /* XXX This should be done with a _little_ more configurability */ + if (reverse) { + ForeColor(blackColor); + BackColor(whiteColor); + } else { + ForeColor(whiteColor); + BackColor(blackColor); + } } - if (a->attr & ATTR_REVERSE) - PaintRect(&a->leadrect); - else - EraseRect(&a->leadrect); + EraseRect(&a->textrect); MoveTo(a->textrect.left, a->textrect.top + a->s->font_ascent); /* FIXME: Sort out bold width adjustments on Original QuickDraw. */ - DrawText(a->text, 0, a->len); + if (a->s->window->grafProcs != NULL) + InvokeQDTextUPP(a->len, a->text, a->numer, a->denom, + a->s->window->grafProcs->textProc); + else + StdText(a->len, a->text, a->numer, a->denom); if (a->attr & TATTR_PASCURS) { PenNormal(); @@ -943,12 +1008,39 @@ void do_cursor(Context ctx, int x, int y, char *text, int len, * Should probably be called start_redraw or something. */ void pre_paint(Session *s) { + GDHandle gdh; + Rect myrect, tmprect; - s->attr_mask = ATTR_INVALID; - if (HAVE_COLOR_QD()) - DeviceLoop(s->window->visRgn, &mac_set_attr_mask_upp, (long)s, 0); - else - mac_set_attr_mask(1, 0, NULL, (long)s); + if (HAVE_COLOR_QD()) { + s->term->attr_mask = 0; + SetPort(s->window); + myrect = (*s->window->visRgn)->rgnBBox; + LocalToGlobal((Point *)&myrect.top); + LocalToGlobal((Point *)&myrect.bottom); + for (gdh = GetDeviceList(); + gdh != NULL; + gdh = GetNextDevice(gdh)) { + if (TestDeviceAttribute(gdh, screenDevice) && + TestDeviceAttribute(gdh, screenActive) && + SectRect(&(*gdh)->gdRect, &myrect, &tmprect)) { + switch ((*(*gdh)->gdPMap)->pixelSize) { + case 1: + if (s->cfg.bold_colour) + s->term->attr_mask |= ~(ATTR_COLOURS | + (s->cfg.bold_colour ? ATTR_BOLD : 0)); + break; + case 2: + s->term->attr_mask |= ~ATTR_COLOURS; + break; + default: + s->term->attr_mask = ~0; + return; /* No point checking more screens. */ + } + } + } + } else + s->term->attr_mask = ~(ATTR_COLOURS | + (s->cfg.bold_colour ? ATTR_BOLD : 0)); } Context get_ctx(void *frontend) { @@ -962,26 +1054,6 @@ void free_ctx(Context ctx) { } -static pascal void mac_set_attr_mask(short depth, short devflags, - GDHandle device, long cookie) { - - Session *s = (Session *)cookie; - - switch (depth) { - default: - s->attr_mask |= ATTR_FGMASK | ATTR_BGMASK; - /* FALLTHROUGH */ - case 2: - s->attr_mask |= ATTR_BOLD; - /* FALLTHROUGH */ - case 1: - s->attr_mask |= ATTR_UNDER | ATTR_REVERSE | TATTR_ACTCURS | - TATTR_PASCURS | ATTR_ASCII | ATTR_GBCHR | ATTR_LINEDRW | - (s->cfg.bold_colour ? 0 : ATTR_BOLD); - break; - } -} - /* * Presumably this does something in Windows */ @@ -1269,19 +1341,46 @@ void palette_reset(void *frontend) { void do_scroll(void *frontend, int topline, int botline, int lines) { Session *s = frontend; Rect r; - RgnHandle update; + RgnHandle scrollrgn = NewRgn(); + RgnHandle movedupdate = NewRgn(); + RgnHandle update = NewRgn(); + Point g2l = { 0, 0 }; - /* FIXME: This is seriously broken on Original QuickDraw. No idea why. */ SetPort(s->window); + + /* + * Work out the part of the update region that will scrolled by + * this operation. + */ + if (lines > 0) + SetRectRgn(scrollrgn, 0, (topline + lines) * s->font_height, + s->term->cols * s->font_width, + (botline + 1) * s->font_height); + else + 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); + GlobalToLocal(&g2l); + OffsetRgn(movedupdate, g2l.h, g2l.v); /* Convert to local co-ords. */ + SectRgn(scrollrgn, movedupdate, movedupdate); /* Clip scrolled section. */ + ValidRgn(movedupdate); + OffsetRgn(movedupdate, 0, -lines * s->font_height); /* Scroll it. */ + PenNormal(); if (HAVE_COLOR_QD()) PmBackColor(DEFAULT_BG); - update = NewRgn(); + else + BackColor(blackColor); /* XXX make configurable */ SetRect(&r, 0, topline * s->font_height, s->term->cols * s->font_width, (botline + 1) * s->font_height); ScrollRect(&r, 0, - lines * s->font_height, update); - /* XXX: move update region? */ + InvalRgn(update); + InvalRgn(movedupdate); + + DisposeRgn(scrollrgn); + DisposeRgn(movedupdate); DisposeRgn(update); }