X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/fbf6cb3b1fcbb6c3a19dd61d308d116878ed2d3d..7440fd4419acfc9c784f142fb9dee3e64c9a18c2:/window.c diff --git a/window.c b/window.c index 3c3cdb68..5174b46f 100644 --- a/window.c +++ b/window.c @@ -1,23 +1,3 @@ -#include -#include -#include -#include -#include -#ifndef AUTO_WINSOCK -#ifdef WINSOCK_TWO -#include -#else -#include -#endif -#endif - -#ifndef NO_MULTIMON -#if WINVER < 0x0500 -#define COMPILE_MULTIMON_STUBS -#include -#endif -#endif - #include #include #include @@ -27,10 +7,21 @@ #define PUTTY_DO_GLOBALS /* actually _define_ globals */ #include "putty.h" #include "terminal.h" -#include "winstuff.h" #include "storage.h" #include "win_res.h" +#ifndef NO_MULTIMON +#if WINVER < 0x0500 +#define COMPILE_MULTIMON_STUBS +#include +#endif +#endif + +#include +#include +#include +#include + #define IDM_SHOWLOG 0x0010 #define IDM_NEWSESS 0x0020 #define IDM_DUPSESS 0x0030 @@ -55,6 +46,7 @@ #define WM_IGNORE_CLIP (WM_XUSER + 2) #define WM_FULLSCR_ON_MAX (WM_XUSER + 3) +#define WM_AGENT_CALLBACK (WM_XUSER + 4) /* Needed for Chinese support and apparently not always defined. */ #ifndef VK_PROCESSKEY @@ -74,6 +66,7 @@ static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned char *output); static void cfgtopalette(void); +static void systopalette(void); static void init_palette(void); static void init_fonts(int, int); static void another_font(int); @@ -122,6 +115,13 @@ Config cfg; /* exported to windlg.c */ extern struct sesslist sesslist; /* imported from windlg.c */ +struct agent_callback { + void (*callback)(void *, void *, int); + void *callback_ctx; + void *data; + int len; +}; + #define FONT_NORMAL 0 #define FONT_BOLD 1 #define FONT_UNDERLINE 2 @@ -169,10 +169,6 @@ static char *window_name, *icon_name; static int compose_state = 0; -static int wsa_started = 0; - -static OSVERSIONINFO osVersion; - static UINT wm_mousewheel = WM_MOUSEWHEEL; /* Dummy routine, only required in plink. */ @@ -182,8 +178,6 @@ void ldisc_update(void *frontend, int echo, int edit) int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { - WORD winsock_ver; - WSADATA wsadata; WNDCLASS wndclass; MSG msg; int guess_width, guess_height; @@ -191,20 +185,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) hinst = inst; flags = FLAG_VERBOSE | FLAG_INTERACTIVE; - winsock_ver = MAKEWORD(1, 1); - if (WSAStartup(winsock_ver, &wsadata)) { - MessageBox(NULL, "Unable to initialise WinSock", "WinSock Error", - MB_OK | MB_ICONEXCLAMATION); - return 1; - } - if (LOBYTE(wsadata.wVersion) != 1 || HIBYTE(wsadata.wVersion) != 1) { - MessageBox(NULL, "WinSock version is incompatible with 1.1", - "WinSock Error", MB_OK | MB_ICONEXCLAMATION); - WSACleanup(); - return 1; - } - wsa_started = 1; - /* WISHLIST: maybe allow config tweaking even if winsock not present? */ sk_init(); InitCommonControls(); @@ -213,16 +193,13 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) * config box. */ defuse_showwindow(); + if (!init_winver()) { - ZeroMemory(&osVersion, sizeof(osVersion)); - osVersion.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); - if (!GetVersionEx ( (OSVERSIONINFO *) &osVersion)) { - char *str = dupprintf("%s Fatal Error", appname); - MessageBox(NULL, "Windows refuses to report a version", - str, MB_OK | MB_ICONEXCLAMATION); - sfree(str); - return 1; - } + char *str = dupprintf("%s Fatal Error", appname); + MessageBox(NULL, "Windows refuses to report a version", + str, MB_OK | MB_ICONEXCLAMATION); + sfree(str); + return 1; } /* @@ -301,8 +278,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) p[i] = '\0'; do_defaults(p + 1, &cfg); if (!*cfg.host && !do_config()) { - WSACleanup(); - return 0; + cleanup_exit(0); } } else if (*p == '&') { /* @@ -320,8 +296,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) UnmapViewOfFile(cp); CloseHandle(filemap); } else if (!do_config()) { - WSACleanup(); - return 0; + cleanup_exit(0); } } else { /* @@ -426,8 +401,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) cmdline_run_saved(&cfg); if (!*cfg.host && !do_config()) { - WSACleanup(); - return 0; + cleanup_exit(0); } /* @@ -489,8 +463,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) MessageBox(NULL, "Unsupported protocol number found", str, MB_OK | MB_ICONEXCLAMATION); sfree(str); - WSACleanup(); - return 1; + cleanup_exit(1); } } @@ -500,8 +473,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) MessageBox(NULL, "Invalid Port Number", str, MB_OK | MB_ICONEXCLAMATION); sfree(str); - WSACleanup(); - return 1; + cleanup_exit(1); } if (!prev) { @@ -628,7 +600,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) * Start up the telnet connection. */ { - char *error; + const char *error; char msg[1024], *title; char *realhost; @@ -836,8 +808,6 @@ void cleanup_exit(int code) if (pal) DeleteObject(pal); sk_cleanup(); - if (wsa_started) - WSACleanup(); if (cfg.protocol == PROT_SSH) { random_save_seed(); @@ -864,8 +834,8 @@ char *do_select(SOCKET skt, int startup) } if (!hwnd) return "do_select(): internal error (hwnd==NULL)"; - if (WSAAsyncSelect(skt, hwnd, msg, events) == SOCKET_ERROR) { - switch (WSAGetLastError()) { + if (p_WSAAsyncSelect(skt, hwnd, msg, events) == SOCKET_ERROR) { + switch (p_WSAGetLastError()) { case WSAENETDOWN: return "Network is down"; default: @@ -922,13 +892,15 @@ void set_raw_mouse_mode(void *frontend, int activate) void connection_fatal(void *frontend, char *fmt, ...) { va_list ap; - char stuff[200], morestuff[100]; + char *stuff, morestuff[100]; va_start(ap, fmt); - vsprintf(stuff, fmt, ap); + stuff = dupvprintf(fmt, ap); va_end(ap); sprintf(morestuff, "%.70s Fatal Error", appname); MessageBox(hwnd, stuff, morestuff, MB_ICONERROR | MB_OK); + sfree(stuff); + if (cfg.close_on_exit == FORCE_ON) PostQuitMessage(1); else { @@ -945,13 +917,14 @@ void connection_fatal(void *frontend, char *fmt, ...) void cmdline_error(char *fmt, ...) { va_list ap; - char stuff[200], morestuff[100]; + char *stuff, morestuff[100]; va_start(ap, fmt); - vsprintf(stuff, fmt, ap); + stuff = dupvprintf(fmt, ap); va_end(ap); sprintf(morestuff, "%.70s Command Line Error", appname); MessageBox(hwnd, stuff, morestuff, MB_ICONERROR | MB_OK); + sfree(stuff); exit(1); } @@ -1009,6 +982,38 @@ static void cfgtopalette(void) defpal[i].rgbtGreen = cfg.colours[w][1]; defpal[i].rgbtBlue = cfg.colours[w][2]; } + + /* Override with system colours if appropriate */ + if (cfg.system_colour) + systopalette(); +} + +/* + * Override bit of defpal with colours from the system. + * (NB that this takes a copy the system colours at the time this is called, + * so subsequent colour scheme changes don't take effect. To fix that we'd + * probably want to be using GetSysColorBrush() and the like.) + */ +static void systopalette(void) +{ + int i; + static const struct { int nIndex; int norm; int bold; } or[] = + { + { COLOR_WINDOWTEXT, 16, 17 }, /* Default Foreground */ + { COLOR_WINDOW, 18, 19 }, /* Default Background */ + { COLOR_HIGHLIGHTTEXT, 20, 21 }, /* Cursor Text */ + { COLOR_HIGHLIGHT, 22, 23 }, /* Cursor Colour */ + }; + + for (i = 0; i < (sizeof(or)/sizeof(or[0])); i++) { + COLORREF colour = GetSysColor(or[i].nIndex); + defpal[or[i].norm].rgbtRed = + defpal[or[i].bold].rgbtRed = GetRValue(colour); + defpal[or[i].norm].rgbtGreen = + defpal[or[i].bold].rgbtGreen = GetGValue(colour); + defpal[or[i].norm].rgbtBlue = + defpal[or[i].bold].rgbtBlue = GetBValue(colour); + } } /* @@ -2575,6 +2580,14 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, SetCursor(LoadCursor(NULL, IDC_ARROW)); return TRUE; } + break; + case WM_AGENT_CALLBACK: + { + struct agent_callback *c = (struct agent_callback *)lParam; + c->callback(c->callback_ctx, c->data, c->len); + sfree(c); + } + return 0; default: if (message == wm_mousewheel || message == WM_MOUSEWHEEL) { int shift_pressed=0, control_pressed=0; @@ -3518,6 +3531,10 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, *p++ = 0x1C; return p - output; } + if (shift_state == 3 && wParam == 0xDE) { + *p++ = 0x1E; /* Ctrl-~ == Ctrl-^ in xterm at least */ + return p - output; + } if (shift_state == 0 && wParam == VK_RETURN && term->cr_lf_return) { *p++ = '\r'; *p++ = '\n'; @@ -3853,9 +3870,10 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, ldisc_send(ldisc, &ch, 1, 1); } alt_sum = 0; - } else + } else { term_seen_key_event(term); lpage_send(ldisc, kbd_codepage, &ch, 1, 1); + } } else { if(capsOn && ch < 0x80) { WCHAR cbuf[2]; @@ -4286,13 +4304,14 @@ void optimised_move(void *frontend, int to, int from, int lines) void fatalbox(char *fmt, ...) { va_list ap; - char stuff[200], morestuff[100]; + char *stuff, morestuff[100]; va_start(ap, fmt); - vsprintf(stuff, fmt, ap); + stuff = dupvprintf(fmt, ap); va_end(ap); sprintf(morestuff, "%.70s Fatal Error", appname); MessageBox(hwnd, stuff, morestuff, MB_ICONERROR | MB_OK); + sfree(stuff); cleanup_exit(1); } @@ -4302,14 +4321,15 @@ void fatalbox(char *fmt, ...) void modalfatalbox(char *fmt, ...) { va_list ap; - char stuff[200], morestuff[100]; + char *stuff, morestuff[100]; va_start(ap, fmt); - vsprintf(stuff, fmt, ap); + stuff = dupvprintf(fmt, ap); va_end(ap); sprintf(morestuff, "%.70s Fatal Error", appname); MessageBox(hwnd, stuff, morestuff, MB_SYSTEMMODAL | MB_ICONERROR | MB_OK); + sfree(stuff); cleanup_exit(1); } @@ -4385,6 +4405,23 @@ void beep(void *frontend, int mode) MB_OK | MB_ICONEXCLAMATION); cfg.beep = BELL_DEFAULT; } + } else if (mode == BELL_PCSPEAKER) { + static long lastbeep = 0; + long beepdiff; + + beepdiff = GetTickCount() - lastbeep; + if (beepdiff >= 0 && beepdiff < 50) + return; + + /* + * We must beep in different ways depending on whether this + * is a 95-series or NT-series OS. + */ + if(osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) + Beep(800, 100); + else + MessageBeep(-1); + lastbeep = GetTickCount(); } /* Otherwise, either visual bell or disabled; do nothing here */ if (!term->has_focus) { @@ -4626,3 +4663,14 @@ int from_backend(void *frontend, int is_stderr, const char *data, int len) { return term_data(term, is_stderr, data, len); } + +void agent_schedule_callback(void (*callback)(void *, void *, int), + void *callback_ctx, void *data, int len) +{ + struct agent_callback *c = snew(struct agent_callback); + c->callback = callback; + c->callback_ctx = callback_ctx; + c->data = data; + c->len = len; + PostMessage(hwnd, WM_AGENT_CALLBACK, 0, (LPARAM)c); +}