⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 window.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 5 页
字号:
#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <time.h>#include <assert.h>#define PUTTY_DO_GLOBALS	       /* actually _define_ globals */#include "putty.h"#include "terminal.h"#include "storage.h"#include "win_res.h"#ifndef NO_MULTIMON#if WINVER < 0x0500#define COMPILE_MULTIMON_STUBS#include <multimon.h>#endif#endif#include <imm.h>#include <commctrl.h>#include <richedit.h>#include <mmsystem.h>#define IDM_SHOWLOG   0x0010#define IDM_NEWSESS   0x0020#define IDM_DUPSESS   0x0030#define IDM_RESTART   0x0040#define IDM_RECONF    0x0050#define IDM_CLRSB     0x0060#define IDM_RESET     0x0070#define IDM_HELP      0x0140#define IDM_ABOUT     0x0150#define IDM_SAVEDSESS 0x0160#define IDM_COPYALL   0x0170#define IDM_FULLSCREEN	0x0180#define IDM_PASTE     0x0190#define IDM_SESSLGP   0x0250	       /* log type printable */#define IDM_SESSLGA   0x0260	       /* log type all chars */#define IDM_SESSLGE   0x0270	       /* log end */#define IDM_SPECIAL_MIN 0x0400#define IDM_SPECIAL_MAX 0x0800#define IDM_SAVED_MIN 0x1000#define IDM_SAVED_MAX 0x2000#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#define VK_PROCESSKEY 0xE5#endif/* Mouse wheel support. */#ifndef WM_MOUSEWHEEL#define WM_MOUSEWHEEL 0x020A	       /* not defined in earlier SDKs */#endif#ifndef WHEEL_DELTA#define WHEEL_DELTA 120#endifstatic Mouse_Button translate_button(Mouse_Button button);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);static void deinit_fonts(void);static void set_input_locale(HKL);static int is_full_screen(void);static void make_full_screen(void);static void clear_full_screen(void);static void flip_full_screen(void);/* Window layout information */static void reset_window(int);static int extra_width, extra_height;static int font_width, font_height, font_dualwidth;static int offset_width, offset_height;static int was_zoomed = 0;static int prev_rows, prev_cols;  static int pending_netevent = 0;static WPARAM pend_netevent_wParam = 0;static LPARAM pend_netevent_lParam = 0;static void enact_pending_netevent(void);static void flash_window(int mode);static void sys_cursor_update(void);static int is_shift_pressed(void);static int get_fullscreen_rect(RECT * ss);static time_t last_movement = 0;static int caret_x = -1, caret_y = -1;static int kbd_codepage;static void *ldisc;static const Backend *back;static void *backhandle;static struct unicode_data ucsdata;static int session_closed;static const struct telnet_special *specials;static int n_specials;static struct {    HMENU menu;    int specials_submenu_pos;} popup_menus[2];enum { SYSMENU, CTXMENU };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#define FONT_BOLDUND 3#define FONT_WIDE	0x04#define FONT_HIGH	0x08#define FONT_NARROW	0x10#define FONT_OEM 	0x20#define FONT_OEMBOLD 	0x21#define FONT_OEMUND 	0x22#define FONT_OEMBOLDUND 0x23#define FONT_MAXNO 	0x2F#define FONT_SHIFT	5static HFONT fonts[FONT_MAXNO];static LOGFONT lfont;static int fontflag[FONT_MAXNO];static enum {    BOLD_COLOURS, BOLD_SHADOW, BOLD_FONT} bold_mode;static enum {    UND_LINE, UND_FONT} und_mode;static int descent;#define NCOLOURS 24static COLORREF colours[NCOLOURS];static HPALETTE pal;static LPLOGPALETTE logpal;static RGBTRIPLE defpal[NCOLOURS];static HWND hwnd;static HBITMAP caretbm;static int dbltime, lasttime, lastact;static Mouse_Button lastbtn;/* this allows xterm-style mouse handling. */static int send_raw_mouse = 0;static int wheel_accumulator = 0;static char *window_name, *icon_name;static int compose_state = 0;static UINT wm_mousewheel = WM_MOUSEWHEEL;/* Dummy routine, only required in plink. */void ldisc_update(void *frontend, int echo, int edit){}static void start_backend(void){    const char *error;    char msg[1024], *title;    char *realhost;    int i;    /*     * Select protocol. This is farmed out into a table in a     * separate file to enable an ssh-free variant.     */    back = NULL;    for (i = 0; backends[i].backend != NULL; i++)	if (backends[i].protocol == cfg.protocol) {	    back = backends[i].backend;	    break;	}    if (back == NULL) {	char *str = dupprintf("%s Internal Error", appname);	MessageBox(NULL, "Unsupported protocol number found",		   str, MB_OK | MB_ICONEXCLAMATION);	sfree(str);	cleanup_exit(1);    }    error = back->init(NULL, &backhandle, &cfg,		       cfg.host, cfg.port, &realhost, cfg.tcp_nodelay,		       cfg.tcp_keepalives);    back->provide_logctx(backhandle, logctx);    if (error) {	char *str = dupprintf("%s Error", appname);	sprintf(msg, "Unable to open connection to\n"		"%.800s\n" "%s", cfg.host, error);	MessageBox(NULL, msg, str, MB_ICONERROR | MB_OK);	sfree(str);	exit(0);    }    window_name = icon_name = NULL;    if (*cfg.wintitle) {	title = cfg.wintitle;    } else {	sprintf(msg, "%s - %s", realhost, appname);	title = msg;    }    sfree(realhost);    set_title(NULL, title);    set_icon(NULL, title);    /*     * Connect the terminal to the backend for resize purposes.     */    term_provide_resize_fn(term, back->size, backhandle);    /*     * Set up a line discipline.     */    ldisc = ldisc_create(&cfg, term, back, backhandle, NULL);    /*     * Destroy the Restart Session menu item. (This will return     * failure if it's already absent, as it will be the very first     * time we call this function. We ignore that, because as long     * as the menu item ends up not being there, we don't care     * whether it was us who removed it or not!)     */    for (i = 0; i < lenof(popup_menus); i++) {	DeleteMenu(popup_menus[i].menu, IDM_RESTART, MF_BYCOMMAND);    }    session_closed = FALSE;}static void close_session(void){    char morestuff[100];    int i;    session_closed = TRUE;    sprintf(morestuff, "%.70s (inactive)", appname);    set_icon(NULL, morestuff);    set_title(NULL, morestuff);    if (ldisc) {	ldisc_free(ldisc);	ldisc = NULL;    }    if (back) {	back->free(backhandle);	backhandle = NULL;	back = NULL;	update_specials_menu(NULL);    }    /*     * Show the Restart Session menu item. Do a precautionary     * delete first to ensure we never end up with more than one.     */    for (i = 0; i < lenof(popup_menus); i++) {	DeleteMenu(popup_menus[i].menu, IDM_RESTART, MF_BYCOMMAND);	InsertMenu(popup_menus[i].menu, IDM_DUPSESS, MF_BYCOMMAND | MF_ENABLED,		   IDM_RESTART, "&Restart Session");    }}int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show){    WNDCLASS wndclass;    MSG msg;    int guess_width, guess_height;    hinst = inst;    statics()->flags = FLAG_VERBOSE | FLAG_INTERACTIVE;    sk_init();    InitCommonControls();    /* Ensure a Maximize setting in Explorer doesn't maximise the     * config box. */    defuse_showwindow();    if (!init_winver())    {	char *str = dupprintf("%s Fatal Error", appname);	MessageBox(NULL, "Windows refuses to report a version",		   str, MB_OK | MB_ICONEXCLAMATION);	sfree(str);	return 1;    }    /*     * If we're running a version of Windows that doesn't support     * WM_MOUSEWHEEL, find out what message number we should be     * using instead.     */    if (osVersion.dwMajorVersion < 4 ||	(osVersion.dwMajorVersion == 4 && 	 osVersion.dwPlatformId != VER_PLATFORM_WIN32_NT))	wm_mousewheel = RegisterWindowMessage("MSWHEEL_ROLLMSG");    /*     * See if we can find our Help file.     */    {        char b[2048], *p, *q, *r;        FILE *fp;        GetModuleFileName(NULL, b, sizeof(b) - 1);        r = b;        p = strrchr(b, '\\');        if (p && p >= r) r = p+1;        q = strrchr(b, ':');        if (q && q >= r) r = q+1;        strcpy(r, "putty.hlp");        if ( (fp = fopen(b, "r")) != NULL) {            help_path = dupstr(b);            fclose(fp);        } else            help_path = NULL;        strcpy(r, "putty.cnt");        if ( (fp = fopen(b, "r")) != NULL) {            help_has_contents = TRUE;            fclose(fp);        } else            help_has_contents = FALSE;    }    /*     * Process the command line.     */    {	char *p;	int got_host = 0;	statics()->default_protocol = be_default_protocol;	/* Find the appropriate default port. */	{	    int i;	    statics()->default_port = 0; /* illegal */	    for (i = 0; backends[i].backend != NULL; i++)		if (backends[i].protocol == statics()->default_protocol) {		    statics()->default_port =                        backends[i].backend->default_port;		    break;		}	}	cfg.logtype = LGTYP_NONE;	do_defaults(NULL, &cfg);	p = cmdline;	/*	 * Process a couple of command-line options which are more	 * easily dealt with before the line is broken up into	 * words. These are the soon-to-be-defunct @sessionname and	 * the internal-use-only &sharedmemoryhandle, neither of	 * which are combined with anything else.	 */	while (*p && isspace(*p))	    p++;	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()) {		cleanup_exit(0);	    }	} else if (*p == '&') {	    /*	     * An initial & means we've been given a command line	     * containing the hex value of a HANDLE for a file	     * mapping object, which we must then extract as a	     * config.	     */	    HANDLE filemap;	    Config *cp;	    if (sscanf(p + 1, "%p", &filemap) == 1 &&		(cp = MapViewOfFile(filemap, FILE_MAP_READ,				    0, 0, sizeof(Config))) != NULL) {		cfg = *cp;		UnmapViewOfFile(cp);		CloseHandle(filemap);	    } else if (!do_config()) {		cleanup_exit(0);	    }	} else {	    /*	     * Otherwise, break up the command line and deal with	     * it sensibly.	     */	    int argc, i;	    char **argv;	    	    split_into_argv(cmdline, &argc, &argv, NULL);	    for (i = 0; i < argc; i++) {		char *p = argv[i];		int ret;		ret = cmdline_process_param(p, i+1<argc?argv[i+1]:NULL,					    1, &cfg);		if (ret == -2) {		    cmdline_error("option \"%s\" requires an argument", p);		} else if (ret == 2) {		    i++;	       /* skip next argument */		} else if (ret == 1) {		    continue;	       /* nothing further needs doing */		} else if (!strcmp(p, "-cleanup")) {		    /*		     * `putty -cleanup'. Remove all registry		     * entries associated with PuTTY, and also find		     * and delete the random seed file.		     */		    char *s1, *s2;		    s1 = dupprintf("This procedure will remove ALL Registry\n"				   "entries associated with %s, and will\n"				   "also remove the random seed file.\n"				   "\n"				   "THIS PROCESS WILL DESTROY YOUR SAVED\n"				   "SESSIONS. Are you really sure you want\n"				   "to continue?", appname);		    s2 = dupprintf("%s Warning", appname);		    if (MessageBox(NULL, s1, s2,				   MB_YESNO | MB_ICONWARNING) == IDYES) {			cleanup_all();		    }		    sfree(s1);		    sfree(s2);		    exit(0);		} else if (*p != '-') {		    char *q = p;		    if (got_host) {			/*			 * If we already have a host name, treat			 * this argument as a port number. NB we			 * have to treat this as a saved -P			 * argument, so that it will be deferred			 * until it's a good moment to run it.			 */			int ret = cmdline_process_param("-P", p, 1, &cfg);			assert(ret == 2);		    } else if (!strncmp(q, "telnet:", 7)) {			/*			 * If the hostname starts with "telnet:",			 * set the protocol to Telnet and process			 * the string as a Telnet URL.			 */			char c;			q += 7;			if (q[0] == '/' && q[1] == '/')			    q += 2;			cfg.protocol = PROT_TELNET;			p = q;			while (*p && *p != ':' && *p != '/')			    p++;			c = *p;			if (*p)			    *p++ = '\0';			if (c == ':')			    cfg.port = atoi(p);			else			    cfg.port = -1;			strncpy(cfg.host, q, sizeof(cfg.host) - 1);			cfg.host[sizeof(cfg.host) - 1] = '\0';			got_host = 1;		    } else {			/*			 * Otherwise, treat this argument as a host

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -