#include <u.h>#include <libc.h>#include <draw.h>#include <event.h>#include <panel.h>#include "rtext.h"#include "mothra.h"#include "html.h" typedef struct Field Field;typedef struct Option Option;struct Form{ int method; char *ctype; char *action; Field *fields, *efields; Form *next;};struct Field{ Field *next; Form *form; char *name; char *value; int checked; int size; /* should be a point, but that feature is deprecated */ int maxlength; int type; int rows, cols; Option *options; int multiple; int state; /* is the button marked? */ Panel *p; Panel *pulldown; Panel *textwin;};/* * Field types */enum{ TYPEIN=1, CHECK, PASSWD, RADIO, SUBMIT, RESET, BUTTON, SELECT, TEXTWIN, HIDDEN, INDEX, FILE,};struct Option{ int selected; int def; char label[NLABEL+1]; char *value; Option *next;}; #define BOUNDARY "nAboJ9uN6ZXsqoVGzLAdjKq97TWDTGjo" void h_checkinput(Panel *, int, int);void h_radioinput(Panel *, int, int);void h_submitinput(Panel *, int);void h_buttoninput(Panel *, int);void h_fileinput(Panel *, int);void h_submittype(Panel *, char *);void h_submitindex(Panel *, char *);void h_resetinput(Panel *, int);void h_select(Panel *, int, int);char *selgen(Panel *, int);char *nullgen(Panel *, int);Field *newfield(Form *form){ Field *f; f=emalloc(sizeof(Field)); if(form->efields==0) form->fields=f; else form->efields->next=f; form->efields=f; f->next=0; f->form=form; return f;}/* * Called by rdhtml on seeing a forms-related tag */void rdform(Hglob *g){ char *s; Field *f; Option *o, **op; Form *form; switch(g->tag){ default: fprint(2, "Bad tag <%s> in rdform (Can't happen!)\n", g->token); return; case Tag_form: if(g->form){ htmlerror(g->name, g->lineno, "nested forms illegal\n"); break; } g->form=emalloc(sizeof(Form)); s=pl_getattr(g->attr, "action"); g->form->action=strdup((s && *s) ? s : g->dst->url->fullname); s=pl_getattr(g->attr, "method"); if(s==0 || *s==0) g->form->method=GET; else if(cistrcmp(s, "post")==0) g->form->method=POST; else{ if(cistrcmp(s, "get")!=0) htmlerror(g->name, g->lineno, "unknown form method %s\n", s); g->form->method=GET; } s=pl_getattr(g->attr, "enctype"); if(s && cistrcmp(s, "multipart/form-data")==0) g->form->ctype = "multipart/form-data; boundary=" BOUNDARY; g->form->fields=0; g->form->next = g->dst->form; g->dst->form = g->form; break; case Tag_input: case Tag_button: if(g->form==0){ /* no form, assume link button */ form = emalloc(sizeof(Form)); form->method = 0; form->fields = 0; form->efields = 0; if(g->state->link) form->action = strdup(g->state->link); form->next = g->dst->form; g->dst->form = form; f=newfield(form); } else f=newfield(g->form); s=pl_getattr(g->attr, "name"); if(s==0 || *s == 0) f->name=0; else f->name=strdup(s); s=pl_getattr(g->attr, "value"); if(s==0) f->value=strdup(""); else f->value=strdup(s); f->checked=pl_hasattr(g->attr, "checked"); s=pl_getattr(g->attr, "size"); if(s==0 || *s==0) f->size=20; else f->size=atoi(s); s=pl_getattr(g->attr, "maxlength"); if(s==0 || *s==0) f->maxlength=0x3fffffff; else f->maxlength=atoi(s); s=pl_getattr(g->attr, "type"); if((g->tag == Tag_button) && (s==0 || cistrcmp(s, "reset") || cistrcmp(s, "button"))) s="submit"; else if(s==0) s="text"; if(cistrcmp(s, "checkbox")==0) f->type=CHECK; else if(cistrcmp(s, "radio")==0) f->type=RADIO; else if(cistrcmp(s, "submit")==0) f->type=SUBMIT; else if(cistrcmp(s, "image")==0){ f->type=SUBMIT; s=pl_getattr(g->attr, "src"); if(s && *s){ free(g->state->image); g->state->image = strdup(s); } s=pl_getattr(g->attr, "width"); if(s && *s) g->state->width=strtolength(g, HORIZ, s); s=pl_getattr(g->attr, "height"); if(s && *s) g->state->height=strtolength(g, VERT, s); s=pl_getattr(g->attr, "alt"); if(s==0 || *s == 0) s = f->value; pl_htmloutput(g, g->nsp, s, f); free(g->state->image); g->state->image = 0; g->state->width=0; g->state->height=0; break; } else if(cistrcmp(s, "button")==0) f->type=BUTTON; else if(cistrcmp(s, "file")==0){ f->type=FILE; /* Websites must not be able to set a default file path */ *f->value = '\0'; }else if(cistrcmp(s, "reset")==0) f->type=RESET; else if(cistrcmp(s, "hidden")==0) f->type=HIDDEN; else{ f->type=TYPEIN; if(cistrcmp(s, "password")==0) f->type=PASSWD; s=f->name; if(s && cistrcmp(s, "isindex")==0) f->type=INDEX; /* * If there's exactly one attribute, use its value as the name, * regardless of the attribute name. This makes * http://linus.att.com/ias/puborder.html work. */ if(s==0){ if(g->attr[0].name && g->attr[1].name==0) f->name=strdup(g->attr[0].value); else f->name=strdup("no-name"); } } if((f->type==CHECK || f->type==RADIO) && !pl_hasattr(g->attr, "value")){ free(f->value); f->value=strdup("on"); } if(f->type!=HIDDEN) pl_htmloutput(g, g->nsp, f->value[0]?f->value:"blank field", f); break; case Tag_select: if(g->form==0){ BadTag: htmlerror(g->name, g->lineno, "<%s> not in form, ignored\n", tag[g->tag].name); break; } f=newfield(g->form); s=pl_getattr(g->attr, "name"); if(s==0 || *s==0){ f->name=strdup("select"); htmlerror(g->name, g->lineno, "select has no name=\n"); } else f->name=strdup(s); f->multiple=pl_hasattr(g->attr, "multiple"); f->type=SELECT; f->size=0; f->options=0; g->text=g->token; g->tp=g->text; g->etext=g->text; break; case Tag_option: if(g->form==0) goto BadTag; if((f=g->form->efields)==0) goto BadTag; if(f->size<8) f->size++; o=emalloc(sizeof(Option)); for(op=&f->options;*op;op=&(*op)->next); *op=o; o->next=0; g->text=o->label; g->tp=o->label; g->etext=o->label+NLABEL; memset(o->label, 0, NLABEL+1); *g->tp++=' '; o->def=pl_hasattr(g->attr, "selected"); o->selected=o->def; if(pl_hasattr(g->attr, "disabled")) o->selected=0; s=pl_getattr(g->attr, "value"); if(s==0) o->value=o->label+1; else o->value=strdup(s); break; case Tag_textarea: if(g->form==0) goto BadTag; f=newfield(g->form); s=pl_getattr(g->attr, "name"); if(s==0 || *s==0){ f->name=strdup("enter text"); htmlerror(g->name, g->lineno, "select has no name=\n"); } else f->name=strdup(s); s=pl_getattr(g->attr, "rows"); f->rows=(s && *s)?atoi(s):8; s=pl_getattr(g->attr, "cols"); f->cols=(s && *s)?atoi(s):30; f->type=TEXTWIN; /* suck up initial text */ pl_htmloutput(g, g->nsp, f->name, f); break; case Tag_isindex: /* * Make up a form with one tag, of type INDEX * I have seen a page with <ISINDEX PROMPT="Enter a title here ">, * which is nonstandard and not handled here. */ form=emalloc(sizeof(Form)); form->fields=0; form->efields=0; s=pl_getattr(g->attr, "action"); form->action=strdup((s && *s) ? s : g->dst->url->fullname); form->method=GET; form->fields=0; f=newfield(form); f->name=0; f->value=strdup(""); f->size=20; f->maxlength=0x3fffffff; f->type=INDEX; pl_htmloutput(g, g->nsp, f->value[0]?f->value:"blank field", f); break; }}/* * Called by rdhtml on seeing a forms-related end tag */void endform(Hglob *g){ Field *f; switch(g->tag){ case Tag_form: g->form=0; break; case Tag_select: if(g->form==0) htmlerror(g->name, g->lineno, "</select> not in form, ignored\n"); else if((f=g->form->efields)==0) htmlerror(g->name, g->lineno, "spurious </select>\n"); else pl_htmloutput(g, g->nsp, f->name, f); break; case Tag_textarea: break; }}char *nullgen(Panel *, int ){ return 0;}char *selgen(Panel *p, int index){ Option *a; Field *f; f=p->userp; if(f==0) return 0; for(a=f->options;index!=0 && a!=0;--index,a=a->next); if(a==0) return 0; a->label[0]=a->selected?'*':' '; return a->label;}char *seloption(Field *f){ Option *a; for(a=f->options;a!=0;a=a->next) if(a->selected) return a->label+1; return f->name;}void mkfieldpanel(Rtext *t){ Action *a; Panel *win, *scrl; Field *f; if((a = t->user) == nil) return; if((f = a->field) == nil) return; f->p=0; switch(f->type){ case TYPEIN: f->p=plentry(0, 0, f->size*chrwidth, f->value, h_submittype); break; case PASSWD: f->p=plentry(0, USERFL, f->size*chrwidth, f->value, h_submittype); break; case CHECK: f->p=plcheckbutton(0, 0, "", h_checkinput); f->state=f->checked; plsetbutton(f->p, f->checked); break; case RADIO: f->p=plradiobutton(0, 0, "", h_radioinput); f->state=f->checked; plsetbutton(f->p, f->checked); break; case SUBMIT: f->p=plbutton(0, 0, f->value[0]?f->value:"submit", h_submitinput); break; case RESET: f->p=plbutton(0, 0, f->value[0]?f->value:"reset", h_resetinput); break; case BUTTON: f->p=plbutton(0, 0, f->value[0]?f->value:"button", h_buttoninput); break; case FILE: f->p=plbutton(0, 0, f->value[0]?f->value:"file", h_fileinput); break; case SELECT: if(f->size <= 0) f->size=1; f->pulldown=plgroup(0,0); scrl=plscrollbar(f->pulldown, PACKW|FILLY); win=pllist(f->pulldown, PACKN, nullgen, f->size, h_select); win->userp=f; plinitlist(win, PACKN, selgen, f->size, h_select); plscroll(win, 0, scrl); plpack(f->pulldown, Rect(0,0,1024,1024)); f->p=plpulldown(0, FIXEDX, seloption(f), f->pulldown, PACKS); f->p->fixedsize.x=f->pulldown->r.max.x-f->pulldown->r.min.x; break; case TEXTWIN: f->p=plframe(0,0); pllabel(f->p, PACKN|FILLX, f->name); scrl=plscrollbar(f->p, PACKW|FILLY); f->textwin=pledit(f->p, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height), 0, 0, 0); f->textwin->userp=f; plscroll(f->textwin, 0, scrl); break; case INDEX: f->p=plentry(0, 0, f->size*chrwidth, f->value, h_submitindex); break; } if(f->p){ f->p->userp=f; free(t->text); t->text=0; t->p=f->p; t->flags|=PL_HOT; }}void h_checkinput(Panel *p, int, int v){ ((Field *)p->userp)->state=v;}void h_radioinput(Panel *p, int, int v){ Field *f, *me; me=p->userp; me->state=v; if(v){ for(f=me->form->fields;f;f=f->next) if(f->type==RADIO && f!=me && strcmp(f->name, me->name)==0){ plsetbutton(f->p, 0); f->state=0; pldraw(f->p, screen); } }}void h_select(Panel *p, int, int index){ Option *a; Field *f; f=p->userp; if(f==0) return; if(!f->multiple) for(a=f->options;a;a=a->next) a->selected=0; for(a=f->options;index!=0 && a!=0;--index,a=a->next); if(a==0) return; a->selected=!a->selected; plinitpulldown(f->p, FIXEDX, seloption(f), f->pulldown, PACKS); pldraw(f->p, screen);}void h_resetinput(Panel *p, int){ Field *f; Option *o; for(f=((Field *)p->userp)->form->fields;f;f=f->next) switch(f->type){ case TYPEIN: plinitentry(f->p, 0, f->size*chrwidth, f->value, 0); break; case PASSWD: plinitentry(f->p, USERFL, f->size*chrwidth, f->value, 0); break; case FILE: free(f->value); f->value=strdup(""); if(f->p==nil) break; f->p->state=0; pldraw(f->p, screen); break; case CHECK: case RADIO: f->state=f->checked; plsetbutton(f->p, f->checked); break; case SELECT: for(o=f->options;o;o=o->next) o->selected=o->def; break; } pldraw(text, screen);} void h_buttoninput(Panel *p, int){ Field *f; f = p->userp; if(f && f->form && f->form->method != POST && f->form->action) geturl(f->form->action, -1, 0, 0);} Lines 1–500 of 766. Load more
#include <u.h> #include <libc.h> #include <draw.h> #include <event.h> #include <panel.h> #include "rtext.h" #include "mothra.h" #include "html.h" typedef struct Field Field; typedef struct Option Option; struct Form{ int method; char *ctype; char *action; Field *fields, *efields; Form *next; }; struct Field{ Field *next; Form *form; char *name; char *value; int checked; int size; /* should be a point, but that feature is deprecated */ int maxlength; int type; int rows, cols; Option *options; int multiple; int state; /* is the button marked? */ Panel *p; Panel *pulldown; Panel *textwin; }; /* * Field types */ enum{ TYPEIN=1, CHECK, PASSWD, RADIO, SUBMIT, RESET, BUTTON, SELECT, TEXTWIN, HIDDEN, INDEX, FILE, }; struct Option{ int selected; int def; char label[NLABEL+1]; char *value; Option *next; }; #define BOUNDARY "nAboJ9uN6ZXsqoVGzLAdjKq97TWDTGjo" void h_checkinput(Panel *, int, int); void h_radioinput(Panel *, int, int); void h_submitinput(Panel *, int); void h_buttoninput(Panel *, int); void h_fileinput(Panel *, int); void h_submittype(Panel *, char *); void h_submitindex(Panel *, char *); void h_resetinput(Panel *, int); void h_select(Panel *, int, int); char *selgen(Panel *, int); char *nullgen(Panel *, int); Field *newfield(Form *form){ Field *f; f=emalloc(sizeof(Field)); if(form->efields==0) form->fields=f; else form->efields->next=f; form->efields=f; f->next=0; f->form=form; return f; } /* * Called by rdhtml on seeing a forms-related tag */ void rdform(Hglob *g){ char *s; Field *f; Option *o, **op; Form *form; switch(g->tag){ default: fprint(2, "Bad tag <%s> in rdform (Can't happen!)\n", g->token); return; case Tag_form: if(g->form){ htmlerror(g->name, g->lineno, "nested forms illegal\n"); break; } g->form=emalloc(sizeof(Form)); s=pl_getattr(g->attr, "action"); g->form->action=strdup((s && *s) ? s : g->dst->url->fullname); s=pl_getattr(g->attr, "method"); if(s==0 || *s==0) g->form->method=GET; else if(cistrcmp(s, "post")==0) g->form->method=POST; else{ if(cistrcmp(s, "get")!=0) htmlerror(g->name, g->lineno, "unknown form method %s\n", s); g->form->method=GET; } s=pl_getattr(g->attr, "enctype"); if(s && cistrcmp(s, "multipart/form-data")==0) g->form->ctype = "multipart/form-data; boundary=" BOUNDARY; g->form->fields=0; g->form->next = g->dst->form; g->dst->form = g->form; break; case Tag_input: case Tag_button: if(g->form==0){ /* no form, assume link button */ form = emalloc(sizeof(Form)); form->method = 0; form->fields = 0; form->efields = 0; if(g->state->link) form->action = strdup(g->state->link); form->next = g->dst->form; g->dst->form = form; f=newfield(form); } else f=newfield(g->form); s=pl_getattr(g->attr, "name"); if(s==0 || *s == 0) f->name=0; else f->name=strdup(s); s=pl_getattr(g->attr, "value"); if(s==0) f->value=strdup(""); else f->value=strdup(s); f->checked=pl_hasattr(g->attr, "checked"); s=pl_getattr(g->attr, "size"); if(s==0 || *s==0) f->size=20; else f->size=atoi(s); s=pl_getattr(g->attr, "maxlength"); if(s==0 || *s==0) f->maxlength=0x3fffffff; else f->maxlength=atoi(s); s=pl_getattr(g->attr, "type"); if((g->tag == Tag_button) && (s==0 || cistrcmp(s, "reset") || cistrcmp(s, "button"))) s="submit"; else if(s==0) s="text"; if(cistrcmp(s, "checkbox")==0) f->type=CHECK; else if(cistrcmp(s, "radio")==0) f->type=RADIO; else if(cistrcmp(s, "submit")==0) f->type=SUBMIT; else if(cistrcmp(s, "image")==0){ f->type=SUBMIT; s=pl_getattr(g->attr, "src"); if(s && *s){ free(g->state->image); g->state->image = strdup(s); } s=pl_getattr(g->attr, "width"); if(s && *s) g->state->width=strtolength(g, HORIZ, s); s=pl_getattr(g->attr, "height"); if(s && *s) g->state->height=strtolength(g, VERT, s); s=pl_getattr(g->attr, "alt"); if(s==0 || *s == 0) s = f->value; pl_htmloutput(g, g->nsp, s, f); free(g->state->image); g->state->image = 0; g->state->width=0; g->state->height=0; break; } else if(cistrcmp(s, "button")==0) f->type=BUTTON; else if(cistrcmp(s, "file")==0){ f->type=FILE; /* Websites must not be able to set a default file path */ *f->value = '\0'; }else if(cistrcmp(s, "reset")==0) f->type=RESET; else if(cistrcmp(s, "hidden")==0) f->type=HIDDEN; else{ f->type=TYPEIN; if(cistrcmp(s, "password")==0) f->type=PASSWD; s=f->name; if(s && cistrcmp(s, "isindex")==0) f->type=INDEX; /* * If there's exactly one attribute, use its value as the name, * regardless of the attribute name. This makes * http://linus.att.com/ias/puborder.html work. */ if(s==0){ if(g->attr[0].name && g->attr[1].name==0) f->name=strdup(g->attr[0].value); else f->name=strdup("no-name"); } } if((f->type==CHECK || f->type==RADIO) && !pl_hasattr(g->attr, "value")){ free(f->value); f->value=strdup("on"); } if(f->type!=HIDDEN) pl_htmloutput(g, g->nsp, f->value[0]?f->value:"blank field", f); break; case Tag_select: if(g->form==0){ BadTag: htmlerror(g->name, g->lineno, "<%s> not in form, ignored\n", tag[g->tag].name); break; } f=newfield(g->form); s=pl_getattr(g->attr, "name"); if(s==0 || *s==0){ f->name=strdup("select"); htmlerror(g->name, g->lineno, "select has no name=\n"); } else f->name=strdup(s); f->multiple=pl_hasattr(g->attr, "multiple"); f->type=SELECT; f->size=0; f->options=0; g->text=g->token; g->tp=g->text; g->etext=g->text; break; case Tag_option: if(g->form==0) goto BadTag; if((f=g->form->efields)==0) goto BadTag; if(f->size<8) f->size++; o=emalloc(sizeof(Option)); for(op=&f->options;*op;op=&(*op)->next); *op=o; o->next=0; g->text=o->label; g->tp=o->label; g->etext=o->label+NLABEL; memset(o->label, 0, NLABEL+1); *g->tp++=' '; o->def=pl_hasattr(g->attr, "selected"); o->selected=o->def; if(pl_hasattr(g->attr, "disabled")) o->selected=0; s=pl_getattr(g->attr, "value"); if(s==0) o->value=o->label+1; else o->value=strdup(s); break; case Tag_textarea: if(g->form==0) goto BadTag; f=newfield(g->form); s=pl_getattr(g->attr, "name"); if(s==0 || *s==0){ f->name=strdup("enter text"); htmlerror(g->name, g->lineno, "select has no name=\n"); } else f->name=strdup(s); s=pl_getattr(g->attr, "rows"); f->rows=(s && *s)?atoi(s):8; s=pl_getattr(g->attr, "cols"); f->cols=(s && *s)?atoi(s):30; f->type=TEXTWIN; /* suck up initial text */ pl_htmloutput(g, g->nsp, f->name, f); break; case Tag_isindex: /* * Make up a form with one tag, of type INDEX * I have seen a page with <ISINDEX PROMPT="Enter a title here ">, * which is nonstandard and not handled here. */ form=emalloc(sizeof(Form)); form->fields=0; form->efields=0; s=pl_getattr(g->attr, "action"); form->action=strdup((s && *s) ? s : g->dst->url->fullname); form->method=GET; form->fields=0; f=newfield(form); f->name=0; f->value=strdup(""); f->size=20; f->maxlength=0x3fffffff; f->type=INDEX; pl_htmloutput(g, g->nsp, f->value[0]?f->value:"blank field", f); break; } } /* * Called by rdhtml on seeing a forms-related end tag */ void endform(Hglob *g){ Field *f; switch(g->tag){ case Tag_form: g->form=0; break; case Tag_select: if(g->form==0) htmlerror(g->name, g->lineno, "</select> not in form, ignored\n"); else if((f=g->form->efields)==0) htmlerror(g->name, g->lineno, "spurious </select>\n"); else pl_htmloutput(g, g->nsp, f->name, f); break; case Tag_textarea: break; } } char *nullgen(Panel *, int ){ return 0; } char *selgen(Panel *p, int index){ Option *a; Field *f; f=p->userp; if(f==0) return 0; for(a=f->options;index!=0 && a!=0;--index,a=a->next); if(a==0) return 0; a->label[0]=a->selected?'*':' '; return a->label; } char *seloption(Field *f){ Option *a; for(a=f->options;a!=0;a=a->next) if(a->selected) return a->label+1; return f->name; } void mkfieldpanel(Rtext *t){ Action *a; Panel *win, *scrl; Field *f; if((a = t->user) == nil) return; if((f = a->field) == nil) return; f->p=0; switch(f->type){ case TYPEIN: f->p=plentry(0, 0, f->size*chrwidth, f->value, h_submittype); break; case PASSWD: f->p=plentry(0, USERFL, f->size*chrwidth, f->value, h_submittype); break; case CHECK: f->p=plcheckbutton(0, 0, "", h_checkinput); f->state=f->checked; plsetbutton(f->p, f->checked); break; case RADIO: f->p=plradiobutton(0, 0, "", h_radioinput); f->state=f->checked; plsetbutton(f->p, f->checked); break; case SUBMIT: f->p=plbutton(0, 0, f->value[0]?f->value:"submit", h_submitinput); break; case RESET: f->p=plbutton(0, 0, f->value[0]?f->value:"reset", h_resetinput); break; case BUTTON: f->p=plbutton(0, 0, f->value[0]?f->value:"button", h_buttoninput); break; case FILE: f->p=plbutton(0, 0, f->value[0]?f->value:"file", h_fileinput); break; case SELECT: if(f->size <= 0) f->size=1; f->pulldown=plgroup(0,0); scrl=plscrollbar(f->pulldown, PACKW|FILLY); win=pllist(f->pulldown, PACKN, nullgen, f->size, h_select); win->userp=f; plinitlist(win, PACKN, selgen, f->size, h_select); plscroll(win, 0, scrl); plpack(f->pulldown, Rect(0,0,1024,1024)); f->p=plpulldown(0, FIXEDX, seloption(f), f->pulldown, PACKS); f->p->fixedsize.x=f->pulldown->r.max.x-f->pulldown->r.min.x; break; case TEXTWIN: f->p=plframe(0,0); pllabel(f->p, PACKN|FILLX, f->name); scrl=plscrollbar(f->p, PACKW|FILLY); f->textwin=pledit(f->p, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height), 0, 0, 0); f->textwin->userp=f; plscroll(f->textwin, 0, scrl); break; case INDEX: f->p=plentry(0, 0, f->size*chrwidth, f->value, h_submitindex); break; } if(f->p){ f->p->userp=f; free(t->text); t->text=0; t->p=f->p; t->flags|=PL_HOT; } } void h_checkinput(Panel *p, int, int v){ ((Field *)p->userp)->state=v; } void h_radioinput(Panel *p, int, int v){ Field *f, *me; me=p->userp; me->state=v; if(v){ for(f=me->form->fields;f;f=f->next) if(f->type==RADIO && f!=me && strcmp(f->name, me->name)==0){ plsetbutton(f->p, 0); f->state=0; pldraw(f->p, screen); } } } void h_select(Panel *p, int, int index){ Option *a; Field *f; f=p->userp; if(f==0) return; if(!f->multiple) for(a=f->options;a;a=a->next) a->selected=0; for(a=f->options;index!=0 && a!=0;--index,a=a->next); if(a==0) return; a->selected=!a->selected; plinitpulldown(f->p, FIXEDX, seloption(f), f->pulldown, PACKS); pldraw(f->p, screen); } void h_resetinput(Panel *p, int){ Field *f; Option *o; for(f=((Field *)p->userp)->form->fields;f;f=f->next) switch(f->type){ case TYPEIN: plinitentry(f->p, 0, f->size*chrwidth, f->value, 0); break; case PASSWD: plinitentry(f->p, USERFL, f->size*chrwidth, f->value, 0); break; case FILE: free(f->value); f->value=strdup(""); if(f->p==nil) break; f->p->state=0; pldraw(f->p, screen); break; case CHECK: case RADIO: f->state=f->checked; plsetbutton(f->p, f->checked); break; case SELECT: for(o=f->options;o;o=o->next) o->selected=o->def; break; } pldraw(text, screen); } void h_buttoninput(Panel *p, int){ Field *f; f = p->userp; if(f && f->form && f->form->method != POST && f->form->action) geturl(f->form->action, -1, 0, 0); }