39 #include "ctk/ctk-textentry-cmdline.h"
40 #include "contiki-net.h"
43 #if WWW_CONF_WITH_WGET
44 #include "program-handler.h"
47 #include "webclient.h"
48 #include "htmlparser.h"
49 #include "http-strings.h"
57 #define PRINTF(x) printf x
62 static char url[WWW_CONF_MAX_URLLEN + 1];
65 static char webpage[WWW_CONF_WEBPAGE_WIDTH *
66 WWW_CONF_WEBPAGE_HEIGHT + 1];
71 #if WWW_CONF_HISTORY_SIZE > 0
72 static struct ctk_button backbutton =
74 static struct ctk_button downbutton =
77 static struct ctk_button downbutton =
80 static struct ctk_button stopbutton =
81 {
CTK_BUTTON(WWW_CONF_WEBPAGE_WIDTH - 16, 0, 4,
"Stop")};
82 static struct ctk_button gobutton =
83 {
CTK_BUTTON(WWW_CONF_WEBPAGE_WIDTH - 4, 0, 2,
"Go")};
85 static struct ctk_separator sep1 =
88 static char editurl[WWW_CONF_MAX_URLLEN + 1];
89 static struct ctk_textentry urlentry =
91 1, editurl, WWW_CONF_MAX_URLLEN)};
92 static struct ctk_label webpagelabel =
94 WWW_CONF_WEBPAGE_HEIGHT, webpage)};
96 static char statustexturl[WWW_CONF_WEBPAGE_WIDTH];
97 static struct ctk_label statustext =
98 {
CTK_LABEL(0, WWW_CONF_WEBPAGE_HEIGHT + 4,
99 WWW_CONF_WEBPAGE_WIDTH, 1,
"")};
100 static struct ctk_separator sep2 =
102 WWW_CONF_WEBPAGE_WIDTH)};
104 #if WWW_CONF_WITH_WGET || defined(WWW_CONF_WGET_EXEC)
107 static struct ctk_label wgetlabel1 =
108 {
CTK_LABEL(1, 1, 34, 1,
"This web page cannot be displayed.")};
109 static struct ctk_label wgetlabel2 =
110 {
CTK_LABEL(1, 3, 35, 1,
"Would you like to download instead?")};
111 static struct ctk_button wgetnobutton =
113 static struct ctk_button wgetyesbutton =
114 {
CTK_BUTTON(11, 5, 24,
"Close browser & download")};
116 static struct ctk_button wgetnobutton =
117 {
CTK_BUTTON((WWW_CONF_WEBPAGE_WIDTH - 38) / 2 + 1,
119 static struct ctk_button wgetyesbutton =
120 {
CTK_BUTTON((WWW_CONF_WEBPAGE_WIDTH - 38) / 2 + 11,
121 11, 24,
"Close browser & download")};
125 #if WWW_CONF_HISTORY_SIZE > 0
127 static char history[WWW_CONF_HISTORY_SIZE][WWW_CONF_MAX_URLLEN];
128 static char history_last;
132 struct ctk_hyperlink hyperlink;
139 struct inputattrib *nextptr;
144 struct inputattrib *nextptr;
145 struct formattrib *formptr;
150 struct inputattrib *nextptr;
151 struct formattrib *formptr;
152 struct ctk_textentry textentry;
156 struct submitattrib {
157 struct inputattrib *nextptr;
158 struct formattrib *formptr;
159 struct ctk_button button;
163 static char pageattribs[WWW_CONF_PAGEATTRIB_SIZE];
164 static char *pageattribptr;
167 static struct formattrib *formptr;
168 static struct inputattrib *currptr;
172 #define ISO_space 0x20
173 #define ISO_ampersand 0x26
174 #define ISO_plus 0x2b
175 #define ISO_slash 0x2f
177 #define ISO_questionmark 0x3f
180 static char *webpageptr;
181 static unsigned char x, y;
182 static unsigned char loading;
183 static unsigned short firsty, pagey;
185 static unsigned char count;
186 static char receivingmsgs[4][23] = {
187 "Receiving web page ...",
188 "Receiving web page. ..",
189 "Receiving web page.. .",
190 "Receiving web page... "
193 PROCESS(www_process,
"Web browser");
195 AUTOSTART_PROCESSES(&www_process);
197 static void CC_FASTCALL formsubmit(
struct formattrib *form);
207 #if WWW_CONF_HISTORY_SIZE > 0
216 CTK_WIDGET_SET_FLAG(&webpagelabel, CTK_WIDGET_FLAG_MONOSPACE);
220 pageattribptr = pageattribs;
234 add_pageattrib(
unsigned size)
238 if(pageattribptr + size > pageattribs +
sizeof(pageattribs)) {
242 pageattribptr += size;
248 add_forminput(
struct inputattrib *inputptr)
250 inputptr->nextptr =
NULL;
251 currptr->nextptr = inputptr;
261 memset(webpage, 0, WWW_CONF_WEBPAGE_WIDTH * WWW_CONF_WEBPAGE_HEIGHT);
268 memcpy(editurl, url, WWW_CONF_MAX_URLLEN);
269 strncpy(editurl,
"http://", 7);
270 petsciiconv_topetscii(editurl + 7, WWW_CONF_MAX_URLLEN - 7);
280 webpageptr = webpage;
286 show_statustext(
char *text)
302 static char host[32];
304 register char *urlptr;
305 static uip_ipaddr_t addr;
308 urlptr = url + strlen(url) - 1;
309 while(*urlptr ==
' ' && urlptr > url) {
320 if(strncmp(url, http_http, 7) != 0) {
321 while(urlptr >= url) {
322 *(urlptr + 7) = *urlptr;
325 strncpy(url, http_http, 7);
330 for(i = 0; i <
sizeof(host); ++i) {
347 while(*urlptr !=
'/' && *urlptr != 0) {
360 uip_ipaddr_t *addrptr;
363 show_statustext(
"Resolving host...");
374 if(webclient_get(host, 80, file) == 0) {
375 show_statustext(
"Out of memory error");
377 show_statustext(
"Connecting...");
390 register char *urlptr;
392 if(strncmp(link, http_http, 7) == 0) {
395 strncpy(url, link, WWW_CONF_MAX_URLLEN);
396 }
else if(*link == ISO_slash &&
397 *(link + 1) == ISO_slash) {
402 strncpy(&url[5], link, WWW_CONF_MAX_URLLEN);
403 }
else if(*link == ISO_slash) {
408 for(urlptr = &url[7];
409 *urlptr != 0 && *urlptr != ISO_slash;
411 strncpy(urlptr, link, WWW_CONF_MAX_URLLEN - (urlptr - url));
417 for(urlptr = url + strlen(url);
418 urlptr != url && *urlptr != ISO_slash;
421 strncpy(urlptr, link, WWW_CONF_MAX_URLLEN - (urlptr - url));
425 #if WWW_CONF_HISTORY_SIZE > 0
434 if(strncmp(url, history[(
int)history_last], WWW_CONF_MAX_URLLEN) != 0) {
435 memcpy(history[(
int)history_last], url, WWW_CONF_MAX_URLLEN);
437 if(history_last >= WWW_CONF_HISTORY_SIZE) {
459 #if WWW_CONF_WITH_WGET
468 memset(webpage, 0,
sizeof(webpage));
470 WWW_CONF_WEBPAGE_HEIGHT+5,
"Web browser");
472 #ifdef WWW_CONF_HOMEPAGE
473 strncpy(editurl, WWW_CONF_HOMEPAGE,
sizeof(editurl));
477 #if WWW_CONF_WITH_WGET || defined(WWW_CONF_WGET_EXEC)
480 ctk_dialog_new(&wgetdialog, 38, 7);
495 webclient_appcall(data);
501 #if WWW_CONF_HISTORY_SIZE > 0
504 memcpy(url, editurl, WWW_CONF_MAX_URLLEN);
505 petsciiconv_toascii(url, WWW_CONF_MAX_URLLEN);
508 #if WWW_CONF_HISTORY_SIZE > 0
509 }
else if(w == (
struct ctk_widget *)&backbutton) {
513 if(history_last > WWW_CONF_HISTORY_SIZE) {
514 history_last = WWW_CONF_HISTORY_SIZE - 1;
516 memcpy(url, history[(
int)history_last], WWW_CONF_MAX_URLLEN);
520 }
else if(w == (
struct ctk_widget *)&downbutton) {
521 firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 4;
525 }
else if(w == (
struct ctk_widget *)&stopbutton) {
528 #if WWW_CONF_WITH_WGET || defined(WWW_CONF_WGET_EXEC)
529 }
else if(w == (
struct ctk_widget *)&wgetnobutton) {
535 }
else if(w == (
struct ctk_widget *)&wgetyesbutton) {
541 #if WWW_CONF_WITH_WGET
543 argptr =
arg_alloc((
char)WWW_CONF_MAX_URLLEN);
545 strncpy(argptr, url, WWW_CONF_MAX_URLLEN);
549 petsciiconv_topetscii(url,
sizeof(url));
552 WWW_CONF_WGET_EXEC(url);
554 show_statustext(
"Cannot exec wget");
560 struct inputattrib *input = (
struct inputattrib *)
561 (((
char *)w) - offsetof(
struct inputattrib, widget));
562 formsubmit(input->formptr);
567 #if WWW_CONF_HISTORY_SIZE > 0
570 set_link(w->
widget.hyperlink.url);
577 strncpy(statustexturl, w->
widget.hyperlink.url,
578 sizeof(statustexturl));
579 petsciiconv_topetscii(statustexturl,
sizeof(statustexturl));
580 show_statustext(statustexturl);
585 if((
char *)data !=
NULL &&
589 show_statustext(
"Host not found");
593 ev == PROCESS_EVENT_EXIT) {
607 set_url(
char *host, uint16_t port,
char *file)
611 memset(url, 0, WWW_CONF_MAX_URLLEN);
613 if(strncmp(file, http_http, 7) == 0) {
614 strncpy(url, file,
sizeof(url));
616 strncpy(url, http_http, 7);
618 strcpy(urlptr, host);
619 urlptr += strlen(host);
620 strcpy(urlptr, file);
632 webclient_aborted(
void)
634 show_statustext(
"Connection reset by peer");
643 webclient_timedout(
void)
645 show_statustext(
"Connection timed out");
655 webclient_closed(
void)
657 show_statustext(
"Stopped");
658 petsciiconv_topetscii(webpageptr - x, x);
669 webclient_connected(
void)
675 show_statustext(
"Request sent...");
676 set_url(webclient_hostname(), webclient_port(), webclient_filename());
687 webclient_datahandler(
char *data, uint16_t len)
690 if(strstr(webclient_mimetype(), http_html + 1) != 0) {
691 count = (count + 1) & 3;
692 show_statustext(receivingmsgs[count]);
693 htmlparser_parse(data, len);
697 #if WWW_CONF_WITH_WGET || defined(WWW_CONF_WGET_EXEC)
699 ctk_dialog_open(&wgetdialog);
701 strcpy(webpage + WWW_CONF_WEBPAGE_WIDTH * 5,
702 (80 - WWW_CONF_WEBPAGE_WIDTH) / 2 +
703 " This web page cannot be displayed.");
704 strcpy(webpage + WWW_CONF_WEBPAGE_WIDTH * 6,
705 (80 - WWW_CONF_WEBPAGE_WIDTH) / 2 +
706 " Would you like to download instead?");
720 show_statustext(
"Done");
721 petsciiconv_topetscii(webpageptr - x, x);
728 add_pagewidget(
char *text,
unsigned char size,
char *attrib,
unsigned char type,
729 unsigned char border)
732 static unsigned char maxwidth;
738 maxwidth = size ? WWW_CONF_WEBPAGE_WIDTH - (1 + 2 * border)
739 : WWW_CONF_WEBPAGE_WIDTH;
744 if(size + x > maxwidth) {
745 htmlparser_newline();
755 if(size > maxwidth) {
760 if(firsty == pagey) {
761 unsigned char attriblen = strlen(attrib);
768 memcpy(wptr, text, size);
770 wptr[size + border] =
' ';
774 struct linkattrib *linkptr =
775 (
struct linkattrib *)add_pageattrib(
sizeof(
struct linkattrib) + attriblen);
776 if(linkptr !=
NULL) {
777 CTK_HYPERLINK_NEW(&linkptr->hyperlink, x, y + 3, size, wptr, linkptr->url);
778 strcpy(linkptr->url, attrib);
779 CTK_WIDGET_SET_FLAG(&linkptr->hyperlink, CTK_WIDGET_FLAG_MONOSPACE);
786 struct submitattrib *submitptr =
787 (
struct submitattrib *)add_pageattrib(
sizeof(
struct submitattrib) + attriblen);
788 if(submitptr !=
NULL) {
789 CTK_BUTTON_NEW((
struct ctk_button *)&submitptr->button, x, y + 3, size, wptr);
790 add_forminput((
struct inputattrib *)submitptr);
791 submitptr->formptr = formptr;
792 strcpy(submitptr->name, attrib);
793 CTK_WIDGET_SET_FLAG(&submitptr->button, CTK_WIDGET_FLAG_MONOSPACE);
799 struct textattrib *textptr =
800 (
struct textattrib *)add_pageattrib(
sizeof(
struct textattrib) + attriblen
801 + (size ? WWW_CONF_MAX_INPUTVALUELEN : strlen(text)) + 1);
802 if(textptr !=
NULL) {
803 CTK_TEXTENTRY_NEW((
struct ctk_textentry *)&textptr->textentry, x, y + 3, size, 1,
804 textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN);
805 add_forminput((
struct inputattrib *)textptr);
806 textptr->formptr = formptr;
807 strcpy(textptr->textentry.text, text);
808 strcpy(textptr->name, attrib);
810 CTK_WIDGET_SET_FLAG(&textptr->textentry, CTK_WIDGET_FLAG_MONOSPACE);
822 size += 1 + 2 * border;
826 if(firsty == pagey) {
830 if(x == WWW_CONF_WEBPAGE_WIDTH) {
831 htmlparser_newline();
836 htmlparser_newline(
void)
850 webpageptr += (WWW_CONF_WEBPAGE_WIDTH - x);
854 wptr = webpageptr - WWW_CONF_WEBPAGE_WIDTH;
855 petsciiconv_topetscii(wptr, WWW_CONF_WEBPAGE_WIDTH);
857 if(y == WWW_CONF_WEBPAGE_HEIGHT) {
864 htmlparser_word(
char *word,
unsigned char wordlen)
867 if(wordlen + 1 > WWW_CONF_WEBPAGE_WIDTH - x) {
868 htmlparser_newline();
872 if(pagey == firsty) {
873 memcpy(webpageptr, word, wordlen);
874 webpageptr += wordlen;
879 if(x == WWW_CONF_WEBPAGE_WIDTH) {
880 htmlparser_newline();
887 htmlparser_link(
char *text,
unsigned char textlen,
char *url)
894 htmlparser_form(
char *action)
896 formptr = (
struct formattrib *)add_pageattrib(
sizeof(
struct formattrib) + strlen(action));
897 if(formptr !=
NULL) {
898 formptr->nextptr =
NULL;
899 currptr = (
struct inputattrib *)formptr;
900 strcpy(formptr->action, action);
905 htmlparser_submitbutton(
char *text,
char *name)
911 htmlparser_inputfield(
unsigned char type,
unsigned char size,
char *text,
char *name)
913 if(type == HTMLPARSER_INPUTTYPE_HIDDEN) {
921 add_query(
char delimiter,
char *
string)
924 unsigned char length;
926 if(delimiter == ISO_questionmark) {
927 query = url + strlen(url);
930 length = strlen(
string);
931 if(query - url + WWW_CONF_MAX_URLLEN - 1 < length) {
935 *query++ = delimiter;
936 strcpy(query,
string);
937 if(delimiter == ISO_eq) {
940 petsciiconv_toascii(query, length);
941 while((space = strchr(space, ISO_space)) !=
NULL) {
949 formsubmit(
struct formattrib *form)
951 struct inputattrib *inputptr;
952 char delimiter = ISO_questionmark;
954 set_link(form->action);
956 for(inputptr = form->nextptr; inputptr !=
NULL; inputptr = inputptr->nextptr) {
961 name = ((
struct submitattrib *)inputptr)->name;
962 value = ((
struct submitattrib *)inputptr)->button.text;
964 name = ((
struct textattrib *)inputptr)->name;
965 value = ((
struct textattrib *)inputptr)->textentry.text;
968 add_query(delimiter, name);
969 add_query(ISO_eq, value);
970 delimiter = ISO_ampersand;
973 #if WWW_CONF_HISTORY_SIZE > 0
#define CTK_WIDGET_ADD(win, widg)
Add a widget to a window.
process_event_t ctk_signal_window_close
Emitted when a window is closed.
#define CTK_WIDGET_TEXTENTRY
Widget number: The CTK textentry widget.
#define CTK_SEPARATOR(x, y, w)
Instantiating macro for the ctk_separator widget.
Hostname is fresh and usable.
void ctk_window_open(CC_REGISTER_ARG struct ctk_window *w)
Open a window, or bring window to front if already open.
#define CTK_WIDGET_FOCUS(win, widg)
Set focus to a widget.
void ctk_window_close(struct ctk_window *w)
Close a window if it is open.
#define PROCESS_BEGIN()
Define the beginning of a process.
process_event_t ctk_signal_hyperlink_hover
Same as ctk_signal_widget_select.
#define CTK_TEXTENTRY(x, y, w, h, text, len)
Instantiating macro for the ctk_textentry widget.
#define ctk_label_set_text(l, t)
Set the text of a label.
#define NULL
The null pointer.
char * arg_alloc(char size)
Allocates an argument buffer.
void ctk_window_redraw(struct ctk_window *w)
Redraw a window.
#define uiplib_ipaddrconv
Convert a textual representation of an IP address to a numerical representation.
#define CTK_LABEL(x, y, w, h, text)
Instantiating macro for the ctk_label widget.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PROCESS_END()
Define the end of a process.
void ctk_window_new(struct ctk_window *window, unsigned char w, unsigned char h, char *title)
Create a new window.
#define uip_abort()
Abort the current connection.
CCIF process_event_t resolv_event_found
Event that is broadcasted when a DNS name has been resolved.
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
PETSCII/ASCII conversion functions.
#define LOADER_UNLOAD()
Unload a program from memory.
void ctk_window_clear(struct ctk_window *w)
Remove all widgets from a window.
process_event_t ctk_signal_hyperlink_activate
Emitted when a hyperlink is activated.
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
#define PROCESS(name, strname)
Declare a process.
#define CTK_WIDGET_BUTTON
Widget number: The CTK button widget.
process_event_t ctk_signal_widget_activate
Emitted when a widget is activated (pressed).
union ctk_widget::@20 widget
The union which contains the actual widget structure, as determined by the type field.
process_event_t tcpip_event
The uIP event.
#define CTK_BUTTON(x, y, w, text)
Instantiating macro for the ctk_button widget.
#define CTK_WIDGET_HYPERLINK
Widget number: The CTK hyperlink widget.
Representation of a CTK window.
The generic CTK widget structure that contains all other widget structures.
#define CTK_WIDGET_REDRAW(widg)
Add a widget to the redraw queue.
unsigned char w
The width of the widget in character coordinates.
#define CC_FASTCALL
Configure if the C compiler supports fastcall function declarations.
void program_handler_load(char *name, char *arg)
Loads a program and displays a dialog telling the user about it.
#define CTK_WIDGET_TYPE(w)
Obtain the type of a widget.
void process_exit(struct process *p)
Cause a process to exit.