#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);
return 1;
}
/* WISHLIST: maybe allow config tweaking even if winsock not present? */
+ sk_init();
InitCommonControls();
}
{
- 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);
}
/*
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);
}
/*
+ * 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, ...) {
* 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 */
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;
- case WSAECONNABORTED:
- sprintf(buf, "Connection aborted");
- 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 {
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:
/*
* 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;
#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))
}
/* 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;
}