earlybrowserreborn - Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 roytam 1 /*==================================================================*/
2 /*                                                                  */
3 /* SGMLInputTextObject                                              */
4 /*                                                                  */
5 /* T.Johnson - (TonyJ@Slacvx.Slac.Stanford.Edu)           June.92   */
6 /*                                                                  */
7 /* Defines a input text segment for the SGMLHyper widget            */
8 /*                                                                  */
9 /*==================================================================*/
10 #include <ctype.h>
11 #include <X11/IntrinsicP.h>
12 #include <X11/StringDefs.h>
13 #include <X11/CoreP.h>
14 #include <Xm/List.h>
15 #include <Xm/RowColumn.h>
16 #include <Xm/PushB.h>
17 #include <Xm/ToggleB.h>
18 #include <Xm/Text.h>
19 #include <Xm/TextF.h>
20 #include <Xm/ScrolledW.h>
21 #include "SGMLInputTextP.h"
22 #include "SGMLFormText.h"
23 #include "SGMLCompositeTextP.h"   /* BAD */
24  
25 /*
26   Private functions
27 */
28  
29 #define Strlen(x) (x?strlen(x):0)
30  
31 static Boolean option_selected, option = FALSE;
32 static char *option_value;
33  
34 /*
35   Widget class methods
36 */
37  
38 static void    Destroy();
39 static void    Initialize();
40 static void    ClassInitialize();
41 static Boolean InheritChanges();
42 static Boolean SetValues();
43  
44 static XrmQuark TypeText;
45 static XrmQuark TypeSubmit;
46 static XrmQuark TypeReset;
47 static XrmQuark TypeCheckbox;
48 static XrmQuark TypePassword;
49 static XrmQuark TypeRadio;
50 static XrmQuark TypeTextArea;
51 static XrmQuark TypeSelect;
52 static XrmQuark TypeHidden;
53 static XrmQuark TypeImage;
54 static XrmQuark TypeOption;
55  
56 static XmString emptyLabel;
57  
58 #define Offset(field) XtOffsetOf(SGMLInputTextRec,sgml_input_text.field)
59  
60 static XtResource resources[] = {
61  
62     {SGMLNtype,SGMLCType,SGMLRQuark,sizeof(XrmQuark),
63      Offset (type),SGMLRQuark,(XtPointer) &TypeText},
64  
65     {SGMLNname,SGMLCName,XtRString,sizeof(String),
66      Offset (name),XtRImmediate,(XtPointer)0},
67  
68     {SGMLNvalue,SGMLCValue,XtRString,sizeof(String),
69      Offset (value),XtRImmediate,(XtPointer)0},
70  
71     {SGMLNimage,SGMLCImage,"Image",sizeof(GIFImage *),
72      Offset (image),XtRImmediate,(XtPointer)0},
73  
74     {SGMLNsize,SGMLCSize,XtRInt,sizeof(int),
75      Offset (size),XtRImmediate,(XtPointer)0},
76  
77     {SGMLNrows,SGMLCRows,XtRInt,sizeof(int),
78      Offset (rows),XtRImmediate,(XtPointer)0},
79  
80     {SGMLNcols,SGMLCCols,XtRInt,sizeof(int),
81      Offset (cols),XtRImmediate,(XtPointer)0},
82  
83     {SGMLNmaxlength,SGMLCMaxlength,XtRInt,sizeof(int),
84      Offset (maxlength),XtRImmediate,(XtPointer)0},
85  
86     {SGMLNchecked,SGMLCChecked,XtRBoolean,sizeof(Boolean),
87      Offset (checked),XtRImmediate,(XtPointer)FALSE},
88  
89     {SGMLNmultiple,SGMLCMultiple,XtRBoolean,sizeof(Boolean),
90      Offset (multiple),XtRImmediate,(XtPointer)FALSE},
91  
92     {SGMLNselected,SGMLCSelected,XtRBoolean,sizeof(Boolean),
93      Offset (selected),XtRImmediate,(XtPointer)FALSE},
94  
95     {SGMLNautosubmit,SGMLCAutosubmit,XtRBoolean,sizeof(Boolean),
96      Offset (auto_submit),XtRImmediate,(XtPointer)TRUE},  
97  
98     {SGMLNbombPixmap,SGMLCBombPixmap,"Icon",sizeof(Pixmap),
99      Offset (bomb),XtRImmediate,(XtPointer)NULL},
100  
101 };
102 #undef Offset
103  
104 /*---------------------------------------------------------------*/
105 /* Static initialisation of the class record                     */
106 /*---------------------------------------------------------------*/
107  
108 SGMLInputTextClassRec  sGMLInputTextClassRec = {
109     {
110     (WidgetClass) &sGMLContainerTextClassRec,
111                                          /* superclass            */
112     "SGMLInputText",                     /* class_name            */
113     sizeof(SGMLInputTextRec),            /* widget_size           */
114     ClassInitialize,                     /* class_initialize      */
115     NULL,                                /* class_part_initialize */
116     FALSE,                               /* class_inited          */
117     Initialize,                          /* initialize            */
118     NULL,                                /* initialize_hook       */
119     NULL,                                /* obj1                  */
120     NULL,                                /* obj2                  */
121     0,                                   /* obj3                  */
122     resources,                           /* resources             */
123     XtNumber(resources),                 /* num_resources         */
124     NULLQUARK,                           /* xrm_class             */
125     0,                                   /* obj4                  */
126     0,                                   /* obj5                  */
127     0,                                   /* obj6                  */
128     0,                                   /* obj7                  */
129     Destroy,                             /* destroy               */
130     NULL,                                /* obj8                  */
131     NULL,                                /* obj9                  */
132     SetValues,                           /* set_values            */
133     NULL,                                /* set_values_hook       */
134     NULL,                                /* obj10                 */
135     NULL,                                /* get_values_hook       */
136     NULL,                                /* obj11                 */
137     XtVersion,                           /* version               */
138     NULL,                                /* callback private      */
139     NULL,                                /* obj12                 */
140     NULL,                                /* obj13                 */
141     NULL,                                /* obj14                 */
142     NULL,                                /* extension             */
143     },
144     {
145     SGMLInheritComputeSize,              /* compute_size          */
146     SGMLInheritAdjustSize,               /* adjust_size           */
147     SGMLInheritAdjustPosition,           /* adjust_position       */
148     SGMLInheritExpose,                   /* expose                */
149     SGMLInheritActivate,                 /* activate              */
150     SGMLInheritHilite,                   /* hilite                */
151     SGMLInheritContains,                 /* contains              */
152     SGMLInheritCallCreateCallback,       /* call_create_callback  */
153     SGMLInheritCallMapCallback,          /* call_map_callback     */
154     SGMLInheritMakeVisible,              /* make_visible          */
155     NULL,                                /* sgml_set_values       */
156     InheritChanges,                      /* inherit_changes       */
157     SGMLInheritComputeChangeMask,        /* compute_change_mask   */
158     SGMLInheritSearch,                   /* search                */
159     SGMLInheritClearSelect,              /* clear_select          */
160     SGMLInheritHiliteSelection,          /* hilite_selection      */
161     SGMLInheritXYToPos,                  /* xy_to_pos             */
162     SGMLInheritPosToXY,                  /* pos_to_xy             */
163     SGMLInheritDumpText,                 /* dump_text             */
164     NULL,                                /* extension             */
165     },
166     {
167     SGMLInheritGeometryManager,          /* geometry_manager      */
168     NULL,                                /* extension             */
169     },
170     {
171     NULL,                                /* extension             */
172     },
173 };
174  
175  
176 WidgetClass sGMLInputTextObjectClass = (WidgetClass) &sGMLInputTextClassRec;
177  
178 /*--------------------------------------------------------------*/
179 /* ClassInitialize:                                             */
180 /*--------------------------------------------------------------*/
181  
182 static void ClassInitialize ()
183 {
184   TypeText      = XrmPermStringToQuark("text");
185   TypeSubmit    = XrmPermStringToQuark("submit");
186   TypeReset     = XrmPermStringToQuark("reset");
187   TypeCheckbox  = XrmPermStringToQuark("checkbox");
188   TypePassword  = XrmPermStringToQuark("password");
189   TypeRadio     = XrmPermStringToQuark("radio");
190   TypeSelect    = XrmPermStringToQuark("select");
191   TypeTextArea  = XrmPermStringToQuark("textarea");
192   TypeHidden    = XrmPermStringToQuark("hidden");
193   TypeImage     = XrmPermStringToQuark("image");
194   TypeOption    = XrmPermStringToQuark("option");
195  
196   emptyLabel    = XmStringCreateSimple("");
197 }
198  
199 /*--------------------------------------------------------------*/
200 /* check_passwd, echos *s in text widget, taken from Motif FAQ  */
201 /*--------------------------------------------------------------*/
202 /* Written by Dan Heller.  Copyright 1991, O'Reilly && Associates.
203  * This program is freely distributable without licensing fees and
204  * is provided without guarantee or warranty expressed or implied.
205  * This program is -not- in the public domain.  This program appears
206  * in the Motif Programming Manual, O'Reilly Volume 6.
207  */
208  
209 /* passwd.c -- prompt for a passwd.  Meaning, all input looks like
210  * a series of *'s.  Store the actual data typed by the user in
211  * an internal variable.  Don't allow paste operations.  Handle
212  * backspacing by deleting all text from insertion point to the
213  * end of text.
214  */
215  
216 void
217 check_passwd(text_w, buffer, cbs)
218 Widget        text_w;
219 char        **buffer;
220 XmTextVerifyCallbackStruct *cbs;
221 {
222     char *new;
223     int len;
224     char *passwd = *buffer;  
225  
226     if (cbs->text->ptr == NULL) { /* backspace */
227         cbs->endPos = Strlen(passwd); /* delete from here to end */
228         if (cbs->endPos <= 0) return; /* catch null passwd - Mark Scoville */
229         passwd[cbs->startPos] = 0; /* backspace--terminate */
230         return;
231     }
232  
233     if (cbs->text->length > 1) {
234         cbs->doit = False; /* don't allow "paste" operations */
235         return; /* make the user *type* the password! */
236     }
237  
238     new = XtMalloc(cbs->endPos + 2); /* new char + NULL terminator */
239     if (passwd) {
240         strcpy(new, passwd);
241         XtFree(passwd);
242     } else
243         new[0] = '\0';
244     passwd = new;
245     strncat(passwd, cbs->text->ptr, cbs->text->length);
246     passwd[cbs->endPos + cbs->text->length] = 0;
247  
248     for (len = 0; len < cbs->text->length; len++)
249         cbs->text->ptr[len] = '*';
250  
251     *buffer = new;
252 }
253  
254 /*--------------------------------------------------------------*/
255 /* SetupImage:                                                  */
256 /*--------------------------------------------------------------*/
257  
258 static void SetupImage(w)
259 SGMLInputTextObject w;
260 {
261   Widget parent = (Widget) w;
262   GIFImage *gifImage = w->sgml_input_text.image;
263   char message[256];
264   Pixmap pixmap;
265  
266   for ( ; !XtIsWidget(parent) ; parent = XtParent(parent));
267  
268   pixmap = GIFToPixmap(parent,gifImage,message);
269   if (!pixmap) printf("Image conversion error: %s\n",message);  
270   else
271    {
272       Arg arglist[10];
273       int n=0;
274  
275       XtSetArg(arglist[n],XmNlabelPixmap,pixmap); n++;
276       XtSetValues(w->sgml_input_text.child,arglist,n);
277     }
278 }
279 /*--------------------------------------------------------------*/
280 /* ResetAction:                                                 */
281 /*--------------------------------------------------------------*/
282  static void ResetAction(w)
283 SGMLInputTextObject w;
284 {
285   XrmQuark type  = w->sgml_input_text.type;
286   Widget child = w->sgml_input_text.child;
287  
288   if (type == TypePassword || type == TypeText)
289     {
290       char *value = w->sgml_input_text.value;
291       XmTextFieldSetString(child,value?value:"");
292     }
293   else if (type == TypeTextArea)
294     {
295       char *text = w->sgml_text.text;
296       XmTextSetString(child,text?text:"");
297     }
298   else if (type == TypeSelect)
299     {
300       Boolean selected = w->sgml_input_text.selected;
301       int n=0;
302       Arg arglist[10];
303  
304       Widget list;
305       Widget p = XtParent((Widget) w);
306  
307       XtSetArg(arglist[n],SGMLNuserdata,&list); n++;
308       XtGetValues(p,arglist,n); n = 0;
309  
310       if (XtIsSubclass(list,xmListWidgetClass))
311         {
312           XmString Text;
313           char *q, *p, *text = XtNewString(w->sgml_text.text);
314  
315           /* Strip off leading and trailing white-space */
316  
317           for (p = text ; *p && isspace(*p) ; p++);
318           for (q = p + Strlen(p) ; q-- > p && isspace(*q) ; ) *q = '\0';
319  
320           if (child) XmListDeselectAllItems(list);
321  
322           Text = XmStringCreateSimple(p);
323           if (selected)
324             {
325               int nsel, i;
326               XmString *List, *NewList;
327  
328               n = 0;
329               XtSetArg(arglist[n],XmNselectedItems,&List); n++;
330               XtSetArg(arglist[n],XmNselectedItemCount,&nsel); n++;
331               XtGetValues(list,arglist,n); n = 0;
332               NewList = (XmString *) XtMalloc((nsel+1) * sizeof(XmString *));
333               for (i = 0; i < nsel; i++) NewList[i] = List[i];
334               NewList[nsel++] = Text;
335  
336               XtSetArg(arglist[n],XmNselectedItems,NewList); n++;
337               XtSetArg(arglist[n],XmNselectedItemCount,nsel); n++;
338               XtSetValues(list,arglist,n);
339               XtFree((char *) NewList);
340             }
341  
342           XmStringFree(Text);
343           XtFree(text);
344         }
345       else if (selected)
346         {
347           n = 0;
348           XtSetArg(arglist[n],XmNmenuHistory,child); n++;
349           XtSetValues(list,arglist,n);
350         }
351     }
352   else if (type == TypeCheckbox || type == TypeRadio)
353     {
354       Boolean set  = w->sgml_input_text.checked;
355       XmToggleButtonSetState(child,set,FALSE);
356     }    
357 }
358 static void Reset(reset,new)
359 Widget reset;
360 Widget new;
361 {
362    if (SGMLIsCompositeText(new))
363      {
364         SGMLCompositeTextObject w = (SGMLCompositeTextObject) new;
365         Widget *children = w->sgml_composite_text.children;
366         int n = w->sgml_composite_text.num_children;
367  
368         for (; n--; ) Reset(reset,*children++);
369      }  
370    else if (SGMLIsInputText(new)) ResetAction(new);
371 }
372 /*
373  * This routine is used to encode a search string
374  * ASSUMES ascii character set
375  */
376 static char* Encode(search)
377 char *search;
378 {
379   static Boolean isAcceptable[96] =
380  
381   /*   0 1 2 3 4 5 6 7 8 9 A B C D E F */
382   {    0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,  /* 2x   !"#$%&'()*+,-./         */
383        1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,  /* 3x  0123456789:;<=>?         */
384        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  /* 4x  @ABCDEFGHIJKLMNO         */
385        1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,  /* 5X  PQRSTUVWXYZ[\]^_         */
386        0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  /* 6x  `abcdefghijklmno         */
387        1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0 };/* 7X  pqrstuvwxyz{\}~ DEL      */
388  
389   if (!search) return;
390   else
391     {
392       char *result = XtMalloc(3*Strlen(search) + 1);
393       char *p, *s, *e, *q;
394  
395       for (s = search ; *s && isspace(*s); s++);
396       for (e = s + Strlen(s) ; e>s && isspace(*(e-1)) ; e--);  
397       for (q = result , p = s ; p<e ; p++ )
398         {
399           int c = (int) *p;
400           if      (isspace(c)) *q++ = '+';
401           else if (c>= 32  && c<= 127 && isAcceptable[c-32]) *q++ = (char) c;
402           else { sprintf(q,"%%%2x",c); q += 3; }
403         }  
404       *q = '\0';
405       return result;
406     }
407 }
408 static void PutResult(buffer,name,value)
409 char **buffer, *name, *value;
410 {
411   char *old = *buffer;
412   char *ename = Encode(name);
413   char *evalue = Encode(value);
414   char *new = (char *) XtMalloc(Strlen(old) + Strlen(ename) + Strlen(evalue) + 3);
415  
416   sprintf(new,"%s%s=%s&",old?old:"",ename,evalue);
417  
418   XtFree(old);
419   XtFree(ename);
420   XtFree(evalue);
421   *buffer = new;
422 }
423 static void ActivateAction(w,ActivateRoutine,Closure)
424 SGMLInputTextObject w;
425 void (*ActivateRoutine)();
426 void *Closure;
427 {
428   XrmQuark type  = w->sgml_input_text.type;
429   Widget child = w->sgml_input_text.child;
430   char *name = w->sgml_input_text.name;
431  
432   if (type == TypeText)
433     {
434       char *value = XmTextFieldGetString(child);
435       ActivateRoutine(Closure,name,value);
436       XtFree(value);
437     }      
438   else if (type == TypePassword)
439     {
440       char *value = w->sgml_input_text.passwd;
441       ActivateRoutine(Closure,name,value);
442     }
443   else if (type == TypeHidden)
444     {
445       char *value =  w->sgml_input_text.value;
446       ActivateRoutine(Closure,name,value);
447     }
448   else if (type == TypeCheckbox || type == TypeRadio)
449     {
450       Boolean set = XmToggleButtonGetState(child);
451       if (set)
452         {
453           char *value =  w->sgml_input_text.value;
454           ActivateRoutine(Closure,name,value?value:"on");
455         }
456     }
457   else if (type == TypeTextArea)
458     {
459       char *value = XmTextGetString(child);
460       ActivateRoutine(Closure,name,value);
461     }
462   else if (type == TypeSelect)
463     {
464       Boolean selected = w->sgml_input_text.selected;
465       int n=0;
466       Arg arglist[10];
467  
468       Widget list;
469       Widget p = XtParent((Widget) w);
470  
471       XtSetArg(arglist[n],SGMLNuserdata,&list); n++;
472       XtGetValues(p,arglist,n); n = 0;
473  
474       if (XtIsSubclass(list,xmListWidgetClass))
475          {
476            static int ns;
477            static int *positions = NULL;
478            static int position;
479            char *name = XtName(list);
480            char *text =  w->sgml_text.text;
481  
482            if (child) /* Only the first item in the list has a child */
483              {
484                XtFree((char *) positions);
485                position = 0;
486                if (!XmListGetSelectedPos(list,&positions,&ns)) { positions = NULL; ns = 0; }
487              }
488            if (text && *text && option)
489              {  
490                position++;
491                for (n = 0; n < ns ; n++)
492                  if (position == positions[n])
493                    {
494                      char *value = w->sgml_input_text.value;
495                      ActivateRoutine(Closure,name,value);
496                    }
497              }
498         }                  
499       else
500         {
501           Widget menuHistory;
502           XtSetArg(arglist[n],XmNmenuHistory,&menuHistory); n++;
503           XtGetValues(list,arglist,n); n = 0;
504           if (menuHistory == child)
505             {
506               char *value = w->sgml_input_text.value;
507               char *name = XtName(list);
508               ActivateRoutine(Closure,name,value);
509             }
510         }
511     }
512   option = (type == TypeOption);
513 }
514 static void ActivateChain(activate,new,ActivateRoutine,Closure)
515 Widget activate;
516 Widget new;
517 void (*ActivateRoutine)();
518 void * Closure;
519 {
520  
521    if (SGMLIsCompositeText(new))
522      {
523         SGMLCompositeTextObject w = (SGMLCompositeTextObject) new;
524         Widget *children = w->sgml_composite_text.children;
525         int n = w->sgml_composite_text.num_children;
526  
527         for (; n--; ) ActivateChain(activate,*children++,ActivateRoutine,Closure);
528      }  
529    else if (SGMLIsInputText(new)) ActivateAction(new,ActivateRoutine,Closure);
530 }
531 static void Activate(activate,form)
532 Widget activate;
533 Widget form;
534 {
535   char *Buffer = NULL;
536   ActivateChain(activate,form,PutResult,&Buffer);
537   if (*Buffer) *(Buffer + Strlen(Buffer) - 1) = '\0';
538   SGMLFormSetResult(form,Buffer);
539 }  
540 static void ActivateImage(activate,form,cb)
541 Widget activate;
542 Widget form;
543 XmPushButtonCallbackStruct *cb;
544 {
545   char *Buffer = NULL;
546   ActivateChain(activate,form,PutResult,&Buffer);
547  
548   if (cb->event->type == ButtonPress || cb->event->type == ButtonRelease)
549     {
550       XButtonEvent *be = (XButtonEvent *) cb->event;
551       char *name = (char *) XtMalloc(Strlen(XtName(activate)) + 10);
552       char value[20];
553       Dimension hT, mH, mW, sT ,mL, mT;
554       Arg arglist[10];
555       int n = 0;
556       Position x, y;
557  
558       XtSetArg(arglist[n],XmNhighlightThickness, &hT); n++;
559       XtSetArg(arglist[n],XmNmarginHeight,       &mH); n++;
560       XtSetArg(arglist[n],XmNmarginWidth,        &mW); n++;
561       XtSetArg(arglist[n],XmNshadowThickness,    &sT); n++;
562       XtSetArg(arglist[n],XmNmarginLeft,         &mL); n++;
563       XtSetArg(arglist[n],XmNmarginTop,          &mT); n++;
564       XtGetValues(activate,arglist,n);
565  
566       x = be->x - hT - mW - sT - mL;
567       y = be->y - hT - mH - sT - mT;
568  
569       sprintf(name,"%s.x",XtName(activate));
570       sprintf(value,"%d",x<0?0:x);
571       PutResult(&Buffer,name,value);
572  
573       sprintf(name,"%s.y",XtName(activate));
574       sprintf(value,"%d",y<0?0:y);
575       PutResult(&Buffer,name,value);
576  
577       XtFree(name);
578     }
579  
580   if (*Buffer) *(Buffer + Strlen(Buffer) - 1) = '\0';
581   SGMLFormSetResult(form,Buffer);
582 }
583 static void RadioAction(radio,w)
584 Widget radio;
585 SGMLInputTextObject w;
586 {
587   Widget c2 = w->sgml_container_text.child;  
588  
589   if (w->sgml_input_text.type != TypeRadio) return;
590   if (radio->core.xrm_name != c2->core.xrm_name) return;
591   XmToggleButtonSetState(c2,(radio == c2),FALSE);
592 }
593 static void Radio(radio,new)
594 Widget radio;
595 Widget new;
596 {
597    if (SGMLIsCompositeText(new))
598      {
599         SGMLCompositeTextObject w = (SGMLCompositeTextObject) new;
600         Widget *children = w->sgml_composite_text.children;
601         int n = w->sgml_composite_text.num_children;
602  
603         for (; n--; ) Radio(radio,*children++);
604      }  
605    else if (SGMLIsInputText(new)) RadioAction(radio,new);
606 }
607 /*--------------------------------------------------------------*/
608 /* Initialize:                                                  */
609 /*--------------------------------------------------------------*/
610  
611 static void Initialize (request, new)
612 SGMLInputTextObject request, new;
613 {
614   Widget parent, child, ichild;
615   XrmQuark type   = new->sgml_input_text.type;
616   char    *name   = new->sgml_input_text.name;
617   char    *value  = new->sgml_input_text.value;
618   Dimension sT, hT, mH, mB;
619   XmFontList font = XmFontListCreate(new->sgml_text.font,XmSTRING_DEFAULT_CHARSET);
620   int n=0;
621   Arg arglist[20];
622  
623   if (name)   new->sgml_input_text.name   = XtNewString(name);
624   if (value)  new->sgml_input_text.value  = XtNewString(value);
625  
626   new->sgml_input_text.passwd = NULL;
627  
628   for (parent = XtParent((Widget) new);
629        !XtIsWidget(parent) ;
630        parent = XtParent(parent));
631  
632   XtSetArg(arglist[n],XmNuserData,new); n++;
633   XtSetArg(arglist[n],XmNfontList,font); n++;  
634  
635   if (type == TypeSubmit)
636     {  
637       Widget form;
638       XmString Value;
639       if (!value) value = "Submit Query";
640  
641       Value = XmStringCreateSimple(value);
642  
643       XtSetArg(arglist[n],XmNlabelString,Value); n++;
644  
645       ichild = child = XtCreateWidget(name,xmPushButtonWidgetClass,parent,arglist,n);
646  
647       n = 0;
648       XtSetArg(arglist[n],XmNshadowThickness,   &sT); n++;
649       XtSetArg(arglist[n],XmNhighlightThickness,&hT); n++;
650       XtSetArg(arglist[n],XmNmarginHeight,      &mH); n++;
651       XtSetArg(arglist[n],XmNmarginBottom,      &mB); n++;
652       XtGetValues(child,arglist,n);
653  
654       new->sgml_container_text.vertical_offset = -sT - hT - mH - mB - new->sgml_text.descent;  
655  
656       XmStringFree(Value);
657  
658       for (form = (Widget) new ; form ; form = XtParent(form))
659         if (SGMLIsFormText(form))
660           {    
661             XtAddCallback(child,XmNactivateCallback,(XtCallbackProc) Activate,(XtPointer) form);
662             break;
663           }
664     }  
665   else if (type == TypeReset)
666     {  
667       Widget form;
668       XmString Value;
669  
670       if (!value) value = "Reset";
671  
672       Value = XmStringCreateSimple(value);
673  
674       XtSetArg(arglist[n],XmNlabelString,Value); n++;
675  
676       ichild = child = XtCreateWidget(name,xmPushButtonWidgetClass,parent,arglist,n);
677  
678       n = 0;
679       XtSetArg(arglist[n],XmNshadowThickness,   &sT); n++;
680       XtSetArg(arglist[n],XmNhighlightThickness,&hT); n++;
681       XtSetArg(arglist[n],XmNmarginHeight,      &mH); n++;
682       XtSetArg(arglist[n],XmNmarginBottom,      &mB); n++;
683       XtGetValues(child,arglist,n);
684  
685       new->sgml_container_text.vertical_offset = -sT - hT - mH - mB - new->sgml_text.descent;  
686  
687       XmStringFree(Value);
688  
689       for (form = (Widget) new ; form ; form = XtParent(form))
690         if (SGMLIsFormText(form))
691           {    
692             XtAddCallback(child,XmNactivateCallback,(XtCallbackProc) Reset,(XtPointer) form);
693             break;
694           }
695     }
696   else if (type == TypePassword || type == TypeText)
697     {
698       Widget form;
699       int size  = new->sgml_input_text.size;
700       int max   = new->sgml_input_text.maxlength;
701       if (size == 0) size = 20;
702  
703       XtSetArg(arglist[n],XmNuserData,new); n++;
704       XtSetArg(arglist[n],XmNcolumns,size); n++;
705       if (max)   { XtSetArg(arglist[n],XmNmaxLength,max); n++; }
706       if (value) { XtSetArg(arglist[n],XmNvalue,value); n++;   }
707  
708       ichild = child = XtCreateWidget(name,xmTextFieldWidgetClass,parent,arglist,n);
709  
710       n = 0;
711       XtSetArg(arglist[n],XmNshadowThickness,   &sT); n++;
712       XtSetArg(arglist[n],XmNhighlightThickness,&hT); n++;
713       XtSetArg(arglist[n],XmNmarginHeight,      &mH); n++;
714       XtGetValues(child,arglist,n);
715  
716       new->sgml_container_text.vertical_offset = -sT - hT - mH - new->sgml_text.descent;  
717  
718       if (type == TypePassword)
719         {
720            new->sgml_input_text.passwd = XtNewString(value);
721            XtAddCallback(child, XmNmodifyVerifyCallback,(XtCallbackProc) check_passwd, (XtPointer) &new->sgml_input_text.passwd);
722         }
723       if (new->sgml_input_text.auto_submit)
724         {
725           for (form = (Widget) new ; form ; form = XtParent(form))
726             if (SGMLIsFormText(form))
727               {    
728                 XtAddCallback(child,XmNactivateCallback,(XtCallbackProc) Activate,(XtPointer) form);
729                 break;
730               }
731         }
732     }        
733   else if (type == TypeTextArea)
734     {
735       int rows  = new->sgml_input_text.rows;
736       int cols  = new->sgml_input_text.cols;
737       char *text = new->sgml_text.text;
738  
739       if (rows == 0) rows = 20;
740       if (cols == 0) cols = 20;
741  
742       XtSetArg(arglist[n],XmNeditMode,XmMULTI_LINE_EDIT); n++;
743       XtSetArg(arglist[n],XmNcolumns,cols); n++;
744       XtSetArg(arglist[n],XmNrows,rows); n++;
745       XtSetArg(arglist[n],XmNvalue,text); n++;
746       ichild = XmCreateScrolledText(parent,name,arglist,n);
747  
748       child = XtParent(ichild);  
749       XtUnmanageChild(child);
750       XtManageChild(ichild);
751     }        
752   else if (type == TypeImage)
753     {
754       Widget form;
755       XtSetArg(arglist[n],XmNlabelType,XmPIXMAP); n++;
756       XtSetArg(arglist[n],XmNmarginWidth,0); n++;
757       XtSetArg(arglist[n],XmNmarginHeight,0); n++;
758       XtSetArg(arglist[n],XmNlabelPixmap,new->sgml_input_text.bomb); n++;
759       ichild = child = XtCreateWidget(name,xmPushButtonWidgetClass,parent,arglist,n);
760  
761       n = 0;
762       XtSetArg(arglist[n],XmNshadowThickness,   &sT); n++;
763       XtSetArg(arglist[n],XmNhighlightThickness,&hT); n++;
764       XtSetArg(arglist[n],XmNmarginHeight,      &mH); n++;
765       XtSetArg(arglist[n],XmNmarginBottom,      &mB); n++;
766       XtGetValues(child,arglist,n);
767  
768       new->sgml_container_text.vertical_offset = -sT - hT - mH - mB - new->sgml_text.descent;  
769  
770       for (form = (Widget) new ; form ; form = XtParent(form))
771         if (SGMLIsFormText(form))
772           {    
773             XtAddCallback(child,XmNactivateCallback,(XtCallbackProc) ActivateImage,(XtPointer) form);
774             break;
775           }
776     }
777   else if (type == TypeOption)
778     {
779       option_selected = new->sgml_input_text.selected;
780       option_value = new->sgml_input_text.value;
781       child = ichild = NULL;
782     }
783   else if (type == TypeSelect)
784     {
785       char *text = XtNewString(new->sgml_text.text);
786       Boolean multiple = new->sgml_input_text.multiple;
787  
788       int nn=0;
789       Arg argl[10];
790  
791       Widget w;
792       Widget p = XtParent((Widget) new);
793  
794       XtSetArg(argl[nn],SGMLNuserdata,&w); nn++;
795       XtGetValues(p,argl,nn);
796       if (!w)
797         {
798           int size = new->sgml_input_text.size;
799           if (size > 1 || multiple)
800             {
801               if (size) { XtSetArg(arglist[n],XmNvisibleItemCount,size); n++; }
802               XtSetArg(arglist[n],XmNselectionPolicy,multiple?XmEXTENDED_SELECT:XmBROWSE_SELECT); n++;
803               w = ichild = XmCreateScrolledList(parent,name,arglist,n);
804  
805               n = 0;
806               XtSetArg(arglist[n],XmNshadowThickness,   &sT); n++;
807               XtSetArg(arglist[n],XmNhighlightThickness,&hT); n++;
808               XtSetArg(arglist[n],XmNlistMarginHeight,  &mH); n++;
809               XtGetValues(ichild,arglist,n);
810  
811               new->sgml_container_text.vertical_offset = -sT - hT - 2*mH - new->sgml_text.descent;  
812  
813               n = 0;
814               XtSetArg(arglist[n],SGMLNuserdata,w); n++;
815               XtSetValues(p,arglist,n);
816  
817               child = XtParent(ichild);  
818               XtUnmanageChild(child);
819               XtManageChild(ichild);          
820             }
821           else
822             {
823               Widget menu;
824               menu = XmCreatePulldownMenu(parent,name,arglist,n);
825  
826               XtSetArg(arglist[n],XmNlabelString,emptyLabel); n++;      
827               XtSetArg(arglist[n],XmNsubMenuId,menu); n++;
828               w = ichild = child = XmCreateOptionMenu(parent,name,arglist,n);
829  
830               n = 0;
831               XtSetArg(arglist[n],XmNshadowThickness,   &sT); n++;
832               XtSetArg(arglist[n],XmNmarginHeight,      &mH); n++;
833               XtGetValues(child,arglist,n);
834  
835               new->sgml_container_text.vertical_offset = -sT - 2*mH - new->sgml_text.descent;  
836  
837               n = 0;
838               XtSetArg(arglist[n],SGMLNuserdata,w); n++;
839               XtSetValues(p,arglist,n);
840              }
841         }
842       else ichild = child = 0;
843  
844       if (text && *text)
845         {
846           char *q, *p, *r = XtNewString(text);
847  
848           /* Strip off leading and trailing white-space */
849  
850           for (p = r; *p && isspace(*p); p++);
851           for (q = p + Strlen(p); q-- > p && isspace(*q); ) *q = '\0';
852  
853           if (option || *p)
854             {
855               XmString Text;
856               if (!*p) p   = "";
857               Text = XmStringCreateSimple(p);
858  
859               if (XtIsSubclass(w,xmListWidgetClass))
860                 {
861                   XmListAddItem(w,Text,0);
862                   if (option_selected)
863                     {
864                       int nsel, i;
865                       XmString *List, *NewList;
866                       n = 0;
867                       XtSetArg(arglist[n],XmNselectedItems,&List); n++;
868                       XtSetArg(arglist[n],XmNselectedItemCount,&nsel); n++;
869                       XtGetValues(w,arglist,n); n = 0;
870                       NewList = (XmString *) XtMalloc((nsel+1) * sizeof(XmString *));
871                       for (i = 0; i < nsel; i++) NewList[i] = List[i];
872                       NewList[nsel++] = Text;
873  
874                       XtSetArg(arglist[n],XmNselectedItems,NewList); n++;
875                       XtSetArg(arglist[n],XmNselectedItemCount,nsel); n++;
876                       XtSetValues(w,arglist,n);
877                       XtFree((char *) NewList);
878                     }
879                 }
880               else
881                 {
882                   Widget menu;
883                   n = 0;
884                   XtSetArg(arglist[n],XmNsubMenuId,&menu); n++;
885                   XtGetValues(w,arglist,n); n = 0;
886  
887                   XtSetArg(arglist[n],XmNlabelString,Text); n++;
888                   XtSetArg(arglist[n],XmNfontList,font); n++;  
889                   ichild = XtCreateManagedWidget(p,xmPushButtonWidgetClass,menu,arglist,n);
890                   if (option_selected)
891                     {
892                       n = 0;
893                       XtSetArg(arglist[n],XmNmenuHistory,ichild); n++;
894                       XtSetValues(w,arglist,n);
895                     }
896                 }
897               XmStringFree(Text);
898             }
899           if (option_value && *option_value)
900             {
901               XtFree(r);
902               new->sgml_input_text.value = XtNewString(option_value);
903             }
904           else new->sgml_input_text.value = p;
905         }        
906       new->sgml_input_text.selected = option_selected;
907       XtFree(text);
908     }
909   else if (type == TypeCheckbox)
910     {
911       Boolean set  = new->sgml_input_text.checked;
912       XtSetArg(arglist[n],XmNspacing,0); n++;
913       XtSetArg(arglist[n],XmNmarginBottom,0); n++;      
914       XtSetArg(arglist[n],XmNset,set); n++;
915       XtSetArg(arglist[n],XmNlabelString,emptyLabel); n++;
916  
917       ichild = child = XtCreateWidget(name,xmToggleButtonWidgetClass,parent,arglist,n);
918  
919       n = 0;
920       XtSetArg(arglist[n],XmNshadowThickness,   &sT); n++;
921       XtSetArg(arglist[n],XmNhighlightThickness,&hT); n++;
922       XtSetArg(arglist[n],XmNmarginHeight,      &mH); n++;
923       XtGetValues(child,arglist,n);
924  
925       new->sgml_container_text.vertical_offset = -sT - hT - mH - new->sgml_text.descent;  
926     }    
927   else if (type == TypeRadio)
928     {
929       Widget form;
930       Boolean set  = new->sgml_input_text.checked;
931  
932       XtSetArg(arglist[n],XmNset,set); n++;
933       XtSetArg(arglist[n],XmNindicatorType,XmONE_OF_MANY); n++;
934       XtSetArg(arglist[n],XmNlabelString,emptyLabel); n++;      
935       XtSetArg(arglist[n],XmNspacing,0); n++;
936       XtSetArg(arglist[n],XmNmarginWidth,0); n++;
937       XtSetArg(arglist[n],XmNmarginHeight,0); n++;
938       XtSetArg(arglist[n],XmNmarginLeft,0); n++;
939       XtSetArg(arglist[n],XmNmarginRight,0); n++;
940       XtSetArg(arglist[n],XmNmarginTop,0); n++;
941       XtSetArg(arglist[n],XmNmarginBottom,0); n++;
942  
943       ichild = child = XtCreateWidget(name,xmToggleButtonWidgetClass,parent,arglist,n);
944  
945       n = 0;
946       XtSetArg(arglist[n],XmNshadowThickness,   &sT); n++;
947       XtSetArg(arglist[n],XmNhighlightThickness,&hT); n++;
948       XtSetArg(arglist[n],XmNmarginHeight,      &mH); n++;
949       XtGetValues(child,arglist,n);
950  
951       new->sgml_container_text.vertical_offset = -sT - hT - mH - new->sgml_text.descent;  
952  
953       for (form = (Widget) new ; form ; form = XtParent(form))
954         if (SGMLIsFormText(form))
955           {    
956             XtAddCallback(child,XmNvalueChangedCallback,(XtCallbackProc) Radio, (XtPointer) form);
957             break;
958           }
959     }
960   else ichild = child = NULL;
961  
962   XmFontListFree(font);  
963  
964   new->sgml_container_text.child = child;
965   new->sgml_input_text.child = ichild;
966   if (new->sgml_input_text.image)  SetupImage(new);
967   option = (type == TypeOption);
968 }
969 /*--------------------------------------------------------------*/
970 /* Destroy the widget: release all memory allocated             */
971 /*--------------------------------------------------------------*/
972  
973 static void Destroy (w)
974 SGMLInputTextObject w;
975 {
976     XtFree(w->sgml_input_text.name);
977     XtFree(w->sgml_input_text.value);
978     XtFree(w->sgml_input_text.passwd);
979     if (w->sgml_input_text.image) GIFFreeFile(w->sgml_input_text.image);
980 }    
981  
982 /*------------------------------------------------------------------*/
983 /* SetValues :                                                      */
984 /*------------------------------------------------------------------*/
985  
986 static Boolean SetValues (current, request, new)
987 SGMLInputTextObject current, request, new;
988 {
989  
990 #define HAS_CHANGED(a)    (new->sgml_input_text.a != current->sgml_input_text.a)
991 #define REJECT(a) if HAS_CHANGED(a) new->sgml_input_text.a != current->sgml_input_text.a
992  
993     REJECT(name);
994     REJECT(value);
995     REJECT(passwd);
996     if (HAS_CHANGED(image))
997       {
998         SetupImage(new);
999         if (current->sgml_input_text.image) GIFFreeFile(current->sgml_input_text.image);
1000       }
1001 #undef HAS_CHANGED
1002 #undef REJECT
1003   return FALSE;
1004 }
1005 /*--------------------------------------------------------------*/
1006 /* Inherit Changes                                              */
1007 /*--------------------------------------------------------------*/
1008  
1009 static Boolean InheritChanges(w,inputMask)
1010 SGMLInputTextObject w;
1011 int inputMask;
1012 {
1013     if (inputMask & gcMask)
1014       {
1015         int n=0;
1016         Arg arglist[10];
1017         XmFontList font = XmFontListCreate(w->sgml_text.font,XmSTRING_DEFAULT_CHARSET);
1018  
1019         XtSetArg(arglist[n],XmNfontList,font); n++;  
1020         if (w->sgml_input_text.child) XtSetValues(w->sgml_input_text.child,arglist,n);
1021         XmFontListFree(font);        
1022       }
1023   return FALSE;
1024 }
1025 /*-----------------------------------------------------------------------*/
1026 /* Create a new SGMLInputTextObject                                      */
1027 /*-----------------------------------------------------------------------*/
1028  
1029 Widget SGMLCreateInputText(parent,name,al,ac)
1030 Widget parent;
1031 char   *name;
1032 ArgList al;
1033 int     ac;
1034 {
1035     return XtCreateWidget(name,sGMLInputTextObjectClass,parent,al,ac);
1036 }