X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/d082ac49971a1c1a9e84c5b201c30aab675f154f..fabd1805a8f429ca83b4271aabd1206ac3537ebb:/mac/mac.c diff --git a/mac/mac.c b/mac/mac.c index add219b7..52258c36 100644 --- a/mac/mac.c +++ b/mac/mac.c @@ -1,4 +1,4 @@ -/* $Id: mac.c,v 1.1 2002/11/19 02:13:46 ben Exp $ */ +/* $Id: mac.c,v 1.32 2003/01/15 23:30:21 ben Exp $ */ /* * Copyright (c) 1999 Ben Harris * All rights reserved. @@ -40,9 +40,12 @@ #include #include #include +#include #include -#include +#include +#include #include +#include #include #include @@ -54,10 +57,13 @@ #include "macresid.h" #include "putty.h" +#include "ssh.h" #include "mac.h" QDGlobals qd; +Session *sesslist; + static int cold = 1; struct mac_gestalts mac_gestalts; @@ -70,16 +76,18 @@ static void mac_growwindow(WindowPtr, EventRecord *); static void mac_activatewindow(WindowPtr, EventRecord *); static void mac_activateabout(WindowPtr, EventRecord *); static void mac_updatewindow(WindowPtr); +static void mac_updatelicence(WindowPtr); static void mac_keypress(EventRecord *); static int mac_windowtype(WindowPtr); static void mac_menucommand(long); static void mac_openabout(void); +static void mac_openlicence(void); static void mac_adjustcursor(RgnHandle); static void mac_adjustmenus(void); static void mac_closewindow(WindowPtr); static void mac_zoomwindow(WindowPtr, short); static void mac_shutdown(void); -#pragma noreturn (mac_shutdown) +#pragma noreturn (cleanup_exit) struct mac_windows { WindowPtr about; @@ -98,6 +106,7 @@ int main (int argc, char **argv) { static void mac_startup(void) { Handle menuBar; + TECInfoHandle ti; /* Init Memory Manager */ MaxApplZone(); @@ -112,16 +121,13 @@ static void mac_startup(void) { /* Init TextEdit */ TEInit(); /* Init Dialog Manager */ - InitDialogs(nil); + InitDialogs(NULL); cold = 0; - /* Check for the Thread Manager. Bail out if it's not there. */ - if (Gestalt(gestaltThreadMgrAttr, &mac_gestalts.thdsattr) != noErr || - !(mac_gestalts.thdsattr & (1 << gestaltThreadMgrPresent)) || - &NewThread == kUnresolvedCFragSymbolAddress) - fatalbox("PuTTY requires the Thread Manager in order to operate. " - "The Thread Manager can be obtained from Apple Software " - "Updates."); + /* Get base system version (only used if there's no better selector) */ + if (Gestalt(gestaltSystemVersion, &mac_gestalts.sysvers) != noErr || + (mac_gestalts.sysvers &= 0xffff) < 0x700) + fatalbox("PuTTY requires System 7 or newer"); /* Find out if we've got Color Quickdraw */ if (Gestalt(gestaltQuickdrawVersion, &mac_gestalts.qdvers) != noErr) mac_gestalts.qdvers = gestaltOriginalQD; @@ -136,12 +142,48 @@ static void mac_startup(void) { if (&RegisterAppearanceClient == kUnresolvedCFragSymbolAddress) mac_gestalts.apprvers = 0; #endif +#if TARGET_CPU_68K + mac_gestalts.cntlattr = 0; + mac_gestalts.windattr = 0; +#else /* Mac OS 8.5 Control Manager (proportional scrollbars)? */ - if (Gestalt(gestaltControlMgrAttr, &mac_gestalts.cntlattr) != noErr) + if (Gestalt(gestaltControlMgrAttr, &mac_gestalts.cntlattr) != noErr || + &SetControlViewSize == kUnresolvedCFragSymbolAddress) mac_gestalts.cntlattr = 0; /* Mac OS 8.5 Window Manager? */ - if (Gestalt(gestaltWindowMgrAttr, &mac_gestalts.windattr) != noErr) + if (Gestalt(gestaltWindowMgrAttr, &mac_gestalts.windattr) != noErr || + &SetWindowContentColor == kUnresolvedCFragSymbolAddress) mac_gestalts.windattr = 0; +#endif + /* Text Encoding Conversion Manager? */ + if ( +#if TARGET_RT_MAC_CFM + &TECGetInfo == kUnresolvedCFragSymbolAddress || +#else + InitializeUnicodeConverter(NULL) != noErr || +#endif + TECGetInfo(&ti) != noErr) + mac_gestalts.encvvers = 0; + else { + mac_gestalts.encvvers = (*ti)->tecVersion; + mac_gestalts.uncvattr = (*ti)->tecUnicodeConverterFeatures; + DisposeHandle((Handle)ti); + } + /* OpenTransport? */ + if (Gestalt(gestaltOpenTpt, &mac_gestalts.otptattr) != noErr || + (mac_gestalts.otptattr & gestaltOpenTptTCPPresentMask) == 0 || + ot_init() != noErr) + mac_gestalts.otptattr = 0; + if (mac_gestalts.otptattr == 0) { + /* MacTCP? */ + if (Gestalt(FOUR_CHAR_CODE('mtcp'), &mac_gestalts.mtcpvers) != noErr) + mac_gestalts.mtcpvers = 0; + if (mac_gestalts.mtcpvers > 0) { + if (mactcp_init() != noErr) + mac_gestalts.mtcpvers = 0; + } + } else + mac_gestalts.mtcpvers = 0; /* We've been tested with the Appearance Manager */ if (mac_gestalts.apprvers != 0) @@ -158,7 +200,30 @@ static void mac_startup(void) { windows.about = NULL; windows.licence = NULL; - init_ucs(); + default_protocol = be_default_protocol; + /* Find the appropriate default port. */ + { + int i; + default_port = 0; /* illegal */ + for (i = 0; backends[i].backend != NULL; i++) + if (backends[i].protocol == default_protocol) { + default_port = backends[i].backend->default_port; + break; + } + } + flags = FLAG_INTERACTIVE; + + { + short vol; + long dirid; + + /* Set the default directory for loading and saving settings. */ + /* XXX Should we create it? */ + if (get_session_dir(FALSE, &vol, &dirid) == noErr) { + LMSetSFSaveDisk(-vol); + LMSetCurDirStore(dirid); + } + } } static void mac_eventloop(void) { @@ -173,7 +238,11 @@ static void mac_eventloop(void) { mac_adjustcursor(cursrgn); if (gotevent) mac_event(&event); - YieldToAnyThread(); + if (mac_gestalts.mtcpvers != 0) + mactcp_poll(); + if (mac_gestalts.otptattr != 0) + ot_poll(); + mac_pollterm(); } DisposeRgn(cursrgn); } @@ -246,13 +315,16 @@ static void mac_contentclick(WindowPtr window, EventRecord *event) { mac_clickterm(window, event); break; case wAbout: - if (DialogSelect(event, &(DialogPtr)window, &item)) + if (DialogSelect(event, &window, &item)) switch (item) { case wiAboutLicence: - /* XXX: Do something */ + mac_openlicence(); break; } break; + case wSettings: + mac_clickdlg(window, event); + break; } } @@ -273,6 +345,9 @@ static void mac_activatewindow(WindowPtr window, EventRecord *event) { case wTerminal: mac_activateterm(window, active); break; + case wSettings: + mac_activatedlg(window, event); + break; case wAbout: mac_activateabout(window, event); break; @@ -299,22 +374,45 @@ static void mac_updatewindow(WindowPtr window) { mac_updateterm(window); break; case wAbout: + case wSettings: BeginUpdate(window); UpdateDialog(window, window->visRgn); EndUpdate(window); break; case wLicence: - /* Do something */ - break; + mac_updatelicence(window); + break; } } +static void mac_updatelicence(WindowPtr window) +{ + Handle h; + int len; + long fondsize; + + SetPort(window); + BeginUpdate(window); + fondsize = GetScriptVariable(smRoman, smScriptSmallFondSize); + TextFont(HiWord(fondsize)); + TextSize(LoWord(fondsize)); + h = Get1Resource('TEXT', wLicence); + len = GetResourceSizeOnDisk(h); + if (h != NULL) { + HLock(h); + TETextBox(*h, len, &window->portRect, teFlushDefault); + HUnlock(h); + } + EndUpdate(window); +} + /* * Work out what kind of window we're dealing with. * Concept shamelessly nicked from SurfWriter. */ static int mac_windowtype(WindowPtr window) { int kind; + long refcon; if (window == NULL) return wNone; @@ -323,7 +421,11 @@ static int mac_windowtype(WindowPtr window) { return wDA; if (GetWVariant(window) == zoomDocProc) return wTerminal; - return GetWRefCon(window); + refcon = GetWRefCon(window); + if (refcon < 1024) + return refcon; + else + return wSettings; } /* @@ -377,11 +479,14 @@ static void mac_menucommand(long result) { case iNew: mac_newsession(); goto done; + case iOpen: + mac_opensession(); + goto done; case iClose: mac_closewindow(window); goto done; case iQuit: - mac_shutdown(); + cleanup_exit(0); goto done; } break; @@ -407,17 +512,28 @@ static void mac_openabout(void) { SelectWindow(windows.about); else { windows.about = GetNewDialog(wAbout, NULL, (WindowPtr)-1); - /* XXX check we're using the right resource file? */ - vers = (VersRecHndl)GetResource('vers', 1); - assert(vers != NULL && *vers != NULL); - longvers = (*vers)->shortVersion + (*vers)->shortVersion[0] + 1; - GetDialogItem(windows.about, wiAboutVersion, &itemtype, &item, &box); - assert(itemtype & kStaticTextDialogItem); - SetDialogItemText(item, longvers); + vers = (VersRecHndl)Get1Resource('vers', 1); + if (vers != NULL && *vers != NULL) { + longvers = (*vers)->shortVersion + (*vers)->shortVersion[0] + 1; + GetDialogItem(windows.about, wiAboutVersion, + &itemtype, &item, &box); + assert(itemtype & kStaticTextDialogItem); + SetDialogItemText(item, longvers); + } ShowWindow(windows.about); } } +static void mac_openlicence(void) { + + if (windows.licence) + SelectWindow(windows.licence); + else { + windows.licence = GetNewWindow(wLicence, NULL, (WindowPtr)-1); + ShowWindow(windows.licence); + } +} + static void mac_closewindow(WindowPtr window) { switch (mac_windowtype(window)) { @@ -425,14 +541,15 @@ static void mac_closewindow(WindowPtr window) { CloseDeskAcc(((WindowPeek)window)->windowKind); break; case wTerminal: - /* FIXME: end session and stuff */ + mac_closeterm(window); break; case wAbout: windows.about = NULL; - CloseWindow(window); + DisposeDialog(window); break; - default: - CloseWindow(window); + case wLicence: + windows.licence = NULL; + DisposeWindow(window); break; } } @@ -506,9 +623,15 @@ static void mac_adjustcursor(RgnHandle cursrgn) { } } -static void mac_shutdown(void) { +void cleanup_exit(int status) +{ - exit(0); +#if !TARGET_RT_MAC_CFM + if (mac_gestalts.encvvers != 0) + TerminateUnicodeConverter(); +#endif + sk_cleanup(); + exit(status); } void fatalbox(char *fmt, ...) { @@ -520,8 +643,8 @@ void fatalbox(char *fmt, ...) { stuff[0] = vsprintf((char *)(&stuff[1]), fmt, ap); va_end(ap); ParamText(stuff, NULL, NULL, NULL); - StopAlert(128, nil); - exit(1); + StopAlert(128, NULL); + cleanup_exit(1); } void modalfatalbox(char *fmt, ...) { @@ -533,8 +656,107 @@ void modalfatalbox(char *fmt, ...) { stuff[0] = vsprintf((char *)(&stuff[1]), fmt, ap); va_end(ap); ParamText(stuff, NULL, NULL, NULL); - StopAlert(128, nil); - exit(1); + StopAlert(128, NULL); + cleanup_exit(1); +} + +/* This should only kill the current session, not the whole application. */ +void connection_fatal(void *fontend, char *fmt, ...) { + va_list ap; + Str255 stuff; + + va_start(ap, fmt); + /* We'd like stuff to be a Pascal string */ + stuff[0] = vsprintf((char *)(&stuff[1]), fmt, ap); + va_end(ap); + ParamText(stuff, NULL, NULL, NULL); + StopAlert(128, NULL); + cleanup_exit(1); +} + +/* Null SSH agent client -- never finds an agent. */ + +int agent_exists(void) +{ + + return FALSE; +} + +void agent_query(void *in, int inlen, void **out, int *outlen) +{ + + *out = NULL; + *outlen = 0; +} + +/* Temporary null routines for testing. */ + +void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, + char *keystr, char *fingerprint) +{ + +} + +void askcipher(void *frontend, char *ciphername, int cs) +{ + +} + +void old_keyfile_warning(void) +{ + +} + +char *platform_default_s(char const *name) +{ + long smfs; + Str255 pname; + static char cname[256]; + + if (!strcmp(name, "Font")) { + smfs = GetScriptVariable(smSystemScript, smScriptMonoFondSize); + if (smfs == 0) + smfs = GetScriptVariable(smRoman, smScriptMonoFondSize); + if (smfs != 0) { + GetFontName(HiWord(smfs), pname); + if (pname[0] == 0) + return "Monaco"; + p2cstrcpy(cname, pname); + return cname; + } else + return "Monaco"; + } + return NULL; +} + +int platform_default_i(char const *name, int def) +{ + long smfs; + + if (!strcmp(name, "FontHeight")) { + smfs = GetScriptVariable(smSystemScript, smScriptMonoFondSize); + if (smfs == 0) + smfs = GetScriptVariable(smRoman, smScriptMonoFondSize); + if (smfs != 0) + return LoWord(smfs); + else + return 9; + } + + /* Non-raw cut and paste of line-drawing chars works badly on the + * current Unix stub implementation of the Unicode functions. + * So I'm going to temporarily set the default to raw mode so + * that the failure mode isn't quite so drastically horrid. + * When Unicode comes in, this can all be put right. */ + if (!strcmp(name, "RawCNP")) + return 1; + return def; +} + +void platform_get_x11_auth(char *display, int *proto, + unsigned char *data, int *datalen) +{ + /* SGT: I have no idea whether Mac X servers need anything here. */ } /*