From 82fecf970f54ab1b7c10ee914af156cac64136e5 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Mon, 29 Mar 1999 19:50:24 +0000 Subject: [PATCH] First attempt at multiple-session support. This has broken meta handling, since mac.c needs to know whether to grab Cmd-keys or not. [originally from svn r138] --- mac.c | 6 +- macterm.c | 302 +++++++++++++++++------------------- putty.h | 170 +++++++++++++------- terminal.c | 443 ++++++++++++++++++++++++++--------------------------- testback.c | 44 +++--- 5 files changed, 504 insertions(+), 461 deletions(-) diff --git a/mac.c b/mac.c index 267e341b..48187ec5 100644 --- a/mac.c +++ b/mac.c @@ -1,4 +1,4 @@ -/* $Id: mac.c,v 1.1.2.19 1999/03/28 02:06:10 ben Exp $ */ +/* $Id: mac.c,v 1.1.2.20 1999/03/29 19:50:22 ben Exp $ */ /* * Copyright (c) 1999 Ben Harris * All rights reserved. @@ -299,9 +299,9 @@ static void mac_keypress(EventRecord *event) { * Check for a command-key combination, but ignore it if it counts * as a meta-key combination and we're in a terminal window. */ - if (event->what == keyDown && (event->modifiers & cmdKey) && + if (event->what == keyDown && (event->modifiers & cmdKey) /*&& !((event->modifiers & cfg.meta_modifiers) == cfg.meta_modifiers && - mac_windowtype(window) == wTerminal)) { + mac_windowtype(window) == wTerminal)*/) { mac_adjustmenus(); mac_menucommand(MenuKey(event->message & charCodeMask)); } else { diff --git a/macterm.c b/macterm.c index 555b2363..afc60aa9 100644 --- a/macterm.c +++ b/macterm.c @@ -1,4 +1,4 @@ -/* $Id: macterm.c,v 1.1.2.31 1999/03/28 15:27:03 ben Exp $ */ +/* $Id: macterm.c,v 1.1.2.32 1999/03/29 19:50:23 ben Exp $ */ /* * Copyright (c) 1999 Simon Tatham * Copyright (c) 1999 Ben Harris @@ -64,31 +64,21 @@ #define CURSOR_BG 22 #define CURSOR_BG_BOLD 23 -#define PTOCC(x) ((x) < 0 ? -(-(x - font_width - 1) / font_width) : \ - (x) / font_width) -#define PTOCR(y) ((y) < 0 ? -(-(y - font_height - 1) / font_height) : \ - (y) / font_height) +#define PTOCC(x) ((x) < 0 ? -(-(x - s->font_width - 1) / s->font_width) : \ + (x) / s->font_width) +#define PTOCR(y) ((y) < 0 ? -(-(y - s->font_height - 1) / s->font_height) : \ + (y) / s->font_height) -struct mac_session { - short fontnum; - int font_ascent; - int font_leading; - WindowPtr window; - PaletteHandle palette; - ControlHandle scrollbar; - WCTabHandle wctab; -}; - -static void mac_initfont(struct mac_session *); -static void mac_initpalette(struct mac_session *); -static void mac_adjustwinbg(struct mac_session *); -static void mac_adjustsize(struct mac_session *, int, int); -static void mac_drawgrowicon(struct mac_session *s); +static void mac_initfont(Session *); +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_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(struct mac_session *, EventRecord *, unsigned char *); -static void text_click(struct mac_session *, EventRecord *); +static int mac_keytrans(Session *, EventRecord *, unsigned char *); +static void text_click(Session *, EventRecord *); #if TARGET_RT_MAC_CFM static RoutineDescriptor mac_scrolltracker_upp = @@ -111,19 +101,17 @@ static RoutineDescriptor mac_set_attr_mask_upp = * sessions */ -static struct mac_session *onlysession; - -static void inbuf_putc(int c) { - inbuf[inbuf_head] = c; - inbuf_head = (inbuf_head+1) & INBUF_MASK; +static void inbuf_putc(Session *s, int c) { + s->inbuf[s->inbuf_head] = c; + s->inbuf_head = (s->inbuf_head+1) & INBUF_MASK; } -static void inbuf_putstr(const char *c) { +static void inbuf_putstr(Session *s, const char *c) { while (*c) - inbuf_putc(*c++); + inbuf_putc(s, *c++); } -static void display_resource(unsigned long type, short id) { +static void display_resource(Session *s, unsigned long type, short id) { Handle h; int len, i; char *t; @@ -135,8 +123,8 @@ static void display_resource(unsigned long type, short id) { t = *h; len = GetResourceSizeOnDisk(h); for (i = 0; i < len; i++) { - inbuf_putc(t[i]); - term_out(); + inbuf_putc(s, t[i]); + term_out(s); } SetResAttrs(h, GetResAttrs(h) & ~resLocked); ReleaseResource(h); @@ -144,16 +132,15 @@ static void display_resource(unsigned long type, short id) { void mac_newsession(void) { - struct mac_session *s; + Session *s; UInt32 starttime; char msg[128]; /* This should obviously be initialised by other means */ - mac_loadconfig(&cfg); - back = &hexdump_backend; s = smalloc(sizeof(*s)); memset(s, 0, sizeof(*s)); - onlysession = s; + mac_loadconfig(&s->cfg); + s->back = &hexdump_backend; /* XXX: Own storage management? */ if (mac_gestalts.qdvers == gestaltOriginalQD) @@ -162,38 +149,38 @@ void mac_newsession(void) { s->window = GetNewCWindow(wTerminal, NULL, (WindowPtr)-1); SetWRefCon(s->window, (long)s); s->scrollbar = GetNewControl(cVScroll, s->window); - term_init(); - term_size(cfg.height, cfg.width, cfg.savelines); + term_init(s); + term_size(s, s->cfg.height, s->cfg.width, s->cfg.savelines); mac_initfont(s); mac_initpalette(s); - attr_mask = ATTR_MASK; + s->attr_mask = ATTR_MASK; /* 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('pTST', 128); + display_resource(s, 'pTST', 128); sprintf(msg, "Elapsed ticks: %d\015\012", TickCount() - starttime); - inbuf_putstr(msg); - term_out(); + inbuf_putstr(s, msg); + term_out(s); } -static void mac_initfont(struct mac_session *s) { +static void mac_initfont(Session *s) { Str255 macfont; FontInfo fi; SetPort(s->window); - macfont[0] = sprintf((char *)&macfont[1], "%s", cfg.font); + macfont[0] = sprintf((char *)&macfont[1], "%s", s->cfg.font); GetFNum(macfont, &s->fontnum); TextFont(s->fontnum); - TextFace(cfg.fontisbold ? bold : 0); - TextSize(cfg.fontheight); + TextFace(s->cfg.fontisbold ? bold : 0); + TextSize(s->cfg.fontheight); GetFontInfo(&fi); - font_width = CharWidth('W'); /* Well, it's what NCSA uses. */ + s->font_width = CharWidth('W'); /* Well, it's what NCSA uses. */ s->font_ascent = fi.ascent; s->font_leading = fi.leading; - font_height = s->font_ascent + fi.descent + s->font_leading; - mac_adjustsize(s, rows, cols); + s->font_height = s->font_ascent + fi.descent + s->font_leading; + mac_adjustsize(s, s->rows, s->cols); } /* @@ -202,11 +189,11 @@ static void mac_initfont(struct mac_session *s) { * It's assumed the terminal emulator will be informed, and will set rows * and cols for us. */ -static void mac_adjustsize(struct mac_session *s, int newrows, int newcols) { +static void mac_adjustsize(Session *s, int newrows, int newcols) { int winwidth, winheight; - winwidth = newcols * font_width + 15; - winheight = newrows * font_height; + winwidth = newcols * s->font_width + 15; + winheight = newrows * s->font_height; SizeWindow(s->window, winwidth, winheight, true); HideControl(s->scrollbar); MoveControl(s->scrollbar, winwidth - 15, -1); @@ -214,14 +201,16 @@ static void mac_adjustsize(struct mac_session *s, int newrows, int newcols) { ShowControl(s->scrollbar); } -static void mac_initpalette(struct mac_session *s) { +static void mac_initpalette(Session *s) { if (mac_gestalts.qdvers == gestaltOriginalQD) return; - s->palette = NewPalette((*cfg.colours)->pmEntries, NULL, pmCourteous, 0); + s->palette = NewPalette((*s->cfg.colours)->pmEntries, + NULL, pmCourteous, 0); if (s->palette == NULL) fatalbox("Unable to create palette"); - CopyPalette(cfg.colours, s->palette, 0, 0, (*cfg.colours)->pmEntries); + CopyPalette(s->cfg.colours, s->palette, 0, 0, + (*s->cfg.colours)->pmEntries); mac_adjustwinbg(s); } @@ -229,9 +218,9 @@ static void mac_initpalette(struct mac_session *s) { * Set the background colour of the window correctly. Should be * called whenever the default background changes. */ -static void mac_adjustwinbg(struct mac_session *s) { +static void mac_adjustwinbg(Session *s) { -#if 0 /* XXX doesn't link (at least for 68k) */ +#if TARGET_RT_CFM /* XXX doesn't link (at least for 68k) */ if (mac_gestalts.windattr & gestaltWindowMgrPresent) SetWindowContentColor(s->window, &(*s->palette)->pmInfo[DEFAULT_BG].ciRGB); @@ -255,13 +244,13 @@ static void mac_adjustwinbg(struct mac_session *s) { * Set the cursor shape correctly */ void mac_adjusttermcursor(WindowPtr window, Point mouse, RgnHandle cursrgn) { - struct mac_session *s; + Session *s; ControlHandle control; short part; int x, y; SetPort(window); - s = (struct mac_session *)GetWRefCon(window); + s = (Session *)GetWRefCon(window); GlobalToLocal(&mouse); part = FindControl(mouse, window, &control); if (control == s->scrollbar) { @@ -269,12 +258,12 @@ void mac_adjusttermcursor(WindowPtr window, Point mouse, RgnHandle cursrgn) { RectRgn(cursrgn, &(*s->scrollbar)->contrlRect); SectRgn(cursrgn, window->visRgn, cursrgn); } else { - x = mouse.h / font_width; - y = mouse.v / font_height; + x = mouse.h / s->font_width; + y = mouse.v / s->font_height; SetCursor(*GetCursor(iBeamCursor)); /* Ask for shape changes if we leave this character cell. */ - SetRectRgn(cursrgn, x * font_width, y * font_height, - (x + 1) * font_width, (y + 1) * font_height); + 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); } } @@ -283,16 +272,16 @@ void mac_adjusttermcursor(WindowPtr window, Point mouse, RgnHandle cursrgn) { * Enable/disable menu items based on the active terminal window. */ void mac_adjusttermmenus(WindowPtr window) { - struct mac_session *s; + Session *s; MenuHandle menu; long offset; - s = (struct mac_session *)GetWRefCon(window); + s = (Session *)GetWRefCon(window); menu = GetMenuHandle(mEdit); EnableItem(menu, 0); DisableItem(menu, iUndo); DisableItem(menu, iCut); - if (term_hasselection()) + if (term_hasselection(s)) EnableItem(menu, iCopy); else DisableItem(menu, iCopy); @@ -305,29 +294,29 @@ void mac_adjusttermmenus(WindowPtr window) { } void mac_menuterm(WindowPtr window, short menu, short item) { - struct mac_session *s; + Session *s; - s = (struct mac_session *)GetWRefCon(window); + s = (Session *)GetWRefCon(window); switch (menu) { case mEdit: switch (item) { case iCopy: - term_copy(); + term_copy(s); break; case iPaste: - term_paste(); + term_paste(s); break; } } } void mac_clickterm(WindowPtr window, EventRecord *event) { - struct mac_session *s; + Session *s; Point mouse; ControlHandle control; int part; - s = (struct mac_session *)GetWRefCon(window); + s = (Session *)GetWRefCon(window); SetPort(window); mouse = event->where; GlobalToLocal(&mouse); @@ -336,7 +325,7 @@ void mac_clickterm(WindowPtr window, EventRecord *event) { switch (part) { case kControlIndicatorPart: if (TrackControl(control, mouse, NULL) == kControlIndicatorPart) - term_scroll(+1, GetControlValue(control)); + term_scroll(s, +1, GetControlValue(control)); break; case kControlUpButtonPart: case kControlDownButtonPart: @@ -350,11 +339,11 @@ void mac_clickterm(WindowPtr window, EventRecord *event) { } } -static void text_click(struct mac_session *s, EventRecord *event) { +static void text_click(Session *s, EventRecord *event) { Point localwhere; int row, col; static UInt32 lastwhen = 0; - static struct mac_session *lastsess = NULL; + static Session *lastsess = NULL; static int lastrow = -1, lastcol = -1; static Mouse_Action lastact = MA_NOTHING; @@ -371,7 +360,7 @@ static void text_click(struct mac_session *s, EventRecord *event) { lastact == MA_3CLK ? MA_CLICK : MA_NOTHING); else lastact = MA_CLICK; - term_mouse(event->modifiers & shiftKey ? MB_EXTEND : MB_SELECT, lastact, + term_mouse(s, event->modifiers & shiftKey ? MB_EXTEND : MB_SELECT, lastact, col, row); lastsess = s; lastrow = row; @@ -380,15 +369,15 @@ static void text_click(struct mac_session *s, EventRecord *event) { GetMouse(&localwhere); col = PTOCC(localwhere.h); row = PTOCR(localwhere.v); - term_mouse(event->modifiers & shiftKey ? MB_EXTEND : MB_SELECT, + term_mouse(s, event->modifiers & shiftKey ? MB_EXTEND : MB_SELECT, MA_DRAG, col, row); - if (row > rows - 1) - term_scroll(0, row - (rows - 1)); + if (row > s->rows - 1) + term_scroll(s, 0, row - (s->rows - 1)); else if (row < 0) - term_scroll(0, row); + term_scroll(s, 0, row); } - term_mouse(event->modifiers & shiftKey ? MB_EXTEND : MB_SELECT, MA_RELEASE, - col, row); + term_mouse(s, event->modifiers & shiftKey ? MB_EXTEND : MB_SELECT, + MA_RELEASE, col, row); lastwhen = TickCount(); } @@ -423,21 +412,21 @@ void get_clip(void **p, int *lenp) { } static pascal void mac_scrolltracker(ControlHandle control, short part) { - struct mac_session *s; + Session *s; - s = (struct mac_session *)GetWRefCon((*control)->contrlOwner); + s = (Session *)GetWRefCon((*control)->contrlOwner); switch (part) { case kControlUpButtonPart: - term_scroll(0, -1); + term_scroll(s, 0, -1); break; case kControlDownButtonPart: - term_scroll(0, +1); + term_scroll(s, 0, +1); break; case kControlPageUpPart: - term_scroll(0, -(rows - 1)); + term_scroll(s, 0, -(s->rows - 1)); break; case kControlPageDownPart: - term_scroll(0, +(rows - 1)); + term_scroll(s, 0, +(s->rows - 1)); break; } } @@ -490,11 +479,11 @@ static pascal void mac_scrolltracker(ControlHandle control, short part) { void mac_keyterm(WindowPtr window, EventRecord *event) { unsigned char buf[20]; int len; - struct mac_session *s; + Session *s; - s = (struct mac_session *)GetWRefCon(window); + s = (Session *)GetWRefCon(window); len = mac_keytrans(s, event, buf); - back->send((char *)buf, len); + s->back->send(s, (char *)buf, len); } static UInt32 mac_rekey(EventModifiers newmodifiers, UInt32 oldmessage) { @@ -516,7 +505,7 @@ static UInt32 mac_rekey(EventModifiers newmodifiers, UInt32 oldmessage) { } -static int mac_keytrans(struct mac_session *s, EventRecord *event, +static int mac_keytrans(Session *s, EventRecord *event, unsigned char *output) { unsigned char *p = output; int code; @@ -525,9 +514,9 @@ static int mac_keytrans(struct mac_session *s, EventRecord *event, /* Check if the meta "key" was held down */ - if ((event->modifiers & cfg.meta_modifiers) == cfg.meta_modifiers) { + if ((event->modifiers & s->cfg.meta_modifiers) == s->cfg.meta_modifiers) { *p++ = '\033'; - event->modifiers &= ~cfg.meta_modifiers; + event->modifiers &= ~s->cfg.meta_modifiers; event->message = mac_rekey(event->modifiers, event->message); } @@ -535,10 +524,10 @@ static int mac_keytrans(struct mac_session *s, EventRecord *event, if (event->modifiers & shiftKey) { switch (event->message & keyCodeMask) { case K_PRIOR: /* shift-pageup */ - term_scroll(0, -(rows - 1)); + term_scroll(s, 0, -(s->rows - 1)); return 0; case K_NEXT: /* shift-pagedown */ - term_scroll(0, +(rows - 1)); + term_scroll(s, 0, +(s->rows - 1)); return 0; } } @@ -598,11 +587,11 @@ static int mac_keytrans(struct mac_session *s, EventRecord *event, case K_PRIOR: code = 5; break; case K_NEXT: code = 6; break; } - if (cfg.linux_funkeys && code >= 11 && code <= 15) { + if (s->cfg.linux_funkeys && code >= 11 && code <= 15) { p += sprintf((char *)p, "\x1B[[%c", code + 'A' - 11); return p - output; } - if (cfg.rxvt_homeend && (code == 1 || code == 4)) { + if (s->cfg.rxvt_homeend && (code == 1 || code == 4)) { p += sprintf((char *)p, code == 1 ? "\x1B[H" : "\x1BOw"); return p - output; } @@ -611,7 +600,7 @@ static int mac_keytrans(struct mac_session *s, EventRecord *event, return p - output; } - if (app_keypad_keys) { + if (s->app_keypad_keys) { switch (event->message & keyCodeMask) { case KP_ENTER: p += sprintf((char *)p, "\x1BOM"); return p - output; case KP_CLEAR: p += sprintf((char *)p, "\x1BOP"); return p - output; @@ -636,22 +625,22 @@ static int mac_keytrans(struct mac_session *s, EventRecord *event, switch (event->message & keyCodeMask) { case K_UP: - p += sprintf((char *)p, app_cursor_keys ? "\x1BOA" : "\x1B[A"); + p += sprintf((char *)p, s->app_cursor_keys ? "\x1BOA" : "\x1B[A"); return p - output; case K_DOWN: - p += sprintf((char *)p, app_cursor_keys ? "\x1BOB" : "\x1B[B"); + p += sprintf((char *)p, s->app_cursor_keys ? "\x1BOB" : "\x1B[B"); return p - output; case K_RIGHT: - p += sprintf((char *)p, app_cursor_keys ? "\x1BOC" : "\x1B[C"); + p += sprintf((char *)p, s->app_cursor_keys ? "\x1BOC" : "\x1B[C"); return p - output; case K_LEFT: - p += sprintf((char *)p, app_cursor_keys ? "\x1BOD" : "\x1B[D"); + p += sprintf((char *)p, s->app_cursor_keys ? "\x1BOD" : "\x1B[D"); return p - output; case KP_ENTER: *p++ = 0x0d; return p - output; case K_BS: - *p++ = (cfg.bksp_is_delete ? 0x7f : 0x08); + *p++ = (s->cfg.bksp_is_delete ? 0x7f : 0x08); return p - output; default: *p++ = event->message & charCodeMask; @@ -663,25 +652,25 @@ void mac_growterm(WindowPtr window, EventRecord *event) { Rect limits; long grow_result; int newrows, newcols; - struct mac_session *s; + Session *s; - s = (struct mac_session *)GetWRefCon(window); - SetRect(&limits, font_width + 15, font_height, SHRT_MAX, SHRT_MAX); + s = (Session *)GetWRefCon(window); + SetRect(&limits, s->font_width + 15, s->font_height, SHRT_MAX, SHRT_MAX); grow_result = GrowWindow(window, event->where, &limits); if (grow_result != 0) { - newrows = HiWord(grow_result) / font_height; - newcols = (LoWord(grow_result) - 15) / font_width; + newrows = HiWord(grow_result) / s->font_height; + newcols = (LoWord(grow_result) - 15) / s->font_width; mac_adjustsize(s, newrows, newcols); - term_size(newrows, newcols, cfg.savelines); + term_size(s, newrows, newcols, s->cfg.savelines); } } void mac_activateterm(WindowPtr window, Boolean active) { - struct mac_session *s; + Session *s; - s = (struct mac_session *)GetWRefCon(window); - has_focus = active; - term_update(); + s = (Session *)GetWRefCon(window); + s->has_focus = active; + term_update(s); if (active) ShowControl(s->scrollbar); else { @@ -692,11 +681,12 @@ void mac_activateterm(WindowPtr window, Boolean active) { } void mac_updateterm(WindowPtr window) { - struct mac_session *s; + Session *s; - s = (struct mac_session *)GetWRefCon(window); + s = (Session *)GetWRefCon(window); + SetPort(window); BeginUpdate(window); - get_ctx(); + pre_paint(s); term_paint(s, (*window->visRgn)->rgnBBox.left, (*window->visRgn)->rgnBBox.top, @@ -709,11 +699,11 @@ void mac_updateterm(WindowPtr window) { EraseRect(&(*s->scrollbar)->contrlRect); UpdateControls(window, window->visRgn); mac_drawgrowicon(s); - free_ctx(NULL); + post_paint(s); EndUpdate(window); } -static void mac_drawgrowicon(struct mac_session *s) { +static void mac_drawgrowicon(Session *s) { Rect clip; SetPort(s->window); @@ -727,7 +717,7 @@ static void mac_drawgrowicon(struct mac_session *s) { } struct do_text_args { - struct mac_session *s; + Session *s; Rect textrect; Rect leadrect; char *text; @@ -740,7 +730,7 @@ struct do_text_args { * * x and y are text row and column (zero-based) */ -void do_text(struct mac_session *s, int x, int y, char *text, int len, +void do_text(Session *s, int x, int y, char *text, int len, unsigned long attr) { int style = 0; struct do_text_args a; @@ -749,10 +739,10 @@ void do_text(struct mac_session *s, int x, int y, char *text, int len, SetPort(s->window); /* First check this text is relevant */ - a.textrect.top = y * font_height; - a.textrect.bottom = (y + 1) * font_height; - a.textrect.left = x * font_width; - a.textrect.right = (x + len) * font_width; + 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; if (!RectInRgn(&a.textrect, s->window->visRgn)) return; @@ -768,12 +758,12 @@ void do_text(struct mac_session *s, int x, int y, char *text, int len, SetRect(&a.leadrect, 0, 0, 0, 0); SetPort(s->window); TextFont(s->fontnum); - if (cfg.fontisbold || (attr & ATTR_BOLD) && !cfg.bold_colour) + if (s->cfg.fontisbold || (attr & ATTR_BOLD) && !s->cfg.bold_colour) style |= bold; if (attr & ATTR_UNDER) style |= underline; TextFace(style); - TextSize(cfg.fontheight); + TextSize(s->cfg.fontheight); SetFractEnable(FALSE); /* We want characters on pixel boundaries */ textrgn = NewRgn(); RectRgn(textrgn, &a.textrect); @@ -790,7 +780,7 @@ static pascal void do_text_for_device(short depth, short devflags, a = (struct do_text_args *)cookie; - bright = (a->attr & ATTR_BOLD) && cfg.bold_colour; + bright = (a->attr & ATTR_BOLD) && a->s->cfg.bold_colour; TextMode(a->attr & ATTR_REVERSE ? notSrcCopy : srcCopy); @@ -856,28 +846,28 @@ static pascal void do_text_for_device(short depth, short devflags, * Call from the terminal emulator to get its graphics context. * Should probably be called start_redraw or something. */ -struct mac_session *get_ctx(void) { - struct mac_session *s = onlysession; +void pre_paint(Session *s) { - attr_mask = ATTR_INVALID; + s->attr_mask = ATTR_INVALID; DeviceLoop(s->window->visRgn, &mac_set_attr_mask_upp, (long)s, 0); - return s; } static pascal void mac_set_attr_mask(short depth, short devflags, GDHandle device, long cookie) { + Session *s = (Session *)cookie; + switch (depth) { default: - attr_mask |= ATTR_FGMASK | ATTR_BGMASK; + s->attr_mask |= ATTR_FGMASK | ATTR_BGMASK; /* FALLTHROUGH */ case 2: - attr_mask |= ATTR_BOLD; + s->attr_mask |= ATTR_BOLD; /* FALLTHROUGH */ case 1: - attr_mask |= ATTR_UNDER | ATTR_REVERSE | ATTR_ACTCURS | + s->attr_mask |= ATTR_UNDER | ATTR_REVERSE | ATTR_ACTCURS | ATTR_PASCURS | ATTR_ASCII | ATTR_GBCHR | ATTR_LINEDRW | - (cfg.bold_colour ? 0 : ATTR_BOLD); + (s->cfg.bold_colour ? 0 : ATTR_BOLD); break; } } @@ -885,7 +875,7 @@ static pascal void mac_set_attr_mask(short depth, short devflags, /* * Presumably this does something in Windows */ -void free_ctx(struct mac_session *ctx) { +void post_paint(Session *s) { } @@ -896,14 +886,13 @@ void free_ctx(struct mac_session *ctx) { * start is the line number of the top of the display * page is the length of the displayed page */ -void set_sbar(int total, int start, int page) { - struct mac_session *s = onlysession; +void set_sbar(Session *s, int total, int start, int page) { /* We don't redraw until we've set everything up, to avoid glitches */ (*s->scrollbar)->contrlMin = 0; (*s->scrollbar)->contrlMax = total - page; SetControlValue(s->scrollbar, start); -#if 0 +#if TARGET_RT_CFM /* XXX: This doesn't link for me. */ if (mac_gestalts.cntlattr & gestaltControlMgrPresent) SetControlViewSize(s->scrollbar, page); @@ -913,7 +902,7 @@ void set_sbar(int total, int start, int page) { /* * Beep */ -void beep(void) { +void beep(Session *s) { SysBeep(30); /* @@ -925,16 +914,15 @@ void beep(void) { /* * Set icon string -- a no-op here (Windowshade?) */ -void set_icon(char *icon) { +void set_icon(Session *s, char *icon) { } /* * Set the window title */ -void set_title(char *title) { +void set_title(Session *s, char *title) { Str255 mactitle; - struct mac_session *s = onlysession; mactitle[0] = sprintf((char *)&mactitle[1], "%s", title); SetWTitle(s->window, mactitle); @@ -943,19 +931,18 @@ void set_title(char *title) { /* * Resize the window at the emulator's request */ -void request_resize(int w, int h) { +void request_resize(Session *s, int w, int h) { - cols = w; - rows = h; - mac_initfont(onlysession); + s->cols = w; + s->rows = h; + mac_initfont(s); } /* * Set the logical palette */ -void palette_set(int n, int r, int g, int b) { +void palette_set(Session *s, int n, int r, int g, int b) { RGBColor col; - struct mac_session *s = onlysession; static const int first[21] = { 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15, @@ -978,12 +965,12 @@ void palette_set(int n, int r, int g, int b) { /* * Reset to the default palette */ -void palette_reset(void) { - struct mac_session *s = onlysession; +void palette_reset(Session *s) { if (mac_gestalts.qdvers == gestaltOriginalQD) return; - CopyPalette(cfg.colours, s->palette, 0, 0, (*cfg.colours)->pmEntries); + CopyPalette(s->cfg.colours, s->palette, 0, 0, + (*s->cfg.colours)->pmEntries); mac_adjustwinbg(s); ActivatePalette(s->window); /* Palette Manager will generate update events as required. */ @@ -993,17 +980,16 @@ void palette_reset(void) { * Scroll the screen. (`lines' is +ve for scrolling forward, -ve * for backward.) */ -void do_scroll(int topline, int botline, int lines) { - struct mac_session *s = onlysession; +void do_scroll(Session *s, int topline, int botline, int lines) { Rect r; RgnHandle update; SetPort(s->window); PmBackColor(DEFAULT_BG); update = NewRgn(); - SetRect(&r, 0, topline * font_height, - cols * font_width, (botline + 1) * font_height); - ScrollRect(&r, 0, - lines * font_height, update); + SetRect(&r, 0, topline * s->font_height, + s->cols * s->font_width, (botline + 1) * s->font_height); + ScrollRect(&r, 0, - lines * s->font_height, update); /* XXX: move update region? */ InvalRgn(update); DisposeRgn(update); diff --git a/putty.h b/putty.h index 6e629b89..4c78be66 100644 --- a/putty.h +++ b/putty.h @@ -10,6 +10,8 @@ #ifdef macintosh #include #include +#include +#include typedef UInt32 DWORD; struct mac_session; #endif /* macintosh */ @@ -70,25 +72,11 @@ typedef HDC Context; #define GLOBAL extern #endif -GLOBAL unsigned long attr_mask; - -GLOBAL int rows, cols, savelines; - -GLOBAL int font_width, font_height; - #define INBUF_SIZE 2048 #define INBUF_MASK (INBUF_SIZE-1) -GLOBAL unsigned char inbuf[INBUF_SIZE]; -GLOBAL int inbuf_head, inbuf_reap; #define OUTBUF_SIZE 2048 #define OUTBUF_MASK (OUTBUF_SIZE-1) -GLOBAL unsigned char outbuf[OUTBUF_SIZE]; -GLOBAL int outbuf_head, outbuf_reap; - -GLOBAL int has_focus; - -GLOBAL int app_cursor_keys, app_keypad_keys; #define WM_NETEVENT (WM_USER + 1) @@ -109,21 +97,21 @@ typedef enum { VT_XWINDOWS, VT_OEMANSI, VT_OEMONLY, VT_POORMAN } VT_Mode; +typedef struct Session Session; + typedef struct { #ifdef macintosh - char *(*init) (char *host, int port, char **realhost); - int (*msg)(void); + char *(*init) (Session *, char *host, int port, char **realhost); + int (*msg)(Session *); #else /* not macintosh */ char *(*init) (HWND hwnd, char *host, int port, char **realhost); int (*msg) (WPARAM wParam, LPARAM lParam); #endif /* not macintosh */ - void (*send) (char *buf, int len); - void (*size) (void); - void (*special) (Telnet_Special code); + void (*send) (Session *, char *buf, int len); + void (*size) (Session *); + void (*special) (Session *, Telnet_Special code); } Backend; -GLOBAL Backend *back; - typedef struct { /* Basic options */ char host[512]; @@ -172,9 +160,79 @@ typedef struct { short wordness[256]; } Config; -GLOBAL Config cfg; - typedef struct { + /* Display buffers and pointers within them */ + unsigned long *text; /* buffer of text on terminal screen */ + unsigned long *scrtop; /* top of working screen */ + unsigned long *disptop; /* top of displayed screen */ + unsigned long *sbtop; /* top of scrollback */ + unsigned long *cpos; /* cursor position (convenience) */ + unsigned long *disptext; /* buffer of text on real screen */ + unsigned long *wanttext; /* buffer of text we want on screen */ + unsigned long *alttext; /* buffer of text on alt. screen */ + unsigned char *selspace; /* buffer for building selections in */ + + /* Current state */ + unsigned long curr_attr; + int curs_x, curs_y; /* cursor */ + int cset; /* 0 or 1: which char set is in GL */ + unsigned long cset_attr[2]; /* G0 and G1 char sets */ + + /* Saved state */ + unsigned long save_attr; + int save_x, save_y; /* saved cursor position */ + int save_cset, save_csattr; /* saved with cursor position */ + + int marg_t, marg_b; /* scroll margins */ + + /* Flags */ + int dec_om; /* DEC origin mode flag */ + int wrap, wrapnext; /* wrap flags */ + int insert; /* insert-mode flag */ + int rvideo; /* global reverse video flag */ + + /* + * Saved settings on the alternate screen. + */ + int alt_x, alt_y, alt_om, alt_wrap, alt_wnext, alt_ins, alt_cset; + int alt_t, alt_b; + int alt_which; + + /* Escape sequence handler state */ +#define ARGS_MAX 32 /* max # of esc sequence arguments */ + int esc_args[ARGS_MAX]; + int esc_nargs; + int esc_query; +#define OSC_STR_MAX 2048 + int osc_strlen; + char osc_string[OSC_STR_MAX+1]; + int osc_w; + + unsigned char *tabs; + int nl_count; + + enum { + TOPLEVEL, IGNORE_NEXT, + SEEN_ESC, SEEN_CSI, SET_GL, SET_GR, + SEEN_OSC, SEEN_OSC_P, SEEN_OSC_W, OSC_STRING, OSC_MAYBE_ST, + SEEN_ESCHASH + } termstate; + + enum { + NO_SELECTION, ABOUT_TO, DRAGGING, SELECTED + } selstate; + enum { + SM_CHAR, SM_WORD, SM_LINE + } selmode; + unsigned long *selstart, *selend, *selanchor; + short wordness[256]; +} Term_State; + +typedef struct Session { + /* Config that created this session */ + Config cfg; + /* Terminal emulator internal state */ + Term_State ts; /* Display state */ int rows, cols, savelines; int font_width, font_height; @@ -188,32 +246,40 @@ typedef struct { int app_cursor_keys, app_keypad_keys; /* Backend */ Backend *back; - /* Config that created this session */ - Config cfg; + /* Conveniences */ + unsigned long attr_mask; /* Mask of attributes to display */ +#ifdef macintosh + short fontnum; + int font_ascent; + int font_leading; + WindowPtr window; + PaletteHandle palette; + ControlHandle scrollbar; + WCTabHandle wctab; +#endif } Session; /* - * Exports from window.c. + * Exports from display system */ -void request_resize (int, int); -void do_text (Context, int, int, char *, int, unsigned long); -void set_title (char *); -void set_icon (char *); -void set_sbar (int, int, int); -Context get_ctx(); -void free_ctx (Context); -void palette_set (int, int, int, int); -void palette_reset (void); +extern void request_resize(Session *, int, int); +extern void do_text(Session *, int, int, char *, int, unsigned long); +extern void set_title(Session *, char *); +extern void set_icon(Session *, char *); +extern void set_sbar(Session *, int, int, int); +extern void pre_paint(Session *); +extern void post_paint(Session *); +extern void palette_set(Session *, int, int, int, int); +extern void palette_reset(Session *); void write_clip (void *, int); void get_clip (void **, int *); -void optimised_move (int, int, int); -void do_scroll(int, int, int); +extern void do_scroll(Session *, int, int, int); void fatalbox (const char *, ...); #ifdef macintosh #pragma noreturn (fatalbox) #endif -void beep (void); +extern void beep (Session *s); #define OPTIMISE_IS_SCROLL 1 /* @@ -241,20 +307,20 @@ void verify_ssh_host_key(char *host, struct RSAKey *key); * Exports from terminal.c. */ -void term_init (void); -void term_size (int, int, int); -void term_out (void); -void term_paint (Context, int, int, int, int); -void term_scroll (int, int); -void term_pwron (void); -void term_clrsb (void); -void term_mouse (Mouse_Button, Mouse_Action, int, int); -void term_copy(void); -void term_paste(void); -int term_hasselection(void); -void term_deselect (void); -void term_update (void); -void term_invalidate(void); +extern void term_init(Session *); +extern void term_size(Session *, int, int, int); +extern void term_out(Session *); +extern void term_paint(Session *, int, int, int, int); +extern void term_scroll(Session *, int, int); +extern void term_pwron(Session *); +extern void term_clrsb(Session *); +extern void term_mouse(Session *, Mouse_Button, Mouse_Action, int, int); +extern void term_copy(Session *); +extern void term_paste(Session *); +extern int term_hasselection(Session *); +extern void term_deselect (Session *); +extern void term_update (Session *); +extern void term_invalidate(Session *); /* * Exports from telnet.c. diff --git a/terminal.c b/terminal.c index aa5a9a63..00a12e79 100644 --- a/terminal.c +++ b/terminal.c @@ -7,100 +7,106 @@ #include #include "putty.h" -static unsigned long *text; /* buffer of text on terminal screen */ -static unsigned long *scrtop; /* top of working screen */ -static unsigned long *disptop; /* top of displayed screen */ -static unsigned long *sbtop; /* top of scrollback */ -static unsigned long *cpos; /* cursor position (convenience) */ -static unsigned long *disptext; /* buffer of text on real screen */ -static unsigned long *wanttext; /* buffer of text we want on screen */ -static unsigned long *alttext; /* buffer of text on alt. screen */ +#define cfg (s->cfg) +#define back (s->back) +#define rows (s->rows) +#define cols (s->cols) +#define savelines (s->savelines) +#define font_width (s->font_width) +#define font_height (s->font_height) +#define has_focus (s->has_focus) +#define inbuf (s->inbuf) +#define inbuf_head (s->inbuf_head) +#define inbuf_reap (s->inbuf_reap) +#define app_cursor_keys (s->app_cursor_keys) +#define app_keypad_keys (s->app_keypad_keys) +#define attr_mask (s->attr_mask) -static unsigned char *selspace; /* buffer for building selections in */ +#define text s->ts.text +#define scrtop s->ts.scrtop +#define disptop s->ts.disptop +#define sbtop s->ts.sbtop +#define cpos s->ts.cpos +#define disptext s->ts.disptext +#define wanttext s->ts.wanttext +#define alttext s->ts.alttext + +#define selspace s->ts.selspace #define TSIZE (sizeof(*text)) #define fix_cpos do { cpos = scrtop + curs_y * (cols+1) + curs_x; } while(0) -static unsigned long curr_attr, save_attr; +#define curr_attr s->ts.curr_attr +#define save_attr s->ts.save_attr -static int curs_x, curs_y; /* cursor */ -static int save_x, save_y; /* saved cursor position */ -static int marg_t, marg_b; /* scroll margins */ -static int dec_om; /* DEC origin mode flag */ -static int wrap, wrapnext; /* wrap flags */ -static int insert; /* insert-mode flag */ -static int cset; /* 0 or 1: which char set */ -static int save_cset, save_csattr; /* saved with cursor position */ -static int rvideo; /* global reverse video flag */ +#define curs_x s->ts.curs_x +#define curs_y s->ts.curs_y +#define save_x s->ts.save_x +#define save_y s->ts.save_y +#define marg_t s->ts.marg_t +#define marg_b s->ts.marg_b +#define curr_dec_om s->ts.dec_om +#define wrap s->ts.wrap +#define wrapnext s->ts.wrapnext +#define insert s->ts.insert +#define cset s->ts.cset +#define save_cset s->ts.save_cset +#define save_csattr s->ts.save_csattr +#define rvideo s->ts.rvideo +#define cset_attr s->ts.cset_attr -static unsigned long cset_attr[2]; +#define alt_x s->ts.alt_x +#define alt_y s->ts.alt_y +#define alt_om s->ts.alt_om +#define alt_wrap s->ts.alt_wrap +#define alt_wnext s->ts.alt_wnext +#define alt_ins s->ts.alt_ins +#define alt_cset s->ts.alt_cset +#define alt_t s->ts.alt_t +#define alt_b s->ts.alt_b +#define alt_which s->ts.alt_which -/* - * Saved settings on the alternate screen. - */ -static int alt_x, alt_y, alt_om, alt_wrap, alt_wnext, alt_ins, alt_cset; -static int alt_t, alt_b; -static int alt_which; - -#define ARGS_MAX 32 /* max # of esc sequence arguments */ #define ARG_DEFAULT -1 /* if an arg isn't specified */ #define def(a,d) ( (a) == ARG_DEFAULT ? (d) : (a) ) -static int esc_args[ARGS_MAX]; -static int esc_nargs; -static int esc_query; -#define OSC_STR_MAX 2048 -static int osc_strlen; -static char osc_string[OSC_STR_MAX+1]; -static int osc_w; +#define esc_args s->ts.esc_args +#define esc_nargs s->ts.esc_nargs +#define esc_query s->ts.esc_query -static unsigned char *tabs; +#define osc_strlen s->ts.osc_strlen +#define osc_string s->ts.osc_string +#define osc_w s->ts.osc_w + +#define tabs s->ts.tabs #define MAXNL 5 -static int nl_count; +#define nl_count s->ts.nl_count -static enum { - TOPLEVEL, IGNORE_NEXT, - SEEN_ESC, SEEN_CSI, SET_GL, SET_GR, - SEEN_OSC, SEEN_OSC_P, SEEN_OSC_W, OSC_STRING, OSC_MAYBE_ST, - SEEN_ESCHASH -} termstate; +#define termstate (s->ts.termstate) +#define selstate (s->ts.selstate) +#define selmode (s->ts.selmode) +#define selstart (s->ts.selstart) +#define selend (s->ts.selend) +#define selanchor (s->ts.selanchor) -static enum { - NO_SELECTION, ABOUT_TO, DRAGGING, SELECTED -} selstate; -static enum { - SM_CHAR, SM_WORD, SM_LINE -} selmode; -static unsigned long *selstart, *selend, *selanchor; - -static short wordness[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 01 */ - 0,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2, 2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1, /* 23 */ - 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2, /* 45 */ - 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1, /* 67 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 89 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* AB */ - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2, /* CD */ - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2, /* EF */ -}; +#define curr_wordness s->ts.wordness static unsigned char sel_nl[] = SEL_NL; /* * Internal prototypes. */ -static void do_paint (Context, int); -static void erase_lots (int, int, int); -static void swap_screen (int); -static void update_sbar (void); -static void deselect (void); -static void scroll_display(int, int, int); +static void do_paint (Session *, int); +static void erase_lots (Session *, int, int, int); +static void swap_screen (Session *, int); +static void update_sbar (Session *); +static void deselect (Session *); +static void scroll_display(Session *, int, int, int); /* * Set up power-on settings for the terminal. */ -static void power_on(void) { +static void power_on(Session *s) { curs_x = curs_y = alt_x = alt_y = save_x = save_y = 0; alt_t = marg_t = 0; if (rows != -1) @@ -112,7 +118,7 @@ static void power_on(void) { for (i = 0; i < cols; i++) tabs[i] = (i % 8 == 0 ? TRUE : FALSE); } - alt_om = dec_om = cfg.dec_om; + alt_om = curr_dec_om = cfg.dec_om; alt_wnext = wrapnext = alt_ins = insert = FALSE; alt_wrap = wrap = cfg.wrap_mode; alt_cset = cset = 0; @@ -125,66 +131,64 @@ static void power_on(void) { { int i; for (i = 0; i < 256; i++) - wordness[i] = cfg.wordness[i]; + curr_wordness[i] = cfg.wordness[i]; } if (text) { - swap_screen (1); - erase_lots (FALSE, TRUE, TRUE); - swap_screen (0); - erase_lots (FALSE, TRUE, TRUE); + swap_screen (s, 1); + erase_lots (s, FALSE, TRUE, TRUE); + swap_screen (s, 0); + erase_lots (s, FALSE, TRUE, TRUE); } } /* * Force a screen update. */ -void term_update(void) { - Context ctx; - ctx = get_ctx(); - if (ctx) { - do_paint (ctx, TRUE); - free_ctx (ctx); - nl_count = 0; - } +void term_update(Session *s) { + + pre_paint(s); + do_paint(s, TRUE); + post_paint(s); + nl_count = 0; } /* * Same as power_on(), but an external function. */ -void term_pwron(void) { - power_on(); +void term_pwron(Session *s) { + power_on(s); fix_cpos; disptop = scrtop; - deselect(); - term_update(); + deselect(s); + term_update(s); } /* * Clear the scrollback. */ -void term_clrsb(void) { +void term_clrsb(Session *s) { disptop = sbtop = scrtop; - update_sbar(); + update_sbar(s); } /* * Initialise the terminal. */ -void term_init(void) { +void term_init(Session *s) { text = sbtop = scrtop = disptop = cpos = NULL; disptext = wanttext = NULL; tabs = NULL; selspace = NULL; - deselect(); + deselect(s); rows = cols = -1; nl_count = 0; - power_on(); + power_on(s); } /* * Set up the terminal for a given size. */ -void term_size(int newrows, int newcols, int newsavelines) { +void term_size(Session *s, int newrows, int newcols, int newsavelines) { unsigned long *newtext, *newdisp, *newwant, *newalt; int i, j, crows, ccols; @@ -264,15 +268,15 @@ void term_size(int newrows, int newcols, int newsavelines) { savelines = newsavelines; fix_cpos; - deselect(); - update_sbar(); - term_update(); + deselect(s); + update_sbar(s); + term_update(s); } /* * Swap screens. */ -static void swap_screen (int which) { +static void swap_screen (Session *s, int which) { int t; unsigned long tt; @@ -289,7 +293,7 @@ static void swap_screen (int which) { t = curs_y; curs_y = alt_y; alt_y = t; t = marg_t; marg_t = alt_t; alt_t = t; t = marg_b; marg_b = alt_b; alt_b = t; - t = dec_om; dec_om = alt_om; alt_om = t; + t = curr_dec_om; curr_dec_om = alt_om; alt_om = t; t = wrap; wrap = alt_wrap; alt_wrap = t; t = wrapnext; wrapnext = alt_wnext; alt_wnext = t; t = insert; insert = alt_ins; alt_ins = t; @@ -301,7 +305,7 @@ static void swap_screen (int which) { /* * Retrieve a character from `inbuf'. */ -static int inbuf_getc(void) { +static int inbuf_getc(Session *s) { if (inbuf_head == inbuf_reap) return -1; /* EOF */ else { @@ -314,22 +318,23 @@ static int inbuf_getc(void) { /* * Update the scroll bar. */ -static void update_sbar(void) { +static void update_sbar(Session *s) { int min; min = (sbtop - text) / (cols+1); - set_sbar ((scrtop - text) / (cols+1) + rows - min, - (disptop - text) / (cols+1) - min, - rows); + set_sbar(s, (scrtop - text) / (cols+1) + rows - min, + (disptop - text) / (cols+1) - min, + rows); } /* * Check whether the region bounded by the two pointers intersects * the selection, and de-select the on-screen selection if so. */ -static void check_selection (unsigned long *from, unsigned long *to) { +static void check_selection(Session *s, + unsigned long *from, unsigned long *to) { if (from < selend && selstart < to) - deselect(); + deselect(s); } /* @@ -337,7 +342,7 @@ static void check_selection (unsigned long *from, unsigned long *to) { * for backward.) `sb' is TRUE if the scrolling is permitted to * affect the scrollback buffer. */ -static void scroll (int topline, int botline, int lines, int sb) { +static void scroll (Session *s, int topline, int botline, int lines, int sb) { unsigned long *scroll_top; int scroll_size, size, i; @@ -355,7 +360,7 @@ static void scroll (int topline, int botline, int lines, int sb) { sbtop = text; scroll_size += scroll_top - sbtop; scroll_top = sbtop; - update_sbar(); + update_sbar(s); } if (scroll_size < 0) { @@ -399,12 +404,12 @@ static void scroll (int topline, int botline, int lines, int sb) { } } #ifdef OPTIMISE_SCROLL - scroll_display(topline, botline, lines); + scroll_display(s, topline, botline, lines); #endif } #ifdef OPTIMISE_SCROLL -static void scroll_display(int topline, int botline, int lines) { +static void scroll_display(Session *s, int topline, int botline, int lines) { unsigned long *start, *end; int distance, size, i; @@ -421,7 +426,7 @@ static void scroll_display(int topline, int botline, int lines) { for (i = 0; i < distance; i++) start[i] |= ATTR_INVALID; } - do_scroll(topline, botline, lines); + do_scroll(s, topline, botline, lines); } #endif /* OPTIMISE_SCROLL */ @@ -432,7 +437,7 @@ static void scroll_display(int topline, int botline, int lines) { * not to, 1 to disallow _passing_ the margins, and 2 to disallow * even _being_ outside the margins. */ -static void move (int x, int y, int marg_clip) { +static void move (Session *s, int x, int y, int marg_clip) { if (x < 0) x = 0; if (x >= cols) @@ -456,7 +461,7 @@ static void move (int x, int y, int marg_clip) { /* * Save or restore the cursor and SGR mode. */ -static void save_cursor(int save) { +static void save_cursor(Session *s, int save) { if (save) { save_x = curs_x; save_y = curs_y; @@ -477,7 +482,7 @@ static void save_cursor(int save) { * Erase a large portion of the screen: the whole screen, or the * whole line, or parts thereof. */ -static void erase_lots (int line_only, int from_begin, int to_end) { +static void erase_lots(Session *s, int line_only, int from_begin, int to_end) { unsigned long *startpos, *endpos; if (line_only) { @@ -491,7 +496,7 @@ static void erase_lots (int line_only, int from_begin, int to_end) { startpos = cpos; if (!to_end) endpos = cpos; - check_selection (startpos, endpos); + check_selection(s, startpos, endpos); while (startpos < endpos) *startpos++ = ERASE_CHAR; } @@ -500,7 +505,7 @@ static void erase_lots (int line_only, int from_begin, int to_end) { * Insert or delete characters within the current line. n is +ve if * insertion is desired, and -ve for deletion. */ -static void insch (int n) { +static void insch(Session *s, int n) { int dir = (n < 0 ? -1 : +1); int m; @@ -508,7 +513,7 @@ static void insch (int n) { if (n > cols - curs_x) n = cols - curs_x; m = cols - curs_x - n; - check_selection (cpos, cpos+n); + check_selection(s, cpos, cpos+n); if (dir < 0) { memmove (cpos, cpos+n, m*TSIZE); while (n--) @@ -524,28 +529,28 @@ static void insch (int n) { * Toggle terminal mode `mode' to state `state'. (`query' indicates * whether the mode is a DEC private one or a normal one.) */ -static void toggle_mode (int mode, int query, int state) { +static void toggle_mode(Session *s, int mode, int query, int state) { if (query) switch (mode) { case 1: /* application cursor keys */ app_cursor_keys = state; break; case 3: /* 80/132 columns */ - deselect(); - request_resize (state ? 132 : 80, rows); + deselect(s); + request_resize(s, state ? 132 : 80, rows); break; case 5: /* reverse video */ rvideo = state; disptop = scrtop; break; case 6: /* DEC origin mode */ - dec_om = state; + curr_dec_om = state; break; case 7: /* auto wrap */ wrap = state; break; case 47: /* alternate screen */ - deselect(); - swap_screen (state); + deselect(s); + swap_screen(s, state); disptop = scrtop; break; } else switch (mode) { @@ -558,22 +563,22 @@ static void toggle_mode (int mode, int query, int state) { /* * Process an OSC sequence: set window title or icon name. */ -static void do_osc(void) { +static void do_osc(Session *s) { if (osc_w) { while (osc_strlen--) - wordness[(unsigned char)osc_string[osc_strlen]] = esc_args[0]; + curr_wordness[(unsigned char)osc_string[osc_strlen]] = esc_args[0]; } else { osc_string[osc_strlen] = '\0'; switch (esc_args[0]) { case 0: case 1: - set_icon (osc_string); + set_icon (s, osc_string); if (esc_args[0] == 1) break; /* fall through: parameter 0 means set both */ case 2: case 21: - set_title (osc_string); + set_title(s, osc_string); break; } } @@ -584,11 +589,11 @@ static void do_osc(void) { * in-memory display. There's a big state machine in here to * process escape sequences... */ -void term_out(void) { +void term_out(Session *s) { int c; int must_update = FALSE; - while ( (c = inbuf_getc()) != -1) { + while ( (c = inbuf_getc(s)) != -1) { #ifdef LOG { static FILE *fp = NULL; @@ -601,10 +606,10 @@ void term_out(void) { do_toplevel: switch (c) { case '\005': /* terminal type query */ - back->send ("\033[?1;2c", 7); + back->send(s, "\033[?1;2c", 7); break; case '\007': - beep(); + beep(s); disptop = scrtop; must_update = TRUE; break; @@ -649,7 +654,7 @@ void term_out(void) { case '\014': case '\012': if (curs_y == marg_b) - scroll (marg_t, marg_b, 1, TRUE); + scroll(s, marg_t, marg_b, 1, TRUE); else if (curs_y < rows-1) curs_y++; if (cfg.lfhascr) @@ -668,7 +673,7 @@ void term_out(void) { { unsigned long *old_cpos = cpos; fix_cpos; - check_selection (old_cpos, cpos); + check_selection(s, old_cpos, cpos); } disptop = scrtop; must_update = TRUE; @@ -678,7 +683,7 @@ void term_out(void) { if (wrapnext) { cpos[1] = ATTR_WRAPPED; if (curs_y == marg_b) - scroll (marg_t, marg_b, 1, TRUE); + scroll(s, marg_t, marg_b, 1, TRUE); else if (curs_y < rows-1) curs_y++; curs_x = 0; @@ -687,8 +692,8 @@ void term_out(void) { nl_count++; } if (insert) - insch (1); - check_selection (cpos, cpos+1); + insch(s, 1); + check_selection(s, cpos, cpos+1); *cpos++ = c | curr_attr | (c <= 0x7F ? cset_attr[cset] : ATTR_ASCII); curs_x++; @@ -711,7 +716,7 @@ void term_out(void) { * and _if_ we see a backslash, we process it. */ if (c == '\\') { - do_osc(); + do_osc(s); termstate = TOPLEVEL; break; } @@ -744,10 +749,10 @@ void term_out(void) { termstate = SET_GR; break; case '7': /* save cursor */ - save_cursor (TRUE); + save_cursor(s, TRUE); break; case '8': /* restore cursor */ - save_cursor (FALSE); + save_cursor(s, FALSE); disptop = scrtop; must_update = TRUE; break; @@ -759,7 +764,7 @@ void term_out(void) { break; case 'D': /* exactly equivalent to LF */ if (curs_y == marg_b) - scroll (marg_t, marg_b, 1, TRUE); + scroll(s, marg_t, marg_b, 1, TRUE); else if (curs_y < rows-1) curs_y++; fix_cpos; @@ -771,7 +776,7 @@ void term_out(void) { curs_x = 0; wrapnext = FALSE; if (curs_y == marg_b) - scroll (marg_t, marg_b, 1, TRUE); + scroll(s, marg_t, marg_b, 1, TRUE); else if (curs_y < rows-1) curs_y++; fix_cpos; @@ -781,7 +786,7 @@ void term_out(void) { break; case 'M': /* reverse index - backwards LF */ if (curs_y == marg_t) - scroll (marg_t, marg_b, -1, TRUE); + scroll(s, marg_t, marg_b, -1, TRUE); else if (curs_y > 0) curs_y--; fix_cpos; @@ -790,10 +795,10 @@ void term_out(void) { must_update = TRUE; break; case 'Z': /* terminal type query */ - back->send ("\033[?6c", 5); + back->send(s, "\033[?6c", 5); break; case 'c': /* restore power-on settings */ - power_on(); + power_on(s); fix_cpos; disptop = scrtop; must_update = TRUE; @@ -834,52 +839,52 @@ void term_out(void) { termstate = SEEN_CSI; break; case 'A': /* move up N lines */ - move (curs_x, curs_y - def(esc_args[0], 1), 1); + move(s, curs_x, curs_y - def(esc_args[0], 1), 1); disptop = scrtop; must_update = TRUE; break; case 'B': case 'e': /* move down N lines */ - move (curs_x, curs_y + def(esc_args[0], 1), 1); + move(s, curs_x, curs_y + def(esc_args[0], 1), 1); disptop = scrtop; must_update = TRUE; break; case 'C': case 'a': /* move right N cols */ - move (curs_x + def(esc_args[0], 1), curs_y, 1); + move(s, curs_x + def(esc_args[0], 1), curs_y, 1); disptop = scrtop; must_update = TRUE; break; case 'D': /* move left N cols */ - move (curs_x - def(esc_args[0], 1), curs_y, 1); + move(s, curs_x - def(esc_args[0], 1), curs_y, 1); disptop = scrtop; must_update = TRUE; break; case 'E': /* move down N lines and CR */ - move (0, curs_y + def(esc_args[0], 1), 1); + move(s, 0, curs_y + def(esc_args[0], 1), 1); disptop = scrtop; must_update = TRUE; break; case 'F': /* move up N lines and CR */ - move (0, curs_y - def(esc_args[0], 1), 1); + move(s, 0, curs_y - def(esc_args[0], 1), 1); disptop = scrtop; must_update = TRUE; break; case 'G': case '`': /* set horizontal posn */ - move (def(esc_args[0], 1) - 1, curs_y, 0); + move(s, def(esc_args[0], 1) - 1, curs_y, 0); disptop = scrtop; must_update = TRUE; break; case 'd': /* set vertical posn */ - move (curs_x, (dec_om ? marg_t : 0) + def(esc_args[0], 1) - 1, - (dec_om ? 2 : 0)); + move(s, curs_x, (curr_dec_om ? marg_t : 0) + def(esc_args[0], 1) - 1, + (curr_dec_om ? 2 : 0)); disptop = scrtop; must_update = TRUE; break; case 'H': case 'f': /* set horz and vert posns at once */ if (esc_nargs < 2) esc_args[1] = ARG_DEFAULT; - move (def(esc_args[1], 1) - 1, - (dec_om ? marg_t : 0) + def(esc_args[0], 1) - 1, - (dec_om ? 2 : 0)); + move(s, def(esc_args[1], 1) - 1, + (curr_dec_om ? marg_t : 0) + def(esc_args[0], 1) - 1, + (curr_dec_om ? 2 : 0)); disptop = scrtop; must_update = TRUE; break; @@ -888,7 +893,7 @@ void term_out(void) { unsigned int i = def(esc_args[0], 0) + 1; if (i > 3) i = 0; - erase_lots(FALSE, !!(i & 2), !!(i & 1)); + erase_lots(s, FALSE, !!(i & 2), !!(i & 1)); } disptop = scrtop; must_update = TRUE; @@ -898,48 +903,48 @@ void term_out(void) { unsigned int i = def(esc_args[0], 0) + 1; if (i > 3) i = 0; - erase_lots(TRUE, !!(i & 2), !!(i & 1)); + erase_lots(s, TRUE, !!(i & 2), !!(i & 1)); } disptop = scrtop; must_update = TRUE; break; case 'L': /* insert lines */ if (curs_y <= marg_b) - scroll (curs_y, marg_b, -def(esc_args[0], 1), FALSE); + scroll(s, curs_y, marg_b, -def(esc_args[0], 1), FALSE); disptop = scrtop; must_update = TRUE; break; case 'M': /* delete lines */ if (curs_y <= marg_b) - scroll (curs_y, marg_b, def(esc_args[0], 1), FALSE); + scroll(s, curs_y, marg_b, def(esc_args[0], 1), FALSE); disptop = scrtop; must_update = TRUE; break; case '@': /* insert chars */ - insch (def(esc_args[0], 1)); + insch(s, def(esc_args[0], 1)); disptop = scrtop; must_update = TRUE; break; case 'P': /* delete chars */ - insch (-def(esc_args[0], 1)); + insch(s, -def(esc_args[0], 1)); disptop = scrtop; must_update = TRUE; break; case 'c': /* terminal type query */ - back->send ("\033[?6c", 5); + back->send(s, "\033[?6c", 5); break; case 'n': /* cursor position query */ if (esc_args[0] == 6) { char buf[32]; sprintf (buf, "\033[%d;%dR", curs_y + 1, curs_x + 1); - back->send (buf, strlen(buf)); + back->send(s, buf, strlen(buf)); } break; case 'h': /* toggle a mode to high */ - toggle_mode (esc_args[0], esc_query, TRUE); + toggle_mode(s, esc_args[0], esc_query, TRUE); break; case 'l': /* toggle a mode to low */ - toggle_mode (esc_args[0], esc_query, FALSE); + toggle_mode(s, esc_args[0], esc_query, FALSE); break; case 'g': /* clear tabs */ if (esc_nargs == 1) { @@ -1024,16 +1029,16 @@ void term_out(void) { } break; case 's': /* save cursor */ - save_cursor (TRUE); + save_cursor(s, TRUE); break; case 'u': /* restore cursor */ - save_cursor (FALSE); + save_cursor(s, FALSE); disptop = scrtop; must_update = TRUE; break; case 't': /* set page size - ie window height */ - request_resize (cols, def(esc_args[0], 24)); - deselect(); + request_resize(s, cols, def(esc_args[0], 24)); + deselect(s); break; case 'X': /* write N spaces w/o moving cursor */ { @@ -1041,7 +1046,7 @@ void term_out(void) { unsigned long *p = cpos; if (n > cols - curs_x) n = cols - curs_x; - check_selection (cpos, cpos+n); + check_selection(s, cpos, cpos+n); while (n--) *p++ = ERASE_CHAR; disptop = scrtop; @@ -1055,7 +1060,7 @@ void term_out(void) { if (i == 0 || i == 1) { strcpy (buf, "\033[2;1;1;112;112;1;0x"); buf[2] += i; - back->send (buf, 20); + back->send(s, buf, 20); } } break; @@ -1089,8 +1094,8 @@ void term_out(void) { osc_strlen = 0; break; case 'R': /* Linux palette reset */ - palette_reset(); - term_invalidate(); + palette_reset(s); + term_invalidate(s); termstate = TOPLEVEL; break; case 'W': /* word-set */ @@ -1125,7 +1130,7 @@ void term_out(void) { * mode unless it is followed by \, in which case it is * synonymous with ST in the first place. */ - do_osc(); + do_osc(s); termstate = TOPLEVEL; } else if (c == '\033') termstate = OSC_MAYBE_ST; @@ -1146,11 +1151,10 @@ void term_out(void) { termstate = TOPLEVEL; osc_string[osc_strlen++] = val; if (osc_strlen >= 7) { - palette_set (osc_string[0], + palette_set (s, osc_string[0], osc_string[1] * 16 + osc_string[2], osc_string[3] * 16 + osc_string[4], osc_string[5] * 16 + osc_string[6]); - term_invalidate(); termstate = TOPLEVEL; } } @@ -1179,38 +1183,25 @@ void term_out(void) { *p++ = ATTR_DEFAULT | 'E'; disptop = scrtop; must_update = TRUE; - check_selection (scrtop, scrtop + rows * (cols+1)); + check_selection(s, scrtop, scrtop + rows * (cols+1)); } termstate = TOPLEVEL; break; } - check_selection (cpos, cpos+1); + check_selection(s, cpos, cpos+1); } if (must_update || nl_count > MAXNL) { - update_sbar(); - term_update(); + update_sbar(s); + term_update(s); } } -/* - * Compare two lines to determine whether they are sufficiently - * alike to scroll-optimise one to the other. Return the degree of - * similarity. - */ -static int linecmp (unsigned long *a, unsigned long *b) { - int i, n; - - for (i=n=0; i < cols; i++) - n += (*a++ == *b++); - return n; -} - /* * Given a context, update the window. Out of paranoia, we don't * allow WM_PAINT responses to do scrolling optimisations. */ -static void do_paint (Context ctx, int may_optimise){ +static void do_paint (Session *s, int may_optimise){ int i, j, start, our_curs_y; unsigned long attr, rv, cursor; char ch[1024]; @@ -1247,7 +1238,7 @@ static void do_paint (Context ctx, int may_optimise){ (t & attr_mask) == attr && j-start < sizeof(ch)); if (start != -1 && !keep_going) { - do_text (ctx, start, i, ch, j-start, attr); + do_text(s, start, i, ch, j-start, attr); start = -1; } if (needs_update) { @@ -1265,7 +1256,7 @@ static void do_paint (Context ctx, int may_optimise){ /* * Invalidate the whole screen so it will be repainted in full. */ -void term_invalidate(void) { +void term_invalidate(Session *s) { int i; for (i=0; i scrtop) disptop = scrtop; - update_sbar(); + update_sbar(s); #ifdef OPTIMISE_SCROLL shift = (disptop - olddisptop) / (cols + 1); if (shift < rows && shift > -rows) - scroll_display(0, rows - 1, shift); + scroll_display(s, 0, rows - 1, shift); #endif /* OPTIMISE_SCROLL */ - term_update(); + term_update(s); } /* * Spread the selection outwards according to the selection mode. */ -static unsigned long *sel_spread_half (unsigned long *p, int dir) { +static unsigned long *sel_spread_half(Session *s, unsigned long *p, int dir) { unsigned long *linestart, *lineend; int x; short wvalue; @@ -1351,12 +1342,12 @@ static unsigned long *sel_spread_half (unsigned long *p, int dir) { * In this mode, the units are maximal runs of characters * whose `wordness' has the same value. */ - wvalue = wordness[*p & CHAR_MASK]; + wvalue = curr_wordness[*p & CHAR_MASK]; if (dir == +1) { - while (p < lineend && wordness[p[1] & CHAR_MASK] == wvalue) + while (p < lineend && curr_wordness[p[1] & CHAR_MASK] == wvalue) p++; } else { - while (p > linestart && wordness[p[-1] & CHAR_MASK] == wvalue) + while (p > linestart && curr_wordness[p[-1] & CHAR_MASK] == wvalue) p--; } break; @@ -1370,12 +1361,12 @@ static unsigned long *sel_spread_half (unsigned long *p, int dir) { return p; } -static void sel_spread (void) { - selstart = sel_spread_half (selstart, -1); - selend = sel_spread_half (selend - 1, +1) + 1; +static void sel_spread(Session *s) { + selstart = sel_spread_half(s, selstart, -1); + selend = sel_spread_half(s, selend - 1, +1) + 1; } -void term_mouse (Mouse_Button b, Mouse_Action a, int x, int y) { +void term_mouse(Session *s, Mouse_Button b, Mouse_Action a, int x, int y) { unsigned long *selpoint; if (x < 0) { @@ -1392,17 +1383,17 @@ void term_mouse (Mouse_Button b, Mouse_Action a, int x, int y) { selpoint = scrtop + rows * (cols + 1) - 1; if (b == MB_SELECT && a == MA_CLICK) { - deselect(); + deselect(s); selstate = ABOUT_TO; selanchor = selpoint; selmode = SM_CHAR; } else if (b == MB_SELECT && (a == MA_2CLK || a == MA_3CLK)) { - deselect(); + deselect(s); selmode = (a == MA_2CLK ? SM_WORD : SM_LINE); selstate = DRAGGING; selstart = selanchor = selpoint; selend = selstart + 1; - sel_spread(); + sel_spread(s); } else if ((b == MB_SELECT && a == MA_DRAG) || (b == MB_EXTEND && a != MA_RELEASE)) { if (selstate == ABOUT_TO && selanchor == selpoint) @@ -1424,24 +1415,24 @@ void term_mouse (Mouse_Button b, Mouse_Action a, int x, int y) { selstart = selanchor; selend = selpoint + 1; } - sel_spread(); + sel_spread(s); } else if ((b == MB_SELECT || b == MB_EXTEND) && a == MA_RELEASE) if (selstate == DRAGGING) { if (cfg.implicit_copy) - term_copy(); + term_copy(s); selstate = SELECTED; } else selstate = NO_SELECTION; else if (b == MB_PASTE && (a==MA_CLICK || a==MA_2CLK || a==MA_3CLK)) - term_paste(); - term_update(); + term_paste(s); + term_update(s); } /* * We've completed a selection. We now transfer the * data to the clipboard. */ -void term_copy() { +void term_copy(Session *s) { unsigned char *p = selspace; unsigned long *q = selstart; @@ -1465,10 +1456,10 @@ void term_copy() { } q = lineend + 1; /* start of next line */ } - write_clip (selspace, p - selspace); + write_clip(selspace, p - selspace); } -void term_paste() { +void term_paste(Session *s) { char *data; int len; @@ -1481,10 +1472,10 @@ void term_paste() { !(p <= data+len-sizeof(sel_nl) && !memcmp(p, sel_nl, sizeof(sel_nl)))) p++; - back->send (q, p-q); + back->send(s, q, p-q); if (p <= data+len-sizeof(sel_nl) && !memcmp(p, sel_nl, sizeof(sel_nl))) { - back->send ("\015", 1); + back->send(s, "\015", 1); p += sizeof(sel_nl); } q = p; @@ -1496,17 +1487,17 @@ void term_paste() { /* * Find out if there's a selection. */ -int term_hasselection(void) { +int term_hasselection(Session *s) { return selstate == SELECTED; } -static void deselect (void) { +static void deselect(Session *s) { selstate = NO_SELECTION; selstart = selend = scrtop; } -void term_deselect (void) { - deselect(); - term_update(); +void term_deselect(Session *s) { + deselect(s); + term_update(s); } diff --git a/testback.c b/testback.c index 9ecf14a4..fcfcd000 100644 --- a/testback.c +++ b/testback.c @@ -1,4 +1,4 @@ -/* $Id: testback.c,v 1.1.2.4 1999/03/28 15:25:45 ben Exp $ */ +/* $Id: testback.c,v 1.1.2.5 1999/03/29 19:50:24 ben Exp $ */ /* * Copyright (c) 1999 Simon Tatham * Copyright (c) 1999 Ben Harris @@ -33,13 +33,13 @@ #include "putty.h" -static char *null_init(char *, int, char **); -static int null_msg(void); -static void null_send(char *, int); -static void loop_send(char *, int); -static void hexdump_send(char *, int); -static void null_size(void); -static void null_special(Telnet_Special); +static char *null_init(Session *, char *, int, char **); +static int null_msg(Session *); +static void null_send(Session *, char *, int); +static void loop_send(Session *, char *, int); +static void hexdump_send(Session *, char *, int); +static void null_size(Session *); +static void null_special(Session *, Telnet_Special); Backend null_backend = { null_init, null_msg, null_send, null_size, null_special @@ -53,49 +53,49 @@ Backend hexdump_backend = { null_init, null_msg, hexdump_send, null_size, null_special }; -static char *null_init(char *host, int port, char **realhost) { +static char *null_init(Session *s, char *host, int port, char **realhost) { return NULL; } -static int null_msg(void) { +static int null_msg(Session *s) { return 1; } -static void null_send(char *buf, int len) { +static void null_send(Session *s, char *buf, int len) { } -static void loop_send (char *buf, int len) { +static void loop_send (Session *s, char *buf, int len) { while (len--) { - int new_head = (inbuf_head + 1) & INBUF_MASK; + int new_head = (s->inbuf_head + 1) & INBUF_MASK; int c = (unsigned char) *buf; - if (new_head != inbuf_reap) { - inbuf[inbuf_head] = *buf++; - inbuf_head = new_head; + if (new_head != s->inbuf_reap) { + s->inbuf[s->inbuf_head] = *buf++; + s->inbuf_head = new_head; } } - term_out(); - term_update(); + term_out(s); + term_update(s); } -static void hexdump_send(char *buf, int len) { +static void hexdump_send(Session *s, char *buf, int len) { static char mybuf[10]; int mylen; while (len--) { mylen = sprintf(mybuf, "%02x\015\012", (unsigned char)*buf++); - loop_send(mybuf, mylen); + loop_send(s, mybuf, mylen); } } -static void null_size(void) { +static void null_size(Session *s) { } -static void null_special(Telnet_Special code) { +static void null_special(Session *s, Telnet_Special code) { }