📄 www.c
字号:
/* * Copyright (c) 2002, Adam Dunkels. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgement: * This product includes software developed by Adam Dunkels. * 4. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This file is part of the Contiki desktop environment * * $Id: www.c,v 1.21 2003/09/04 19:35:32 adamdunkels Exp $ * */#include "ctk.h"#include "dispatcher.h"#include "webclient.h"#include "htmlparser.h"#include "http-strings.h"#include "resolv.h"#include "petsciiconv.h"#include "program-handler.h"#include "loader.h"#include "www-conf.h"#if 1#define PRINTF(x)#else#include <stdio.h>#define PRINTF(x) printf x#endif/* The array that holds the current URL. */static char url[WWW_CONF_MAX_URLLEN + 1];static char tmpurl[WWW_CONF_MAX_URLLEN + 1];/* The array that holds the web page text. */static char webpage[WWW_CONF_WEBPAGE_WIDTH * WWW_CONF_WEBPAGE_HEIGHT + 1];/* The CTK widgets for the main window. */static struct ctk_window mainwindow;static struct ctk_button backbutton = {CTK_BUTTON(0, 0, 4, "Back")};static struct ctk_button downbutton = {CTK_BUTTON(10, 0, 4, "Down")};static struct ctk_button stopbutton = {CTK_BUTTON(WWW_CONF_WEBPAGE_WIDTH - 16, 0, 4, "Stop")};static struct ctk_button gobutton = {CTK_BUTTON(WWW_CONF_WEBPAGE_WIDTH - 4, 0, 2, "Go")};static struct ctk_separator sep1 = {CTK_SEPARATOR(0, 2, WWW_CONF_WEBPAGE_WIDTH)};static char editurl[WWW_CONF_MAX_URLLEN + 1];static struct ctk_textentry urlentry = {CTK_TEXTENTRY(0, 1, WWW_CONF_WEBPAGE_WIDTH - 2, 1, editurl, WWW_CONF_MAX_URLLEN)};static struct ctk_label webpagelabel = {CTK_LABEL(0, 3, WWW_CONF_WEBPAGE_WIDTH, WWW_CONF_WEBPAGE_HEIGHT, webpage)};static char statustexturl[WWW_CONF_WEBPAGE_WIDTH];static struct ctk_label statustext = {CTK_LABEL(0, WWW_CONF_WEBPAGE_HEIGHT + 4, WWW_CONF_WEBPAGE_WIDTH, 1, "")};static struct ctk_separator sep2 = {CTK_SEPARATOR(0, WWW_CONF_WEBPAGE_HEIGHT + 3, WWW_CONF_WEBPAGE_WIDTH)};static struct ctk_window wgetdialog;static struct ctk_label wgetlabel1 = {CTK_LABEL(1, 1, 34, 1, "This web page cannot be displayed.")};static struct ctk_label wgetlabel2 = {CTK_LABEL(1, 3, 35, 1, "Would you like to download instead?")};static struct ctk_button wgetnobutton = {CTK_BUTTON(1, 5, 6, "Cancel")};static struct ctk_button wgetyesbutton = {CTK_BUTTON(11, 5, 24, "Close browser & download")};/* The char arrays that hold the history of visited URLs. */static char history[WWW_CONF_HISTORY_SIZE][WWW_CONF_MAX_URLLEN];static char history_last, history_first;/* The CTK widget definitions for the hyperlinks and the char arrays that hold the link URLs. */struct formattribs { char formaction[WWW_CONF_MAX_FORMACTIONLEN]; char formname[WWW_CONF_MAX_FORMNAMELEN];#define FORMINPUTTYPE_SUBMITBUTTON 1#define FORMINPUTTYPE_INPUTFIELD 2 unsigned char inputtype; char inputname[WWW_CONF_MAX_INPUTNAMELEN]; char *inputvalue;};union pagewidgetattrib { char url[WWW_CONF_MAX_URLLEN];#if WWW_CONF_FORMS struct formattribs form;#endif /* WWW_CONF_FORMS */};static struct ctk_widget pagewidgets[WWW_CONF_MAX_NUMPAGEWIDGETS];static union pagewidgetattrib pagewidgetattribs[WWW_CONF_MAX_NUMPAGEWIDGETS];static unsigned char pagewidgetptr;/* The "scrolly" variable holds the line number (in the web page) of the first line of text shown on screen. */static unsigned short scrolly;/* The "scrollend" variable contains the web page line number of the last line that should be shown on screen, before the download should stop. */#if WWW_CONF_PAGEVIEWstatic unsigned short scrollend;#endif /* WWW_CONF_PAGEVIEW */#if WWW_CONF_RENDERSTATEstatic unsigned char renderstate;#endif /* WWW_CONF_RENDERSTATE *//* The "run" flag is used to determine if the web page should be continuosly scrolled upward with new data coming in from below. */static unsigned char run;#define ISO_nl 0x0a#define ISO_space 0x20#define ISO_ampersand 0x26#define ISO_plus 0x2b#define ISO_slash 0x2f#define ISO_eq 0x3d#define ISO_questionmark 0x3f/* The state of the rendering code. */static u8_t x;static u16_t starty;static char nextword[WWW_CONF_WEBPAGE_WIDTH + 1];static unsigned char nextwordptr;static unsigned char count;static char receivingmsgs[4][23] = { "Receiving web page ...", "Receiving web page. ..", "Receiving web page.. .", "Receiving web page... "};static DISPATCHER_SIGHANDLER(www_sighandler, s, data);static struct dispatcher_proc p = {DISPATCHER_PROC("Web browser", NULL, www_sighandler, webclient_appcall)};static ek_id_t id;static void formsubmit(struct formattribs *attribs);/*-----------------------------------------------------------------------------------*//* make_window() * * Creates the web browser's window. */static voidmake_window(void){ CTK_WIDGET_ADD(&mainwindow, &backbutton); CTK_WIDGET_ADD(&mainwindow, &downbutton); CTK_WIDGET_ADD(&mainwindow, &stopbutton); CTK_WIDGET_ADD(&mainwindow, &gobutton); CTK_WIDGET_ADD(&mainwindow, &urlentry); CTK_WIDGET_ADD(&mainwindow, &sep1); CTK_WIDGET_ADD(&mainwindow, &webpagelabel); CTK_WIDGET_ADD(&mainwindow, &sep2); CTK_WIDGET_ADD(&mainwindow, &statustext); CTK_WIDGET_FOCUS(&mainwindow, &stopbutton); pagewidgetptr = 0;}/*-----------------------------------------------------------------------------------*//* redraw_window(): * * Convenience function that calls upon CTK to redraw the browser * window. */static voidredraw_window(void){ ctk_window_redraw(&mainwindow);}/*-----------------------------------------------------------------------------------*//* www_init(); * * Initializes and starts the web browser. Called either at startup or * to open the browser window. */LOADER_INIT_FUNC(www_init, arg){ arg_free(arg); if(id == EK_ID_NONE) { id = dispatcher_start(&p); /* Create the main window. */ memset(webpage, 0, sizeof(webpage)); ctk_window_new(&mainwindow, WWW_CONF_WEBPAGE_WIDTH, WWW_CONF_WEBPAGE_HEIGHT+5, "Web browser"); make_window();#ifdef WWW_CONF_HOMEPAGE strncpy(editurl, WWW_CONF_HOMEPAGE, sizeof(editurl));#endif /* WWW_CONF_HOMEPAGE */ CTK_WIDGET_FOCUS(&mainwindow, &urlentry); /* Create download dialog.*/ ctk_dialog_new(&wgetdialog, 38, 7); CTK_WIDGET_ADD(&wgetdialog, &wgetlabel1); CTK_WIDGET_ADD(&wgetdialog, &wgetlabel2); CTK_WIDGET_ADD(&wgetdialog, &wgetnobutton); CTK_WIDGET_ADD(&wgetdialog, &wgetyesbutton); /* Attach as a listener to a number of signals ("Button activate", "Hyperlink activate" and "Hyperlink hover", and the resolver's signal. */ dispatcher_listen(ctk_signal_window_close); dispatcher_listen(ctk_signal_widget_activate); dispatcher_listen(ctk_signal_hyperlink_activate); dispatcher_listen(ctk_signal_hyperlink_hover); dispatcher_listen(resolv_signal_found); } ctk_window_open(&mainwindow);}/*-----------------------------------------------------------------------------------*/static voidclear_page(void){ /* if(ctk_window_isopen(&mainwindow)) { ctk_window_close(&mainwindow); }*/ ctk_window_clear(&mainwindow); make_window(); /* ctk_window_open(&mainwindow);*/ ctk_window_redraw(&mainwindow); memset(webpage, 0, WWW_CONF_WEBPAGE_WIDTH * WWW_CONF_WEBPAGE_HEIGHT); }/*-----------------------------------------------------------------------------------*/static voidshow_url(void){ memcpy(editurl, url, WWW_CONF_MAX_URLLEN); strncpy(editurl, "http://", 7); petsciiconv_topetscii(editurl + 7, WWW_CONF_MAX_URLLEN - 7); CTK_WIDGET_REDRAW(&urlentry);}/*-----------------------------------------------------------------------------------*/static voidshow_statustext(char *text){ ctk_label_set_text(&statustext, text); CTK_WIDGET_REDRAW(&statustext);}/*-----------------------------------------------------------------------------------*//* open_url(): * * Called when the URL present in the global "url" variable should be * opened. It will call the hostname resolver as well as the HTTP * client requester. */static voidopen_url(void){ unsigned char i; static char host[32]; char *file; register char *urlptr; unsigned short port; static u16_t addr[2]; /* Trim off any spaces in the end of the url. */ urlptr = url + strlen(url) - 1; while(*urlptr == ' ' && urlptr > url) { *urlptr = 0; --urlptr; } /* Don't even try to go further if the URL is empty. */ if(urlptr == url) { return; } /* See if the URL starts with http://, otherwise prepend it. */ if(strncmp(url, http_http, 7) != 0) { while(urlptr >= url) { *(urlptr + 7) = *urlptr; --urlptr; } strncpy(url, http_http, 7); } /* Find host part of the URL. */ urlptr = &url[7]; for(i = 0; i < sizeof(host); ++i) { if(*urlptr == 0 || *urlptr == '/' || *urlptr == ' ' || *urlptr == ':') { host[i] = 0; break; } host[i] = *urlptr; ++urlptr; } /* XXX: Here we should find the port part of the URL, but this isn't currently done because of laziness from the programmer's side :-) */ /* Find file part of the URL. */ while(*urlptr != '/' && *urlptr != 0) { ++urlptr; } if(*urlptr == '/') { file = urlptr; } else { file = "/"; } /* Try to lookup the hostname. If it fails, we initiate a hostname lookup and print out an informative message on the statusbar. */ if(uip_main_ipaddrconv(host, (unsigned char *)addr) == 0) { if(resolv_lookup(host) == NULL) { resolv_query(host); show_statustext("Resolving host..."); return; } } /* The hostname we present in the hostname table, so we send out the initial GET request. */ if(webclient_get(host, 80, file) == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -