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

📄 window.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			 * name.			 */			while (*p && !isspace(*p))			    p++;			if (*p)			    *p++ = '\0';			strncpy(cfg.host, q, sizeof(cfg.host) - 1);			cfg.host[sizeof(cfg.host) - 1] = '\0';			got_host = 1;		    }		} else {		    cmdline_error("unknown option \"%s\"", p);		}	    }	}	cmdline_run_saved(&cfg);	if (!*cfg.host && !do_config()) {	    cleanup_exit(0);	}	/*	 * Trim leading whitespace off the hostname if it's there.	 */	{	    int space = strspn(cfg.host, " \t");	    memmove(cfg.host, cfg.host+space, 1+strlen(cfg.host)-space);	}	/* See if host is of the form user@host */	if (cfg.host[0] != '\0') {	    char *atsign = strrchr(cfg.host, '@');	    /* Make sure we're not overflowing the user field */	    if (atsign) {		if (atsign - cfg.host < sizeof cfg.username) {		    strncpy(cfg.username, cfg.host, atsign - cfg.host);		    cfg.username[atsign - cfg.host] = '\0';		}		memmove(cfg.host, atsign + 1, 1 + strlen(atsign + 1));	    }	}	/*	 * Trim a colon suffix off the hostname if it's there.	 */	cfg.host[strcspn(cfg.host, ":")] = '\0';	/*	 * Remove any remaining whitespace from the hostname.	 */	{	    int p1 = 0, p2 = 0;	    while (cfg.host[p2] != '\0') {		if (cfg.host[p2] != ' ' && cfg.host[p2] != '\t') {		    cfg.host[p1] = cfg.host[p2];		    p1++;		}		p2++;	    }	    cfg.host[p1] = '\0';	}    }    /* Check for invalid Port number (i.e. zero) */    if (cfg.port == 0) {	char *str = dupprintf("%s Internal Error", appname);	MessageBox(NULL, "Invalid Port Number",		   str, MB_OK | MB_ICONEXCLAMATION);	sfree(str);	cleanup_exit(1);    }    if (!prev) {	wndclass.style = 0;	wndclass.lpfnWndProc = WndProc;	wndclass.cbClsExtra = 0;	wndclass.cbWndExtra = 0;	wndclass.hInstance = inst;	wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON));	wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM);	wndclass.hbrBackground = NULL;	wndclass.lpszMenuName = NULL;	wndclass.lpszClassName = appname;	RegisterClass(&wndclass);    }    hwnd = NULL;    memset(&ucsdata, 0, sizeof(ucsdata));    term = term_init(&cfg, &ucsdata, NULL);    logctx = log_init(NULL, &cfg);    term_provide_logctx(term, logctx);    cfgtopalette();    /*     * Guess some defaults for the window size. This all gets     * updated later, so we don't really care too much. However, we     * do want the font width/height guesses to correspond to a     * large font rather than a small one...     */    font_width = 10;    font_height = 20;    extra_width = 25;    extra_height = 28;    term_size(term, cfg.height, cfg.width, cfg.savelines);    guess_width = extra_width + font_width * term->cols;    guess_height = extra_height + font_height * term->rows;    {	RECT r;		get_fullscreen_rect(&r);	if (guess_width > r.right - r.left)	    guess_width = r.right - r.left;	if (guess_height > r.bottom - r.top)	    guess_height = r.bottom - r.top;    }    {	int winmode = WS_OVERLAPPEDWINDOW | WS_VSCROLL;	int exwinmode = 0;	if (!cfg.scrollbar)	    winmode &= ~(WS_VSCROLL);	if (cfg.resize_action == RESIZE_DISABLED)	    winmode &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX);	if (cfg.alwaysontop)	    exwinmode |= WS_EX_TOPMOST;	if (cfg.sunken_edge)	    exwinmode |= WS_EX_CLIENTEDGE;	hwnd = CreateWindowEx(exwinmode, appname, appname,			      winmode, CW_USEDEFAULT, CW_USEDEFAULT,			      guess_width, guess_height,			      NULL, NULL, inst, NULL);    }    /*     * Initialise the fonts, simultaneously correcting the guesses     * for font_{width,height}.     */    init_fonts(0,0);    /*     * Correct the guesses for extra_{width,height}.     */    {	RECT cr, wr;	GetWindowRect(hwnd, &wr);	GetClientRect(hwnd, &cr);	offset_width = offset_height = cfg.window_border;	extra_width = wr.right - wr.left - cr.right + cr.left + offset_width*2;	extra_height = wr.bottom - wr.top - cr.bottom + cr.top +offset_height*2;    }    /*     * Resize the window, now we know what size we _really_ want it     * to be.     */    guess_width = extra_width + font_width * term->cols;    guess_height = extra_height + font_height * term->rows;    SetWindowPos(hwnd, NULL, 0, 0, guess_width, guess_height,		 SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER);    /*     * Set up a caret bitmap, with no content.     */    {	char *bits;	int size = (font_width + 15) / 16 * 2 * font_height;	bits = snewn(size, char);	memset(bits, 0, size);	caretbm = CreateBitmap(font_width, font_height, 1, 1, bits);	sfree(bits);    }    CreateCaret(hwnd, caretbm, font_width, font_height);    /*     * Initialise the scroll bar.     */    {	SCROLLINFO si;	si.cbSize = sizeof(si);	si.fMask = SIF_ALL | SIF_DISABLENOSCROLL;	si.nMin = 0;	si.nMax = term->rows - 1;	si.nPage = term->rows;	si.nPos = 0;	SetScrollInfo(hwnd, SB_VERT, &si, FALSE);    }    /*     * Prepare the mouse handler.     */    lastact = MA_NOTHING;    lastbtn = MBT_NOTHING;    dbltime = GetDoubleClickTime();    /*     * Set up the session-control options on the system menu.     */    {	HMENU s, m;	int i, j;	char *str;	popup_menus[SYSMENU].menu = GetSystemMenu(hwnd, FALSE);	popup_menus[CTXMENU].menu = CreatePopupMenu();	AppendMenu(popup_menus[CTXMENU].menu, MF_ENABLED, IDM_PASTE, "&Paste");	s = CreateMenu();	get_sesslist(&sesslist, TRUE);	for (i = 1;	     i < ((sesslist.nsessions < 256) ? sesslist.nsessions : 256);	     i++)	    AppendMenu(s, MF_ENABLED, IDM_SAVED_MIN + (16 * i),		       sesslist.sessions[i]);	for (j = 0; j < lenof(popup_menus); j++) {	    m = popup_menus[j].menu;	    AppendMenu(m, MF_SEPARATOR, 0, 0);	    popup_menus[j].specials_submenu_pos = GetMenuItemCount(m);	    AppendMenu(m, MF_ENABLED, IDM_SHOWLOG, "&Event Log");	    AppendMenu(m, MF_SEPARATOR, 0, 0);	    AppendMenu(m, MF_ENABLED, IDM_NEWSESS, "Ne&w Session...");	    AppendMenu(m, MF_ENABLED, IDM_DUPSESS, "&Duplicate Session");	    AppendMenu(m, MF_POPUP | MF_ENABLED, (UINT) s, "Sa&ved Sessions");	    AppendMenu(m, MF_ENABLED, IDM_RECONF, "Chan&ge Settings...");	    AppendMenu(m, MF_SEPARATOR, 0, 0);	    AppendMenu(m, MF_ENABLED, IDM_COPYALL, "C&opy All to Clipboard");	    AppendMenu(m, MF_ENABLED, IDM_CLRSB, "C&lear Scrollback");	    AppendMenu(m, MF_ENABLED, IDM_RESET, "Rese&t Terminal");	    AppendMenu(m, MF_SEPARATOR, 0, 0);	    AppendMenu(m, (cfg.resize_action == RESIZE_DISABLED) ?		       MF_GRAYED : MF_ENABLED, IDM_FULLSCREEN, "&Full Screen");	    AppendMenu(m, MF_SEPARATOR, 0, 0);	    if (help_path)		AppendMenu(m, MF_ENABLED, IDM_HELP, "&Help");	    str = dupprintf("&About %s", appname);	    AppendMenu(m, MF_ENABLED, IDM_ABOUT, str);	    sfree(str);	}    }    start_backend();    /*     * Set up the initial input locale.     */    set_input_locale(GetKeyboardLayout(0));    /*     * Open the initial log file if there is one.     */    logfopen(logctx);    /*     * Finally show the window!     */    ShowWindow(hwnd, show);    SetForegroundWindow(hwnd);    /*     * Set the palette up.     */    pal = NULL;    logpal = NULL;    init_palette();    term->has_focus = (GetForegroundWindow() == hwnd);    UpdateWindow(hwnd);    if (GetMessage(&msg, NULL, 0, 0) == 1) {	int timer_id = 0, long_timer = 0;	while (msg.message != WM_QUIT) {	    /* Sometimes DispatchMessage calls routines that use their own	     * GetMessage loop, setup this timer so we get some control back.	     *	     * Also call term_update() from the timer so that if the host	     * is sending data flat out we still do redraws.	     */	    if (timer_id && long_timer) {		KillTimer(hwnd, timer_id);		long_timer = timer_id = 0;	    }	    if (!timer_id)		timer_id = SetTimer(hwnd, 1, 20, NULL);	    if (!(IsWindow(logbox) && IsDialogMessage(logbox, &msg)))		DispatchMessage(&msg);	    /* Make sure we blink everything that needs it. */	    term_blink(term, 0);	    /* Send the paste buffer if there's anything to send */	    term_paste(term);	    /* If there's nothing new in the queue then we can do everything	     * we've delayed, reading the socket, writing, and repainting	     * the window.	     */	    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))		continue;	    if (pending_netevent) {		enact_pending_netevent();		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))		    continue;	    }	    /* Okay there is now nothing to do so we make sure the screen is	     * completely up to date then tell windows to call us in a little 	     * while.	     */	    if (timer_id) {		KillTimer(hwnd, timer_id);		timer_id = 0;	    }	    HideCaret(hwnd);	    if (GetCapture() != hwnd || 		(send_raw_mouse &&		 !(cfg.mouse_override && is_shift_pressed())))		term_out(term);	    term_update(term);	    ShowCaret(hwnd);	    flash_window(1);	       /* maintain */	    /* The messages seem unreliable; especially if we're being tricky */	    term->has_focus = (GetForegroundWindow() == hwnd);	    if (term->in_vbell)		/* Hmm, term_update didn't want to do an update too soon ... */		timer_id = SetTimer(hwnd, 1, 50, NULL);	    else if (!term->has_focus)		timer_id = SetTimer(hwnd, 1, 500, NULL);	    else		timer_id = SetTimer(hwnd, 1, 100, NULL);	    long_timer = 1;	    /* There's no point rescanning everything in the message queue	     * so we do an apparently unnecessary wait here	     */	    WaitMessage();	    if (GetMessage(&msg, NULL, 0, 0) != 1)		break;	}    }    cleanup_exit(msg.wParam);	       /* this doesn't return... */    return msg.wParam;		       /* ... but optimiser doesn't know */}/* * Clean up and exit. */void cleanup_exit(int code){    /*     * Clean up.     */    deinit_fonts();    sfree(logpal);    if (pal)	DeleteObject(pal);    sk_cleanup();    if (cfg.protocol == PROT_SSH) {	random_save_seed();#ifdef MSCRYPTOAPI	crypto_wrapup();#endif    }    exit(code);}/* * 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_CONNECT | FD_READ | FD_WRITE |		  FD_OOB | FD_CLOSE | FD_ACCEPT);    } else {	msg = events = 0;    }    if (!hwnd)	return "do_select(): internal error (hwnd==NULL)";    if (p_WSAAsyncSelect(skt, hwnd, msg, events) == SOCKET_ERROR) {	switch (p_WSAGetLastError()) {	  case WSAENETDOWN:	    return "Network is down";	  default:	    return "WSAAsyncSelect(): unknown error";	}    }    return NULL;}/* * Update the Special Commands submenu. */void update_specials_menu(void *frontend){    HMENU p;    int menu_already_exists = (specials != NULL);    int i, j;    if (back)	specials = back->get_specials(backhandle);    else	specials = NULL;    if (specials) {	/* We can't use Windows to provide a stack for submenus, so	 * here's a lame "stack" that will do for now. */	HMENU saved_menu = NULL;	int nesting = 1;	p = CreatePopupMenu();	for (i = 0; nesting > 0; i++) {	    assert(IDM_SPECIAL_MIN + 0x10 * i < IDM_SPECIAL_MAX);	    switch (specials[i].code) {	      case TS_SEP:		AppendMenu(p, MF_SEPARATOR, 0, 0);		break;	      case TS_SUBMENU:		assert(nesting < 2);		nesting++;		saved_menu = p; /* XXX lame stacking */		p = CreatePopupMenu();		AppendMenu(saved_menu, MF_POPUP | MF_ENABLED,			   (UINT) p, specials[i].name);		break;	      case TS_EXITMENU:		nesting--;		if (nesting) {		    p = saved_menu; /* XXX lame stacking */		    saved_menu = NULL;		}		break;	      default:		AppendMenu(p, MF_ENABLED, IDM_SPECIAL_MIN + 0x10 * i,			   specials[i].name);		break;	    }	}	/* Squirrel the highest special. */	n_specials = i - 1;    } else {	p = NULL;	n_specials = 0;    }    for (j = 0; j < lenof(popup_menus); j++) {	if (menu_already_exists) {	    /* XXX does this free up all submenus? */	    DeleteMenu(popup_menus[j].menu,		       popup_menus[j].specials_submenu_pos,		       MF_BYPOSITION);	    DeleteMenu(popup_menus[j].menu,		       popup_menus[j].specials_submenu_pos,		       MF_BYPOSITION);	}	if (specials) {	    InsertMenu(popup_menus[j].menu,		       popup_menus[j].specials_submenu_pos,		       MF_BYPOSITION | MF_SEPARATOR, 0, 0);	    InsertMenu(popup_menus[j].menu,		       popup_menus[j].specials_submenu_pos,		       MF_BYPOSITION | MF_POPUP | MF_ENABLED,		       (UINT) p, "S&pecial Command");	}    }}/* * set or clear the "raw mouse message" mode */void set_raw_mouse_mode(void *frontend, int activate){    activate = activate && !cfg.no_mouse_rep;    send_raw_mouse = activate;    SetCursor(LoadCursor(NULL, activate ? IDC_ARROW : IDC_IBEAM));}/* * Print a message box and close the connection. */void connection_fatal(void *frontend, char *fmt, ...)

⌨️ 快捷键说明

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