diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2019-01-07 20:00:52 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2019-01-07 20:00:52 (GMT) |
commit | 1ea9e06c2ff3a6f4059d1be92dcca32157fe7c03 (patch) | |
tree | fb96917e1f49ca7bcef7efc1107c1306f604a471 /tkhtml1/src/htmlform.c | |
parent | f946ccfb35b2c144c4bb456d5fe9b48c1b8ae524 (diff) | |
download | blt-1ea9e06c2ff3a6f4059d1be92dcca32157fe7c03.zip blt-1ea9e06c2ff3a6f4059d1be92dcca32157fe7c03.tar.gz blt-1ea9e06c2ff3a6f4059d1be92dcca32157fe7c03.tar.bz2 |
update TEA 3.13
Diffstat (limited to 'tkhtml1/src/htmlform.c')
-rw-r--r-- | tkhtml1/src/htmlform.c | 606 |
1 files changed, 0 insertions, 606 deletions
diff --git a/tkhtml1/src/htmlform.c b/tkhtml1/src/htmlform.c deleted file mode 100644 index 210ae62..0000000 --- a/tkhtml1/src/htmlform.c +++ /dev/null @@ -1,606 +0,0 @@ -/* -** Routines used for processing HTML makeup for forms. -** -** Copyright (C) 1997-2000 D. Richard Hipp -** -** This library is free software; you can redistribute it and/or -** modify it under the terms of the GNU Library General Public -** License as published by the Free Software Foundation; either -** version 2 of the License, or (at your option) any later version. -** -** This library is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Library General Public License for more details. -** -** You should have received a copy of the GNU Library General Public -** License along with this library; if not, write to the -** Free Software Foundation, Inc., 59 Temple Place - Suite 330, -** Boston, MA 02111-1307, USA. -** -** Author contact information: -** drh@acm.org -** http://www.hwaci.com/drh/ -*/ -#include <tk.h> -#include <string.h> -#include <stdlib.h> -#include <stdarg.h> -#include "htmlform.h" - -/* -** Unmap any input control that is currently mapped. -*/ -void HtmlUnmapControls(HtmlWidget *htmlPtr){ - HtmlElement *p; - - for(p=htmlPtr->firstInput; p; p=p->input.pNext){ - if( p->input.tkwin!=0 && Tk_IsMapped(p->input.tkwin) ){ - Tk_UnmapWindow(p->input.tkwin); - } - } -} - -/* -** Map any control that should be visible according to the -** current scroll position. At the same time, if any controls that -** should not be visible are mapped, unmap them. After this routine -** finishes, all <INPUT> controls should be in their proper places -** regardless of where they might have been before. -** -** Return the number of controls that are currently visible. -*/ -int HtmlMapControls(HtmlWidget *htmlPtr){ - HtmlElement *p; /* For looping over all controls */ - int x, y, w, h; /* Part of the virtual canvas that is visible */ - int cnt = 0; /* Number of visible controls */ - - x = htmlPtr->xOffset; - y = htmlPtr->yOffset; - w = Tk_Width(htmlPtr->clipwin); - h = Tk_Height(htmlPtr->clipwin); - for(p=htmlPtr->firstInput; p; p=p->input.pNext){ - if( p->input.tkwin==0 ) continue; - if( p->input.y < y+h - && p->input.y + p->input.h > y - && p->input.x < x+w - && p->input.x + p->input.w > x - ){ - /* The control should be visible. Make is so if it isn't already */ - Tk_MoveResizeWindow(p->input.tkwin, - p->input.x - x, p->input.y - y, - p->input.w, p->input.h); - if( !Tk_IsMapped(p->input.tkwin) ){ - Tk_MapWindow(p->input.tkwin); - } - cnt++; - }else{ - /* This control should not be visible. Unmap it. */ - if( Tk_IsMapped(p->input.tkwin) ){ - Tk_UnmapWindow(p->input.tkwin); - } - } - } - return cnt; -} - -/* -** Delete all input controls. This happens when the HTML widget -** is cleared. -** -** When the TCL "exit" command is invoked, the order of operations -** here is very touchy. -*/ -void HtmlDeleteControls(HtmlWidget *htmlPtr){ - HtmlElement *p; /* For looping over all controls */ - Tcl_Interp *interp; /* The interpreter */ - - interp = htmlPtr->interp; - p = htmlPtr->firstInput; - htmlPtr->firstInput = 0; - htmlPtr->lastInput = 0; - htmlPtr->nInput = 0; - if( p==0 || htmlPtr->tkwin==0 ) return; - HtmlLock(htmlPtr); - for(; p; p=p->input.pNext){ - if( p->input.pForm && p->input.pForm->form.id>0 - && htmlPtr->zFormCommand && htmlPtr->zFormCommand[0] - && !Tcl_InterpDeleted(interp) && htmlPtr->clipwin ){ - Tcl_DString cmd; - int result; - char zBuf[60]; - Tcl_DStringInit(&cmd); - Tcl_DStringAppend(&cmd, htmlPtr->zFormCommand, -1); - sprintf(zBuf," %d flush", p->input.pForm->form.id); - Tcl_DStringAppend(&cmd, zBuf, -1); - result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); - Tcl_DStringFree(&cmd); - if( !Tcl_InterpDeleted(interp) ){ - if( result != TCL_OK ){ - Tcl_AddErrorInfo(htmlPtr->interp, - "\n (-formcommand flush callback executed by html widget)"); - Tcl_BackgroundError(htmlPtr->interp); - TestPoint(0); - } - Tcl_ResetResult(htmlPtr->interp); - } - p->input.pForm->form.id = 0; - } - if( p->input.tkwin ){ - if( htmlPtr->clipwin!=0 ) Tk_DestroyWindow(p->input.tkwin); - p->input.tkwin = 0; - } - p->input.sized = 0; - } - HtmlUnlock(htmlPtr); -} - -/* -** Return an appropriate type value for the given <INPUT> markup. -*/ -static int InputType(HtmlElement *p){ - int type = INPUT_TYPE_Unknown; - char *z; - int i; - static struct { - char *zName; - int type; - } types[] = { - { "checkbox", INPUT_TYPE_Checkbox }, - { "file", INPUT_TYPE_File }, - { "hidden", INPUT_TYPE_Hidden }, - { "image", INPUT_TYPE_Image }, - { "password", INPUT_TYPE_Password }, - { "radio", INPUT_TYPE_Radio }, - { "reset", INPUT_TYPE_Reset }, - { "submit", INPUT_TYPE_Submit }, - { "text", INPUT_TYPE_Text }, - }; - - switch( p->base.type ){ - case Html_INPUT: - z = HtmlMarkupArg(p, "type", "text"); - if( z==0 ){ TestPoint(0); break; } - for(i=0; i<sizeof(types)/sizeof(types[0]); i++){ - if( stricmp(types[i].zName,z)==0 ){ - type = types[i].type; - TestPoint(0); - break; - } - TestPoint(0); - } - break; - case Html_SELECT: - type = INPUT_TYPE_Select; - TestPoint(0); - break; - case Html_TEXTAREA: - type = INPUT_TYPE_TextArea; - TestPoint(0); - break; - case Html_APPLET: - case Html_IFRAME: - case Html_EMBED: - type = INPUT_TYPE_Applet; - TestPoint(0); - break; - default: - CANT_HAPPEN; - break; - } - return type; -} - -/* -** Create the window name for a child widget. Space to hold the name -** is obtained from HtmlAlloc() and must be freed by the calling function. -*/ -static char *MakeWindowName( - HtmlWidget *htmlPtr, /* The HTML widget */ - HtmlElement *pElem /* The input that needs a child widget */ -){ - int n; - char *zBuf; - - n = strlen(Tk_PathName(htmlPtr->clipwin)); - zBuf = HtmlAlloc( n + 20 ); - sprintf(zBuf,"%s.x%d",Tk_PathName(htmlPtr->clipwin), pElem->input.cnt); - return zBuf; -} - -/* -** A Input element is the input. Mark this element as being -** empty. It has no widget and doesn't appear on the screen. -** -** This is called for HIDDEN inputs or when the -formcommand -** callback doesn't create the widget. -*/ -static void EmptyInput(HtmlElement *pElem){ - pElem->input.tkwin = 0; - pElem->input.w = 0; - pElem->input.h = 0; - pElem->base.flags &= !HTML_Visible; - pElem->base.style.flags |= STY_Invisible; - pElem->input.sized = 1; -} - -/* -** This routine is called when one of the child windows for a form -** wants to change its size. -*/ -static void HtmlInputRequestProc(ClientData clientData, Tk_Window tkwin){ - HtmlElement *pElem = (HtmlElement*)clientData; - if( pElem->base.type!=Html_INPUT ){ CANT_HAPPEN; return; } - if( pElem->input.tkwin!=tkwin ){ CANT_HAPPEN; return; } - pElem->input.w = Tk_ReqWidth(tkwin); - pElem->input.h = Tk_ReqHeight(tkwin); - if( pElem->input.htmlPtr && pElem->input.htmlPtr->tkwin!=0 ){ - pElem->input.htmlPtr->flags |= RELAYOUT; - HtmlScheduleRedraw(pElem->input.htmlPtr); - } -} - -/* -** This routine is called when another entity takes over geometry -** management for a widget corresponding to an input element. -*/ -static void HtmlInputLostSlaveProc(ClientData clientData, Tk_Window tkwin){ - HtmlElement *pElem = (HtmlElement*)clientData; - if( pElem->base.type!=Html_INPUT ){ CANT_HAPPEN; return; } - if( pElem->input.tkwin!=tkwin ){ CANT_HAPPEN; return; } - EmptyInput(pElem); - if( pElem->input.htmlPtr && pElem->input.htmlPtr->tkwin!=0 ){ - pElem->input.htmlPtr->flags |= RELAYOUT; - HtmlScheduleRedraw(pElem->input.htmlPtr); - } -} - -/* -** This routine catches DestroyNotify events on a INPUT window so -** that we will know the window is been deleted. -*/ -static void HtmlInputEventProc(ClientData clientData, XEvent *eventPtr){ - HtmlElement *pElem = (HtmlElement*)clientData; - /* if( pElem->base.type!=Html_INPUT ){ CANT_HAPPEN; return; } */ - if( eventPtr->type==DestroyNotify ){ - EmptyInput(pElem); - if( pElem->input.htmlPtr && pElem->input.htmlPtr->tkwin!=0 ){ - pElem->input.htmlPtr->flags |= RELAYOUT; - HtmlScheduleRedraw(pElem->input.htmlPtr); - } - } -} - -/* -** The geometry manager for the HTML widget -*/ -static Tk_GeomMgr htmlGeomType = { - "html", /* Name */ - HtmlInputRequestProc, /* Called when widget changes size */ - HtmlInputLostSlaveProc, /* Called when someone else takes over management */ -}; - -/* -** zWin is the name of a child widget that is used to implement an -** input element. Query Tk for information about this widget (such -** as its size) and put that information in the pElem structure -** that represents the input. -*/ -static void SizeAndLink(HtmlWidget *htmlPtr, char *zWin, HtmlElement *pElem){ - pElem->input.tkwin = Tk_NameToWindow(htmlPtr->interp, zWin, htmlPtr->clipwin); - if( pElem->input.tkwin==0 ){ - Tcl_ResetResult(htmlPtr->interp); - EmptyInput(pElem); - }else if( pElem->input.type==INPUT_TYPE_Hidden ){ - pElem->input.w = 0; - pElem->input.h = 0; - pElem->base.flags &= !HTML_Visible; - pElem->base.style.flags |= STY_Invisible; - }else{ - pElem->input.w = Tk_ReqWidth(pElem->input.tkwin); - pElem->input.h = Tk_ReqHeight(pElem->input.tkwin); - pElem->base.flags |= HTML_Visible; - pElem->input.htmlPtr = htmlPtr; - Tk_ManageGeometry(pElem->input.tkwin, &htmlGeomType, pElem); - Tk_CreateEventHandler(pElem->input.tkwin, StructureNotifyMask, - HtmlInputEventProc, pElem); - } - pElem->input.pNext = 0; - if( htmlPtr->firstInput==0 ){ - htmlPtr->firstInput = pElem; - }else{ - htmlPtr->lastInput->input.pNext = pElem; - } - htmlPtr->lastInput = pElem; - pElem->input.sized = 1; -} - -/* Append all text and space tokens between pStart and pEnd to -** the given Tcl_DString. -*/ -static void HtmlAppendText( - Tcl_DString *str, /* Append the text here */ - HtmlElement *pFirst, /* The first token */ - HtmlElement *pEnd /* The last token */ -){ - while( pFirst && pFirst!=pEnd ){ - switch( pFirst->base.type ){ - case Html_Text: { - Tcl_DStringAppend(str, pFirst->text.zText, -1); - break; - } - case Html_Space: { - if( pFirst->base.flags & HTML_NewLine ){ - Tcl_DStringAppend(str, "\n", 1); - }else{ - int cnt; - static char zSpaces[] = " "; - cnt = pFirst->base.count; - while( cnt>sizeof(zSpaces)-1 ){ - Tcl_DStringAppend(str, zSpaces, sizeof(zSpaces)-1); - cnt -= sizeof(zSpaces)-1; - } - if( cnt>0 ){ - Tcl_DStringAppend(str, zSpaces, cnt); - } - } - break; - } - default: - /* Do nothing */ - break; - } - pFirst = pFirst->pNext; - } -} - -/* -** The "p" argument points to a <select>. This routine scans all -** subsequent elements (up to the next </select>) looking for -** <option> tags. For each option tag, it appends three elements -** to the "str" DString: -** -** * 1 or 0 to indicated whether or not the element is -** selected. -** -** * The value returned if this element is selected. -** -** * The text displayed for this element. -*/ -static void AddSelectOptions( - Tcl_DString *str, /* Add text here */ - HtmlElement *p, /* The <SELECT> markup */ - HtmlElement *pEnd /* The </SELECT> markup */ -){ - while( p && p!=pEnd && p->base.type!=Html_EndSELECT ){ - if( p->base.type==Html_OPTION ){ - char *zValue; - Tcl_DStringStartSublist(str); - if( HtmlMarkupArg(p, "selected", 0)==0 ){ - Tcl_DStringAppend(str, "0 ", 2); - }else{ - Tcl_DStringAppend(str, "1 ", 2); - } - zValue = HtmlMarkupArg(p, "value", ""); - Tcl_DStringAppendElement(str, zValue); - Tcl_DStringStartSublist(str); - p = p->pNext; - while( p && p!=pEnd && p->base.type!=Html_EndOPTION - && p->base.type!=Html_OPTION && p->base.type!=Html_EndSELECT ){ - if( p->base.type==Html_Text ){ - Tcl_DStringAppend(str, p->text.zText, -1); - }else if( p->base.type==Html_Space ){ - Tcl_DStringAppend(str, " ", 1); - } - p = p->pNext; - } - Tcl_DStringEndSublist(str); - Tcl_DStringEndSublist(str); - }else{ - p = p->pNext; - } - } -} - -/* -** This routine implements the Sizer() function for <INPUT>, -** <SELECT> and <TEXTAREA> markup. -** -** A side effect of sizing these markups is that widgets are -** created to represent the corresponding input controls. -** -** The function normally returns 0. But if it is dealing with -** a <SELECT> or <TEXTAREA> that is incomplete, 1 is returned. -** In that case, the sizer will be called again at some point in -** the future when more information is available. -*/ -int HtmlControlSize(HtmlWidget *htmlPtr, HtmlElement *pElem){ - char *zWin; /* Name of child widget that implements this input */ - int incomplete = 0; /* True if data is incomplete */ - Tcl_DString cmd; /* The complete -formcommand callback */ - - if( pElem->input.sized ) return 0; - pElem->input.type = InputType(pElem); - switch( pElem->input.type ){ - case INPUT_TYPE_Checkbox: - case INPUT_TYPE_Hidden: - case INPUT_TYPE_Image: - case INPUT_TYPE_Radio: - case INPUT_TYPE_Reset: - case INPUT_TYPE_Submit: - case INPUT_TYPE_Text: - case INPUT_TYPE_Password: - case INPUT_TYPE_File: { - int result; - char zToken[50]; - - if( pElem->input.pForm==0 || htmlPtr->zFormCommand==0 - || htmlPtr->zFormCommand[0]==0 ){ - EmptyInput(pElem); - break; - } - Tcl_DStringInit(&cmd); - Tcl_DStringAppend(&cmd, htmlPtr->zFormCommand, -1); - sprintf(zToken," %d input ",pElem->input.pForm->form.id); - Tcl_DStringAppend(&cmd, zToken, -1); - pElem->input.cnt = ++htmlPtr->nInput; - zWin = MakeWindowName(htmlPtr, pElem); - Tcl_DStringAppend(&cmd, zWin, -1); - Tcl_DStringStartSublist(&cmd); - HtmlAppendArglist(&cmd, pElem); - Tcl_DStringEndSublist(&cmd); - HtmlLock(htmlPtr); - result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); - Tcl_DStringFree(&cmd); - if( !HtmlUnlock(htmlPtr) ){ - SizeAndLink(htmlPtr, zWin, pElem); - } - HtmlFree(zWin); - break; - } - case INPUT_TYPE_Select: { - int result; - char zToken[50]; - - if( pElem->input.pForm==0 || htmlPtr->zFormCommand==0 - || htmlPtr->zFormCommand[0]==0 ){ - EmptyInput(pElem); - break; - } - Tcl_DStringInit(&cmd); - Tcl_DStringAppend(&cmd, htmlPtr->zFormCommand, -1); - sprintf(zToken," %d select ",pElem->input.pForm->form.id); - Tcl_DStringAppend(&cmd, zToken, -1); - pElem->input.cnt = ++htmlPtr->nInput; - zWin = MakeWindowName(htmlPtr, pElem); - Tcl_DStringAppend(&cmd, zWin, -1); - Tcl_DStringStartSublist(&cmd); - HtmlAppendArglist(&cmd, pElem); - Tcl_DStringEndSublist(&cmd); - Tcl_DStringStartSublist(&cmd); - AddSelectOptions(&cmd, pElem, pElem->input.pEnd); - Tcl_DStringEndSublist(&cmd); - HtmlLock(htmlPtr); - result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); - Tcl_DStringFree(&cmd); - if( !HtmlUnlock(htmlPtr) ){ - SizeAndLink(htmlPtr, zWin, pElem); - } - HtmlFree(zWin); - break; - } - case INPUT_TYPE_TextArea: { - int result; - char zToken[50]; - - if( pElem->input.pForm==0 || htmlPtr->zFormCommand==0 - || htmlPtr->zFormCommand[0]==0 ){ - EmptyInput(pElem); - break; - } - Tcl_DStringInit(&cmd); - Tcl_DStringAppend(&cmd, htmlPtr->zFormCommand, -1); - sprintf(zToken," %d textarea ",pElem->input.pForm->form.id); - Tcl_DStringAppend(&cmd, zToken, -1); - pElem->input.cnt = ++htmlPtr->nInput; - zWin = MakeWindowName(htmlPtr, pElem); - Tcl_DStringAppend(&cmd, zWin, -1); - Tcl_DStringStartSublist(&cmd); - HtmlAppendArglist(&cmd, pElem); - Tcl_DStringEndSublist(&cmd); - Tcl_DStringStartSublist(&cmd); - HtmlAppendText(&cmd, pElem, pElem->input.pEnd); - Tcl_DStringEndSublist(&cmd); - HtmlLock(htmlPtr); - result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); - Tcl_DStringFree(&cmd); - if( !HtmlUnlock(htmlPtr) ){ - SizeAndLink(htmlPtr, zWin, pElem); - } - HtmlFree(zWin); - break; - } - case INPUT_TYPE_Applet: { - int result; - - if( htmlPtr->zAppletCommand==0 || htmlPtr->zAppletCommand[0]==0 ){ - EmptyInput(pElem); - break; - } - Tcl_DStringInit(&cmd); - Tcl_DStringAppend(&cmd, htmlPtr->zAppletCommand, -1); - Tcl_DStringAppend(&cmd, " ", 1); - pElem->input.cnt = ++htmlPtr->nInput; - zWin = MakeWindowName(htmlPtr, pElem); - Tcl_DStringAppend(&cmd, zWin, -1); - Tcl_DStringStartSublist(&cmd); - HtmlAppendArglist(&cmd, pElem); - Tcl_DStringEndSublist(&cmd); - HtmlLock(htmlPtr); - result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); - Tcl_DStringFree(&cmd); - if( !HtmlUnlock(htmlPtr) ){ - SizeAndLink(htmlPtr, zWin, pElem); - } - HtmlFree(zWin); - break; - } - default: { - CANT_HAPPEN; - pElem->base.flags &= ~HTML_Visible; - pElem->base.style.flags |= STY_Invisible; - pElem->input.tkwin = 0; - break; - } - } - return incomplete; -} - -#if 0 -/* -** The following array determines which characters can be put directly -** in a query string and which must be escaped. -*/ -static char needEscape[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, -}; -#define NeedToEscape(C) ((C)>0 && (C)<127 && needEscape[(int)(C)]) - -/* -** Append to the given DString, an encoded version of the given -** text. -*/ -static void EncodeText(Tcl_DString *str, char *z){ - int i; - while( *z ){ - for(i=0; z[i] && !NeedToEscape(z[i]); i++){ TestPoint(0); } - if( i>0 ){ TestPoint(0); Tcl_DStringAppend(str, z, i); } - z += i; - while( *z && NeedToEscape(*z) ){ - if( *z==' ' ){ - Tcl_DStringAppend(str,"+",1); - TestPoint(0); - }else if( *z=='\n' ){ - Tcl_DStringAppend(str, "%0D%0A", 6); - TestPoint(0); - }else if( *z=='\r' ){ - /* Ignore it... */ - TestPoint(0); - }else{ - char zBuf[5]; - sprintf(zBuf,"%%%02X",0xff & *z); - Tcl_DStringAppend(str, zBuf, 3); - TestPoint(0); - } - z++; - } - } -} -#endif |