home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-03-10 | 29.7 KB | 1,054 lines |
- /* Dialog box commands for tcl */
- /* (c) C.T.Stretch */
- /* Mon,08 Aug 1994 */
-
- #include "tclInt.h"
- #undef UCHAR
- #include "h.wimp"
- #include "h.WInt"
- #include "h.RISCOSint"
- #include "h.dragasprite"
-
- enum ictypes { IHLIST,IVLIST,IBOX,ISPRITE,ISAVE,IACTION,IDEFAULT,
- IINFO,IDISPLAY,IWATCH,IOPTION,IRADIO,IWRITE,ILAST};
- /*Note ictypes>ISAVE are equalised*/
- /*Note ictypes>IDEFAULT have 4? parameters*/
-
- typedef struct icdata
- { char *t; /*Name*/
- int w,h,n; /*Width, height, no. of icons*/
- } icdata;
-
- icdata icd[ILAST]=
- { {"hlist", 0 ,0 ,0},
- {"vlist", 0 ,0 ,0},
- {"box", 0 ,0 ,2},
- {"sprite", 100,100,1},
- {"save", 192,176,2},
- {"action", 28 ,60 ,1},
- {"default",44 ,76 ,1},
- {"info", 80 ,60 ,2},
- {"display",80 ,60 ,2},
- {"watch" ,80 ,60 ,2},
- {"option", 60 ,52 ,1},
- {"radio", 60 ,52 ,1},
- {"write", 80 ,68 ,2}
- };
-
- #define GAP 8
- #define HALFGAP (GAP/2)
- #define CHWIDTH 16
-
- enum actions { ANONE,AACTION,ADISPLAY,AWATCH,
- AOPTION,ARADIO1,ARADIO2,AWRITE,ADRAG};
-
- static wimp_window progInfo=
- { {0,0,0,0},
- 0, 0, (wimp_w)-1, 0x84000012,
- 0x7, 0x2, 0x7, 0x1,
- 0xc, 0xe, 0xc, 0x0,
- {0,0,0,0},
- 0x13d, 0x0, (osspriteop_area*)0x1, 0, 0,
- "",
- 0
- };
-
- #define TRACEFLAGS TCL_TRACE_WRITES|TCL_GLOBAL_ONLY
- #define BSIZE(n) ((int)sizeof(boxnode)+(n-1)*(int)sizeof(boxnode*))
- #define WSIZE(n) ((int)sizeof(wimp_window)+(n-1)*(int)sizeof(wimp_icon))
-
- typedef struct boxnode /* A node of the tree used to parse dbox descriptions */
- { int type; /* object type from enum ictypes */
- int w,h; /* width and height in os units */
- int n1,n2,n3,n4; /* integers describing object */
- char *s1,*s2,*s3; /* strings describing object */
- struct boxnode *blist[UNKNOWN]; /* subobjects */
- } boxnode;
-
- typedef struct dbox /* A permanent object describing a dbox */
- { wimp_window *ww; /* window template */
- int *t; /* list of action types */
- char **s; /* list of script strings */
- char *d; /* script for default icon */
- char *e; /* script for Cancel icon */
- bool tagged; /* TRUE for tagged dbox*/
- int c; /* icon to place caret (-1 for none)*/
- } dbox;
-
- typedef struct openbox /* A list of these describes the open dboxes */
- { struct openbox *next; /* linkedlist pointer */
- wimp_w w; /* window handle */
- char *tag; /* dbox tag */
- dbox *db; /* the dbox that this is an instance of */
- } openbox;
-
- typedef struct watchdata
- { struct watchdata *next;
- openbox *ob;
- int ic;
- } watchdata;
-
-
- Tcl_HashTable boxTable;
- static openbox *openboxlist;
- static watchdata *watchdatalist;
-
- /* variables that hold information about an icon drag */
- static char *dragleaf,*dragscript;
- static int dragtype;
- static openbox *dragopenbox;
-
- /* vertical position to open a permanent dbox. */
- static int offset=600;
-
- /*The remaining variables are used temporarily during dbox creation */
- static int nicons,inum;
- static int *dbt;
- static char **dbs;
- static char *dd,*ee;
- static char *esg[16];
- static int esg_first;
- static wimp_icon *nexticon;
- static int careticon;
-
- #define USFLAGS osspriteop_USER_AREA|osspriteop_NAME
- #define SSFLAGS osspriteop_NAME
-
- static char *update(ClientData,Tcl_Interp*,char*,char*,int);
-
- /*static void ckpfree(void *p) { fprintf(stderr,"free p=%p\n",p);ckfree(p);}*/
-
- /*
- * box_find --
- * Looks up the name of a dbox in the hash table.
- * Returns 0 if not found or a pointer to the structure.
- * Result is void* so the dbox structures need not be defined
- * outside this file.
- *
- * Results:
- * Returns a pointer to a dbox or 0.
- *
- * Side effects:
- * None.
- *
- */
-
- extern void *box_find(char *name)
- { Tcl_HashEntry *p;
- p=Tcl_FindHashEntry(&boxTable,name);
- if(!p) return 0;
- return Tcl_GetHashValue(p);
- }
-
- static void freebox(openbox *ob)
- { dbox *db=ob->db;
- int ni=db->ww->icon_count;
- int i;
- wimp_window *ww=db->ww;
- for(i=0;i<ni;i++) switch(db->t[i])
- { case AWATCH:{ watchdata *wd;
- for(wd=watchdatalist;wd;wd=wd->next) if(wd->ob==ob&&wd->ic==i)
- { Tcl_UntraceVar2(w_Interp,db->s[i],ob->tag,TRACEFLAGS,
- update,(ClientData)wd);
- unlink(&watchdatalist,wd);
- ckfree(wd);
- break; /* from for loop */
- }
- }
- /*Deliberate fall through*/
- case ADISPLAY:case AWRITE:
- ckfree(ww->icons[i].data.indirected_text.text);
- }
- wimp_delete_window(ob->w);
- unlink(&openboxlist,ob);
- ckfree(ob->tag);
- ckfree(ob);
- substr['d'-'a']=0;
- }
-
- /*
- * box_close --
- * Called after a close event is returned from wimp_poll.
- * If the window is a dialog box it is deleted and the openbox
- * structure is removed from the list.
-
- * Results:
- * Returns true if the window was a dialog box.
- *
- * Side effects:
- * None.
- *
- */
-
- bool box_close(void)
- { openbox *ob;
- for(ob=openboxlist;ob;ob=ob->next)
- if(ob->w==block.close.w)
- { freebox(ob);
- return TRUE;
- }
- return FALSE;
- }
-
- /*
- * closebox --
- * Deletes a dialog box after a user selection.
- * Removes it from the openbox list.
- * Disposes of any open menu.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- static void closebox(openbox *ob)
- { wimp_create_menu((wimp_menu*)-1,0,0);
- freebox(ob);
- }
-
- /*
- * getvars --
- * Scans the objects of an open dialog box and sets the corresponding
- * Tcl variables.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- static void getvars(openbox *ob)
- { int i,j;
- dbox *db=ob->db;
- int ni=db->ww->icon_count;
- wimp_window *ww=db->ww;
- substr['d'-'a']=ob->tag;
- for(i=0;i<ni;i++) switch(db->t[i])
- { case AOPTION:{ wimp_icon_state *wis=(wimp_icon_state*)█
- bool b;
- wis->w=ob->w;
- wis->i=i;
- wimp_get_icon_state(wis);
- b=wis->icon.flags&wimp_ICON_SELECTED;
- Tcl_SetVar2(w_Interp,db->s[i],ob->tag,
- (b)?"1":"0",TCL_GLOBAL_ONLY);
- break;
- }
- case ARADIO1:{ wimp_i *wi=(wimp_i*)█
- wimp_which_icon(ob->w,wi,0x003f0000,
- 0x00200000|(ww->icons[i].flags&0x000f0000));
- j=wi[0];
- if(j>0)
- Tcl_SetVar2(w_Interp,db->s[i],ob->tag,
- ww->icons[j].data.indirected_text.text,TCL_GLOBAL_ONLY);
- break;
- }
- case AWRITE:{ wimp_icon_state *wis=(wimp_icon_state*)█
- wis->w=ob->w;
- wis->i=i;
- wimp_get_icon_state(wis);
- Tcl_SetVar2(w_Interp,db->s[i],ob->tag,
- wis->icon.data.indirected_text.text,TCL_GLOBAL_ONLY);
- break;
- }
- }
- }
-
- /*
- * box_key --
- * Called after a key event is returned by wimp_poll.
- * If the window is an open dialog box it takes the relevant action.
- *
- * Results:
- * Returns TRUE if the window was a dbox and key dealt with.
- *
- * Side effects:
- * None.
- *
- */
-
- bool box_key(void)
- { openbox *ob;
- char *s;
- for(ob=openboxlist;ob;ob=ob->next)
- if(ob->w==block.key.w) switch(block.key.c)
- { case 13:s=ob->db->d;goto run ;
- case 27:s=ob->db->e;goto run;
- default:return FALSE;
- }
- run:if(s)
- { getvars(ob);
- sprintf(substr['b'-'a'],"s");
- checkEval(s,"key action");
- if(!strcmp(w_Interp->result,"0")) closebox(ob);
- }
- return TRUE;
- }
-
- /*
- * box_click --
- * Called after a mouse (except menu) event is returned by wimp_poll.
- * If the window is an open dialog box it takes the relevant action.
- * For a drag event is starts a sprite drag, it sets the variables
- * dragtype, dragscript, dragleaf and dragopenbox.
- *
- * Results:
- * Returns TRUE if the window was a dbox.
- *
- * Side effects:
- * None.
- *
- */
-
- extern bool box_click(void)
- { openbox *ob;
- dbox *db;
- for(ob=openboxlist;ob;ob=ob->next)
- if(ob->w==block.pointer.w)
- { wimp_i ic=block.pointer.i;
- wimp_window *ww;
- db=ob->db;
- if(block.pointer.buttons==wimp_DRAG_SELECT) switch(db->t[ic])
- { case ADRAG:{ os_box sbox;
- wimp_window_state state[1];
- wimp_icon_state *wis=(wimp_icon_state*)█
- char *s;
- ww=db->ww;
- state->w=ob->w;
- wimp_get_window_state(state);
- sbox.x0=state->visible.x0+ww->icons[ic].extent.x0;
- sbox.x1=sbox.x0+68;
- sbox.y0=state->visible.y1+ww->icons[ic].extent.y0;
- sbox.y1=sbox.y0+68;
- dragasprite_start(
- dragasprite_HPOS_CENTRE|dragasprite_VPOS_CENTRE|
- dragasprite_BOUND_POINTER|dragasprite_DROP_SHADOW,
- (osspriteop_area*)1,
- ww->icons[ic].data.indirected_text.text,&sbox,0);
- wis->w=ob->w;
- wis->i=ic;
- wimp_get_icon_state(wis);
- dragtype=
- (int)strtol(wis->icon.data.indirected_text.text+5,0,16);
- wis->w=ob->w;
- wis->i=ic+1;
- wimp_get_icon_state(wis);
- dragleaf=wis->icon.data.indirected_text.text;
- s=strrchr(dragleaf,'.');
- if(s) dragleaf=s+1;
- dragscript=db->s[ic];
- dragopenbox=ob;
- }
- }
- else switch(db->t[ic])
- { case AACTION:if(db->s[ic]==0) closebox(ob);
- else
- { setbutton();
- getvars(ob);
- checkEval(db->s[ic],"action button");
- if(getconstant(w_Interp->result)==0) closebox(ob);
- }
- break;
- }
- return TRUE;
- }
- return FALSE;
- }
-
- /*
- * box_dragged --
- * Called after a user_drag_box event is returned from wimp_poll
- * sends a data_save message to the window under the ponter.
- * Stops the sprite drag.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- void box_dragged(void)
- { wimp_pointer wp[1];
- wimp_message wm;
- if(!dragscript) return;
- dragasprite_stop();
- wimp_get_pointer_info(wp);
- if(!wp->w) return;
- wm.size=256;
- wm.your_ref=0;
- wm.action=message_DATA_SAVE;
- wm.data.data_xfer.w=wp->w;
- wm.data.data_xfer.i=wp->i;
- wm.data.data_xfer.pos=wp->pos;
- wm.data.data_xfer.est_size=0;
- wm.data.data_xfer.file_type=dragtype;
- sprintf(wm.data.data_xfer.file_name,dragleaf);
- wimp_send_message_to_window(wimp_USER_MESSAGE_RECORDED,&wm,wp->w,wp->i);
- }
-
- /*
- * box_dragsave --
- * Called after the receipt of a data_save_acknowledge message.
- * Sets the variables from dragopenbox.
- * Sets w_file and the %t substitution.
- * Evaluates dragscript.
- * If dragscript indicates success returns a data_load message.
- * If the script indicates closes the dbox
- * Zeros dragopenbox and dragscript to avoid possible confusion
- * from spurious messages.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- void box_dragsave(wimp_message *m)
- { wimp_message_data_xfer *dx=&(m->data.data_xfer);
- wimp_message wm;
- wimp_t from=m->sender;
- int res;
- wm.size=256;
- wm.your_ref=m->my_ref;
- wm.action=message_DATA_LOAD;
- wm.data.data_xfer=m->data.data_xfer;
- if(!dragscript) return;
- if(dragopenbox) getvars(dragopenbox);
- Tcl_SetVar2(w_Interp,"w_file",0,dx->file_name,TCL_GLOBAL_ONLY);
- sprintf(substr['t'-'a'],"%d",dx->file_type);
- checkEval(dragscript,"save drag");
- dragscript=0;
- res=getconstant(w_Interp->result);
- if(res<'2') wimp_send_message(wimp_USER_MESSAGE_RECORDED,&wm,from);
- if(!(res&1)&&dragopenbox) closebox(dragopenbox);
- dragopenbox=0;
- }
-
- /*
- * box_dragload --
- * Called in response to a wimp_dataload message.
- * If the message is to a writeable icon in a dbox it copies the
- * file name into the icon if it fits.
- *
- * Results:
- * TRUE if the message was to a dbox.
- *
- * Side effects:
- * None.
- *
- */
-
- bool box_dragload(wimp_message *m)
- { openbox *ob;
- wimp_message_data_xfer *dx=&(m->data.data_xfer);
- for(ob=openboxlist;ob;ob=ob->next)
- if(ob->w==dx->w)
- { wimp_i ic=dx->i;
- dbox *db=ob->db;
- wimp_window *ww=db->ww;
- if(ic>=0&&db->t[ic]==AWRITE)
- { int n=ww->icons[ic].data.indirected_text.size;
- char *t=ww->icons[ic].data.indirected_text.text;
- if(n>strlen(dx->file_name))
- { strcpy(t,dx->file_name);
- wimp_set_icon_state(dx->w,ic,0,0);
- }
- }
- return TRUE;
- }
- return FALSE;
- }
-
- /*
- * freeboxtree --
- * Frees the boxtree after a dbox has been created.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- static void freeboxtree(boxnode *bn)
- { int i;
- switch(bn->type)
- { case IHLIST:
- case IVLIST:for(i=0;i<bn->n1;i++) freeboxtree(bn->blist[i]);
- break;
- case IBOX:freeboxtree(bn->blist[0]);
- break;
- }
- ckfree(bn);
- }
-
- /*
- * equalize --
- * Scans a vertical or horizontal list node in the box tree.
- * If consecutive objects of the same type are found their sizes
- * are set to the maximum. Objects of type HLIST VLIST BOX and SPRITE
- * are not considered, and are ignored when considering consecutiveness.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- static void equalize(boxnode *bn,int n)
- { int i,j,k,gtype,n1,n2,n3=-1;
- boxnode *gn;
- for(i=0;i<n;i++)
- { gn=bn->blist[i];
- if(gn->type>ISAVE)
- { if(gn->type==gtype)
- { if(gn->n1>n1) { n1=gn->n1;for(j=k;j<i;j++) bn->blist[j]->n1=n1;}
- else gn->n1=n1;
- if(gn->n2>n2) { n2=gn->n2;for(j=k;j<i;j++) bn->blist[j]->n2=n2;}
- else gn->n2=n2;
- if(gn->n3>n3) { n3=gn->n3;for(j=k;j<i;j++) bn->blist[j]->n3=n3;}
- else gn->n2=n2;
- }
- else
- { gtype=gn->type;
- n1=gn->n1;n2=gn->n2;n3=gn->n3;
- k=i;
- }
- }
- }
- }
-
- /*
- * getboxtree --
- * The construction of a dbox from a textual description proceeds
- * in two stages. First a tree structure is constructed from the
- * text. This is then used to make a dbox structure, including a
- * window template with icon descriptions. This recursive procedure
- * creates the boxtree.
- *
- * Results:
- * Returns a node of a box tree or zero for error.
- *
- * Side effects:
- * Uses some temporary global variables.
- *
- */
-
- static boxnode *getboxtree(char *desc)
- { boxnode *bn,*gn;
- int nargs,i,type;
- char **args;
- if(Tcl_SplitList(w_Interp,desc,&nargs,&args)) return 0;
- if(nargs<2) return wrong0(WNA,"<component> ...");
- for(type=0;type<ILAST;type++) if(!strcmp(args[0],icd[type].t))break;
- if(type>=ILAST) return wrong0("Unknown dbox component: ",args[0]);
- switch(type)
- { case IHLIST:
- case IVLIST:bn=ckalloc(BSIZE(nargs-1));
- bn->n1=nargs-1;
- for(i=0;i<nargs-1;i++)
- { bn->blist[i]=getboxtree(args[i+1]);
- if(bn->blist[i]==0) return wrong0("empty vlist",0);
- bn->w=0;bn->h=0;
- }
- break;
- case IBOX:if(nargs!=3) return wrong0(WNA,"box <name> <component>");
- bn=ckalloc(BSIZE(1));
- bn->s1=scopy(args[1]);
- bn->n1=strlen(bn->s1);
- bn->blist[0]=getboxtree(args[2]);
- if(bn->blist[0]==0) return wrong0("empty hlist",0);
- bn->w=64+bn->blist[0]->w;
- bn->h=72+bn->blist[0]->h;
- if(bn->n1*CHWIDTH+80>bn->w) bn->w=bn->n1*CHWIDTH+80;
- break;
- case ISPRITE:bn=ckalloc(BSIZE(0));
- bn->s1=scopy(args[1]);
- bn->n1=(int)spriteinfo(bn->s1,&(bn->w),&(bn->h),TRUE);
- if(bn->n1==0) bn->n1=1;
- bn->w+=GAP;
- bn->h+=GAP;
- break;
- case ISAVE:if(nargs!=4)
- return wrong0(WNA,"save <filetype> <variable> <script>");
- bn=ckalloc(BSIZE(0));
- bn->n1=typenumber(args[1]);
- if(bn->n1>=0&&bn->n1<4096)
- { bn->s1=ckalloc(9);
- sprintf(bn->s1,"file_%03.3x",bn->n1);
- }
- else
- { char *s="file_xxx";
- if(bn->n1==0x1000) s="directory";
- if(bn->n1==0x2000) s="application";
- bn->s1=scopy(s);
- }
- bn->s2=scopy(args[2]);
- bn->s3=scopy(args[3]);
- bn->w=192;
- bn->h=176;
- break;
- default:bn=ckalloc(BSIZE(0));
- if(nargs<3&&type>IDEFAULT)
- return wrong0("Component requires more arguments: ",args[0]);
- bn->n1=strlen(args[1]);
- bn->n2=0;bn->n3=0;bn->n4=0;
- bn->s1=scopy(args[1]);
- bn->s2=(nargs==2)?0:scopy(args[2]);
- bn->s3=0;
- bn->h=icd[type].h;
- }
- nicons+=icd[type].n;
- bn->type=type;
- switch(type)
- { case IHLIST:equalize(bn,nargs-1);
- for(i=0;i<nargs-1;i++)
- { gn=bn->blist[i];
- if(gn->type>ISAVE)
- gn->w=icd[gn->type].w+(gn->n1+gn->n2+gn->n3)*CHWIDTH;
- bn->w+=gn->w;
- if(gn->h>bn->h) bn->h=gn->h;
- }
- break;
- case IVLIST:equalize(bn,nargs-1);
- for(i=0;i<nargs-1;i++)
- { gn=bn->blist[i];
- if(gn->type>ISAVE)
- gn->w=icd[gn->type].w+(gn->n1+gn->n2+gn->n3)*CHWIDTH;
- bn->h+=gn->h;
- if(gn->w>bn->w) bn->w=gn->w;
- }
- break;
- case IINFO:bn->n2=strlen(args[2]);
- break;
- case IDISPLAY:if(nargs>3) bn->n2=atoi(args[3]);
- if(bn->n2<1) bn->n2=20;
- break;
- case IWRITE:case IWATCH:
- if(nargs>3) bn->n2=atoi(args[3]);
- if(nargs>4) bn->n4=atoi(args[4]);
- if(bn->n2<1) bn->n2=20;
- if(bn->n4<1) bn->n4=256;
- break;
- }
- if(type>ISAVE) bn->w=icd[type].w+(bn->n1+bn->n2+bn->n3)*CHWIDTH;
- return bn;
- }
-
- /*
- * puticon --
- * Sets the size and flags of an icon. Increments nexticon to point
- * to the space for the next icon's data. Increments the count of
- * icons in the box.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- static void puticon(bits flags,int x0,int x1,int y0,int y1)
- { nexticon->extent.x0=x0;
- nexticon->extent.x1=x1;
- nexticon->extent.y1=-y1;
- nexticon->extent.y0=-y0;
- nexticon->flags=flags;
- nexticon++;inum++;
- }
-
- /*
- * setind --
- * Sets the indirected icon data
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- static void setind(char *t,char *v,int s)
- { nexticon->data.indirected_text.text=t;
- nexticon->data.indirected_text.validation=v;
- nexticon->data.indirected_text.size=s;
- }
-
- /*
- * group --
- * Determines the esg of a radio button icon from its variable name
- *
- * Results:
- * An esg number.
- *
- * Side effects:
- * If this is the first use of this radio button variable name
- * in this dbox the name is stored in esg[esgnumber]. The fact
- * that this was first is stored in esg_first.
- *
- */
-
- static bits group(char *s)
- { bits i;
- for(i=1;i<16;i++)
- { if(esg[i]==0) { esg[i]=s;esg_first=ARADIO1;break;}
- if(!strcmp(s,esg[i])) { esg_first=ARADIO2;break;}
- }
- if(i>15) i=15;
- return i<<wimp_ICON_ESG_SHIFT;
- }
-
- /*
- * seticons --
- * Adds the icon definitions to a dbox template.
- * adds the action data for the icons to dbt and dbs.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Uses some temporary global variables.
- *
- */
-
- static void seticons(boxnode *bn,int w,int h,int in,int dn)
- { int i,xg,yg,out,type=bn->type;
- bits g;
- xg=w-bn->w;
- yg=h-bn->h;
- switch(type)
- { case IHLIST:xg=xg/(bn->n1+1);
- for(i=0;i<bn->n1;i++)
- { in+=xg;
- seticons(bn->blist[i],bn->blist[i]->w,h,in,dn);
- in+=bn->blist[i]->w;
- }
- break;
- case IVLIST:yg=yg/(bn->n1+1);
- for(i=0;i<bn->n1;i++)
- { dn+=yg;
- seticons(bn->blist[i],w,bn->blist[i]->h,in,dn);
- dn+=bn->blist[i]->h;
- }
- break;
- case IBOX:in+=xg/2+16;dn+=yg/2+24;
- setind("","R4",0);
- out=in+bn->w-32;
- puticon(0x1700011D,in,out,dn+bn->h-32,dn);
- setind(bn->s1,(char*)-1,bn->n1);
- out=in+48+CHWIDTH*bn->n1;
- puticon(0x17000139,in+32,out,dn+24,dn-20);
- seticons(bn->blist[0],bn->w-64,bn->h-72,in+16,dn+32);
- break;
- case ISPRITE:in+=xg/2;dn+=yg/2;
- setind(bn->s1,(char*)(bn->n1),strlen(bn->s1));
- puticon(0x1700013a,in,in+bn->w,dn+bn->h,dn);
- break;
- case ISAVE:in+=xg/2;dn+=yg/2;
- dbt[inum]=ADRAG;dbs[inum]=bn->s3;
- setind(bn->s1,(char*)1,strlen(bn->s1)+1);
- puticon(0x1700613a,in+62,in+130,dn+76,dn+8);
- dbt[inum]=AWRITE;dbs[inum]=bn->s2;
- if(careticon<0) careticon=inum;
- setind(0,"A~ ;Kta;Pptr_write",256);
- puticon(0x0700f13d,in+8,in+184,dn+144,dn+92);
- break;
- case IINFO:case IDISPLAY:case IWATCH:
- in+=xg/2+HALFGAP;dn+=yg/2+HALFGAP;
- setind(bn->s1,0,bn->n1);
- out=in+CHWIDTH*bn->n1+32;
- puticon(0x17000311,in,out,dn+icd[type].h-GAP,dn);
- in=out+GAP;
- if(type==IDISPLAY) {dbt[inum]=ADISPLAY;dbs[inum]=bn->s2;}
- if(type==IWATCH) {dbt[inum]=AWATCH;dbs[inum]=bn->s2;}
- setind(bn->s2,"R2",(type==IWATCH)?bn->n4:bn->n2);
- out=in+CHWIDTH*bn->n2+32;
- puticon(0x1700013d,in,out,dn+icd[type].h-GAP,dn);
- break;
- case IDEFAULT:dd=bn->s2;/*Deliberate fall through*/
- case IACTION:if(!strcmp(bn->s1,"Cancel")) ee=bn->s2;
- in+=xg/2+HALFGAP;dn+=yg/2+HALFGAP;
- setind(bn->s1,(type==IACTION)?"R5.3":"R6,3",bn->n1);
- dbt[inum]=AACTION;dbs[inum]=bn->s2;
- out=in+CHWIDTH*bn->n1+32;
- puticon((type==IACTION)?0x1702313d:0x170f313d,
- in,out,dn+icd[type].h-GAP,dn);
- break;
- case IOPTION:in+=xg/2+HALFGAP;dn+=yg/2+HALFGAP;
- setind(bn->s1,"soptoff,opton",bn->n1);
- dbt[inum]=AOPTION;dbs[inum]=bn->s2;
- out=in+CHWIDTH*bn->n1+52;
- puticon(0x1720b113,in,out,dn+icd[type].h-GAP,dn);
- break;
- case IRADIO:in+=xg/2+HALFGAP;dn+=yg/2+HALFGAP;
- setind(bn->s1,"sradiooff,radioon",bn->n1);
- g=group(bn->s2);
- dbt[inum]=esg_first;dbs[inum]=bn->s2;
- out=in+CHWIDTH*bn->n1+52;
- puticon(0x1720b113|g,in,out,dn+icd[type].h-GAP,dn);
- break;
- case IWRITE:in+=xg/2+HALFGAP;dn+=yg/2+HALFGAP;
- setind(bn->s1,0,bn->n1);
- out=in+CHWIDTH*bn->n1+32;
- puticon(0x17000311,in,out,dn+icd[type].h-GAP,dn);
- in=out+GAP;
- dbt[inum]=AWRITE;dbs[inum]=bn->s2;
- if(careticon<0) careticon=inum;
- setind(0,"Kta;Pptr_write",bn->n4);
- out=in+CHWIDTH*bn->n2+32;
- puticon(0x0700f13d,in,out,dn+icd[type].h-GAP,dn);
- break;
- }
- }
-
- /*
- * makedbox --
- * Creates a dbox structure from a box tree.
- *
- * Results:
- * Returns a dbox pointer or zero for error
- *
- * Side effects:
- * Uses some temporary global variables.
- *
- */
-
- static dbox *makedbox(boxnode *bn)
- { dbox *db=ckcalloc(sizeof(dbox));
- wimp_window *ww=ckalloc(WSIZE(nicons));
- int x,y;
- screensize(&x,&y);
- db->t=ckcalloc(nicons*sizeof(int));
- db->s=ckcalloc(nicons*sizeof(char*));
- dbt=db->t;dbs=db->s;dd=0;ee=0;
- careticon=-1;
- inum=0;
- *ww=progInfo;
- if(bn->w>1600||bn->h>1200)
- { sprintf(w_Interp->result,
- "dbox too large %d x %d",bn->w,bn->h);
- return 0;
- }
- ww->visible.x0=(x-bn->w)/2;
- if(offset>y-INSET) offset=y-INSET;
- offset-=bn->h+40;
- if(offset<INSET) offset=y-INSET-bn->h;
- ww->visible.y0=offset;
- ww->visible.x1=ww->visible.x0+bn->w;
- ww->visible.y1=ww->visible.y0+bn->h;
- ww->extent.x1=bn->w;
- ww->extent.y0=-bn->h;
- ww->icon_count=nicons;
- db->ww=ww;
- nexticon=db->ww->icons;
- seticons(bn,bn->w,bn->h,0,0);
- db->d=dd;db->e=ee;db->c=careticon;
- return db;
- }
-
- /*
- * update --
- * Called by a variable trace to update a watch icon
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- static char *update(ClientData d,Tcl_Interp *interp,char *n1,char *n2,int flags)
- { char *v=Tcl_GetVar2(interp,n1,n2,flags&TCL_GLOBAL_ONLY);
- char *t;
- int n;
- wimp_icon_state *wis=(wimp_icon_state*)█
- wis->w=((watchdata*)d)->ob->w;
- wis->i=((watchdata*)d)->ic;
- wimp_get_icon_state(wis);
- t=wis->icon.data.indirected_text.text;
- n=wis->icon.data.indirected_text.size;
- if(v) strncpy(t,v,n);else t[0]=0;
- t[n-1]=0;
- wimp_set_icon_state(wis->w,wis->i,0,0);
- return 0;
- }
-
- /*
- * box_fillin --
- * Sets the dialog box fields corresponding to Tcl variables
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- static void box_fillin(dbox *db,char *tag,openbox *ob)
- { wimp_window *ww=db->ww;
- int ni=ww->icon_count;
- int i,n;
- bool truth;
- char *s,*t;
- for(i=0;i<ni;i++) switch(db->t[i])
- { case ADISPLAY:s=Tcl_GetVar2(w_Interp,db->s[i],tag,TCL_GLOBAL_ONLY);
- if(!s) s="";
- ww->icons[i].data.indirected_text.text=scopy(s);
- break;
- case AOPTION:s=Tcl_GetVar2(w_Interp,db->s[i],tag,TCL_GLOBAL_ONLY);
- if(!s) truth=FALSE;
- else truth=strcmp(s,"0");
- if(truth) ww->icons[i].flags|=wimp_ICON_SELECTED;
- else ww->icons[i].flags&=~wimp_ICON_SELECTED;
- break;
- case ARADIO1:case ARADIO2:
- s=Tcl_GetVar2(w_Interp,db->s[i],tag,TCL_GLOBAL_ONLY);
- if(!s) truth=FALSE;
- else truth=!strcmp(s,ww->icons[i].data.indirected_text.text);
- if(truth) ww->icons[i].flags|=wimp_ICON_SELECTED;
- else ww->icons[i].flags&=~wimp_ICON_SELECTED;
- break;
- case AWATCH:{ watchdata *wd=ckalloc(sizeof(struct watchdata));
- wd->next=watchdatalist;
- watchdatalist=wd;
- wd->ob=ob;
- wd->ic=i;
- Tcl_TraceVar2(w_Interp,db->s[i],tag,
- TRACEFLAGS,update,(ClientData)wd);
- }
- /*Deliberate fall through*/
- case AWRITE:n=ww->icons[i].data.indirected_text.size;
- t=ckalloc(n);
- ww->icons[i].data.indirected_text.text=t;
- s=Tcl_GetVar2(w_Interp,db->s[i],tag,TCL_GLOBAL_ONLY);
- if(s) strncpy(t,s,n);else t[0]=0;
- t[n-1]=0;
- break;
- }
- }
-
- /*
- * box_submenu --
- * Opens a transient dbox
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- extern void box_submenu(void *d,char *tag,int x,int y)
- { openbox *ob=ckalloc(sizeof(openbox));
- dbox *db=d;
- if(!db->tagged) tag=0;
- if(tag) tag=scopy(tag);
- box_fillin(db,tag,ob);
- if(xwimp_create_window(db->ww,&(ob->w))) return;
- ob->tag=tag;
- ob->db=db;
- ob->next=openboxlist;
- openboxlist=ob;
- block.open.w=ob->w;
- wimp_create_sub_menu((wimp_menu*)ob->w,x,y);
- }
-
- /*
- * box_open --
- * Implements the w_box <name> open command
- *
- * Results:
- * A standard Tcl result
- *
- * Side effects:
- * None.
- *
- */
-
- static int box_open(void *d,char *tag)
- { openbox *ob=ckalloc(sizeof(openbox));
- dbox* db=d;
- box_fillin(db,tag,ob);
- if(xwimp_create_window(db->ww,&(ob->w)))
- return wrong("Unable to create window",0);
- ob->tag=tag;
- ob->db=db;
- ob->next=openboxlist;
- openboxlist=ob;
- block.open.w=ob->w;
- wimp_get_window_state((wimp_window_state*)&block);
- wimp_open_window((wimp_open*)&block);
- if(db->c>=0) wimp_set_caret_position(ob->w,db->c,0,0,-1,1000);
- return TCL_OK;
- }
-
- /*
- * w_BoxCmd --
- * Implements the Tcl w_box command
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * Creating a box uses various temporary global variables
- *
- */
-
- int w_BoxCmd(ClientData dummy,Tcl_Interp *interp,int argc,char **argv)
- { dbox *db;
- Tcl_HashEntry *p;
- if(argc<3) return wrong(WNA,"w_box <name> <command> ...");
- /* *********** create a dbox *************** */
- if(!strcmp(argv[2],"create"))
- { boxnode *bn;
- int new;
- if(argc!=5&&(argc!=6||strcmp(argv[5],"-tag")))
- return wrong(WNA,"w_box <name> create <title> <component> ?-tag?");
- nicons=0;
- for(new=0;new<16;new++) esg[new]=0;
- bn=getboxtree(argv[4]);
- if(nicons==0) return wrong("dbox has no icons",0);
- if(!bn) return TCL_ERROR;
- db=makedbox(bn);
- if(db==0) return TCL_ERROR;
- freeboxtree(bn);
- db->tagged=(argc==6);
- db->ww->title_data.indirected_text.text=scopy(argv[3]);
- db->ww->title_data.indirected_text.validation=(char*)-1;
- db->ww->title_data.indirected_text.size=strlen(argv[3]);
- p=Tcl_CreateHashEntry(&boxTable,argv[1],&new);
- if(!new)
- { Tcl_AppendResult(interp,"box already exists ",argv[1],0);
- return TCL_ERROR;
- }
- Tcl_SetHashValue(p,db);
- return TCL_OK;
- }
- p=Tcl_FindHashEntry(&boxTable,argv[1]);
- if(!p) return wrong("No such dbox",argv[1]);
- db=(dbox*)Tcl_GetHashValue(p);
- /* *********** open a persistent dbox *************** */
- if(!strcmp(argv[2],"open")) return box_open(db,(argc>3)?scopy(argv[3]):0);
- return wrong("unknown w_box command",argv[2]);
- }
-
-
-
-