X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/ec55b2200b3a40631648cfa02ed63207b58832fe..8df7a775f6f8b0f81f84eafe28cd0bb8d4c6d1f4:/window.c diff --git a/window.c b/window.c index 822cb01e..1e38a487 100644 --- a/window.c +++ b/window.c @@ -14,6 +14,7 @@ #define PUTTY_DO_GLOBALS /* actually _define_ globals */ #include "putty.h" +#include "winstuff.h" #include "storage.h" #include "win_res.h" @@ -45,6 +46,11 @@ #define WM_IGNORE_SIZE (WM_XUSER + 1) #define WM_IGNORE_CLIP (WM_XUSER + 2) +/* Needed for Chinese support and apparently not always defined. */ +#ifndef VK_PROCESSKEY +#define VK_PROCESSKEY 0xE5 +#endif + static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned char *output); static void cfgtopalette(void); @@ -107,7 +113,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { MSG msg; int guess_width, guess_height; - putty_inst = inst; + hinst = inst; flags = FLAG_VERBOSE | FLAG_INTERACTIVE; winsock_ver = MAKEWORD(1, 1); @@ -123,9 +129,14 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { return 1; } /* WISHLIST: maybe allow config tweaking even if winsock not present? */ + sk_init(); InitCommonControls(); + /* Ensure a Maximize setting in Explorer doesn't maximise the + * config box. */ + defuse_showwindow(); + /* * Process the command line. */ @@ -193,6 +204,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { * An initial @ means to activate a saved session. */ if (*p == '@') { + int i = strlen(p); + while (i > 1 && isspace(p[i-1])) + i--; + p[i] = '\0'; do_defaults (p+1, &cfg); if (!*cfg.host && !do_config()) { WSACleanup(); @@ -348,14 +363,14 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { } { - int winmode = WS_OVERLAPPEDWINDOW|WS_VSCROLL; - if (!cfg.scrollbar) winmode &= ~(WS_VSCROLL); - if (cfg.locksize) winmode &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX); - hwnd = CreateWindow (appname, appname, - winmode, - CW_USEDEFAULT, CW_USEDEFAULT, - guess_width, guess_height, - NULL, NULL, inst, NULL); + int winmode = WS_OVERLAPPEDWINDOW|WS_VSCROLL; + if (!cfg.scrollbar) winmode &= ~(WS_VSCROLL); + if (cfg.locksize) winmode &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX); + hwnd = CreateWindow (appname, appname, + winmode, + CW_USEDEFAULT, CW_USEDEFAULT, + guess_width, guess_height, + NULL, NULL, inst, NULL); } /* @@ -421,7 +436,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { char msg[1024], *title; char *realhost; - error = back->init (hwnd, cfg.host, cfg.port, &realhost); + error = back->init (cfg.host, cfg.port, &realhost); if (error) { sprintf(msg, "Unable to open connection:\n%s", error); MessageBox(NULL, msg, "PuTTY Error", MB_ICONERROR | MB_OK); @@ -610,6 +625,28 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { } /* + * Set up, or shut down, an AsyncSelect. Called from winnet.c. + */ +char *do_select(SOCKET skt, int startup) { + int msg, events; + if (startup) { + msg = WM_NETEVENT; + events = FD_READ | FD_WRITE | FD_OOB | FD_CLOSE; + } else { + msg = events = 0; + } + if (!hwnd) + return "do_select(): internal error (hwnd==NULL)"; + if (WSAAsyncSelect (skt, hwnd, msg, events) == SOCKET_ERROR) { + switch (WSAGetLastError()) { + case WSAENETDOWN: return "Network is down"; + default: return "WSAAsyncSelect(): unknown error"; + } + } + return NULL; +} + +/* * Print a message box and close the connection. */ void connection_fatal(char *fmt, ...) { @@ -632,8 +669,9 @@ void connection_fatal(char *fmt, ...) { * Actually do the job requested by a WM_NETEVENT */ static void enact_pending_netevent(void) { - int i; static int reentering = 0; + extern int select_result(WPARAM, LPARAM); + int ret; if (reentering) return; /* don't unpend the pending */ @@ -641,22 +679,10 @@ static void enact_pending_netevent(void) { pending_netevent = FALSE; reentering = 1; - i = back->msg (pend_netevent_wParam, pend_netevent_lParam); + ret = select_result (pend_netevent_wParam, pend_netevent_lParam); reentering = 0; - if (i < 0) { - char buf[1024]; - switch (WSABASEERR + (-i) % 10000) { - case WSAECONNRESET: - sprintf(buf, "Connection reset by peer"); - break; - default: - sprintf(buf, "Unexpected network error %d", -i); - break; - } - connection_fatal(buf); - } - if (i <= 0) { + if (ret == 0) { if (cfg.close_on_exit) PostQuitMessage(0); else { @@ -1476,12 +1502,29 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, unsigned char buf[20]; int len; - len = TranslateKey (message, wParam, lParam, buf); - if (len == -1) - return DefWindowProc (hwnd, message, wParam, lParam); - ldisc->send (buf, len); + if (wParam==VK_PROCESSKEY) { + MSG m; + m.hwnd = hwnd; + m.message = WM_KEYDOWN; + m.wParam = wParam; + m.lParam = lParam & 0xdfff; + TranslateMessage(&m); + } else { + len = TranslateKey (message, wParam, lParam, buf); + if (len == -1) + return DefWindowProc (hwnd, message, wParam, lParam); + ldisc->send (buf, len); + } } return 0; + case WM_IME_CHAR: + { + unsigned char buf[2]; + + buf[1] = wParam; + buf[0] = wParam >> 8; + ldisc->send (buf, 2); + } case WM_CHAR: case WM_SYSCHAR: /* @@ -1736,15 +1779,6 @@ static int check_compose(int first, int second) { static int recurse = 0; int nc = -1; - if(0) - { - char buf[256]; - char * p; - sprintf(buf, "cc(%d,%d)", first, second); - for(p=buf; *p; p++) - c_write1(*p); - } - for(c=composetbl; *c; c++) { if( (*c)[0] == first && (*c)[1] == second) { @@ -1771,7 +1805,8 @@ static int check_compose(int first, int second) { * codes. Returns number of bytes used or zero to drop the message * or -1 to forward the message to windows. */ -static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned char *output) { +static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, + unsigned char *output) { BYTE keystate[256]; int scan, left_alt = 0, key_down, shift_state; int r, i, code; @@ -1844,25 +1879,28 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned cha #endif /* Note if AltGr was pressed and if it was used as a compose key */ - if (wParam == VK_MENU && (HIWORD(lParam)&KF_EXTENDED)) - { - keystate[VK_RMENU] = keystate[VK_MENU]; - if (!compose_state) compose_key = wParam; - } - if (wParam == VK_APPS && !compose_state) - compose_key = wParam; + if (cfg.compose_key) { + if (wParam == VK_MENU && (HIWORD(lParam)&KF_EXTENDED)) + { + keystate[VK_RMENU] = keystate[VK_MENU]; + if (!compose_state) compose_key = wParam; + } + if (wParam == VK_APPS && !compose_state) + compose_key = wParam; - if (wParam == compose_key) - { - if (compose_state == 0 && (HIWORD(lParam)&(KF_UP|KF_REPEAT))==0) - compose_state = 1; - else if (compose_state == 1 && (HIWORD(lParam)&KF_UP)) - compose_state = 2; - else - compose_state = 0; - } - else if (compose_state==1 && wParam != VK_CONTROL) - compose_state = 0; + if (wParam == compose_key) + { + if (compose_state == 0 && (HIWORD(lParam)&(KF_UP|KF_REPEAT))==0) + compose_state = 1; + else if (compose_state == 1 && (HIWORD(lParam)&KF_UP)) + compose_state = 2; + else + compose_state = 0; + } + else if (compose_state==1 && wParam != VK_CONTROL) + compose_state = 0; + } else + compose_state = 0; /* Nastyness with NUMLock - Shift-NUMLock is left alone though */ if ( (cfg.funky_type == 3 || (cfg.funky_type <= 1 && app_keypad_keys)) @@ -2207,7 +2245,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned cha if ((nc=check_compose(compose_char,ch)) == -1) { - c_write1('\007'); + MessageBeep(MB_ICONHAND); return 0; } *p++ = xlat_kbd2tty((unsigned char)nc); @@ -2235,8 +2273,10 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned cha } /* This stops ALT press-release doing a 'COMMAND MENU' function */ - if (message == WM_SYSKEYUP && wParam == VK_MENU) - return 0; + if (!cfg.alt_only) { + if (message == WM_SYSKEYUP && wParam == VK_MENU) + return 0; + } return -1; }