home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-03-21 | 24.8 KB | 1,019 lines |
- /* Wimp commands for tcl */
- /* (c) C.T.Stretch */
- /* Sat,25 Jun 1994 */
-
- #include "h.WInt"
- #include "h.osbyte"
- #include "h.taskwindow"
- #include "h.taskmanager"
- #include "h.RISCOSint"
-
- /* Return value from catch if a send script returns an error */
-
- #define TCL_REMOTEERROR 5
-
- /* Message numbers for the Tcl w_send protocol */
-
- #define message_TCL_SCRIPT 0x4cd40
- #define message_TCL_RESULT 0x4cd41
-
-
- /* The content of the messsages */
-
- typedef struct wimp_message_tcl
- { char *source;
- int len;
- int resultcode;
- } wimp_message_tcl;
-
- /* A list of these holds the scripts to be run on null events */
-
- typedef struct nullscript
- { struct nullscript *next;
- os_t when;
- char *name;
- char *script;
- } nullscript;
-
- char progname[PNSIZE+1]; /* Program name passed to w_Init */
- Tcl_Interp *w_Interp; /* The interpreter used by all w_ commands */
- wimp_block block; /* Block used when calling wimp SWIs */
- char *substr[26]; /* Points to the % substitution strings*/
- char subbuffer[128]; /* Holds the values of % substitutions*/
- int current_ex,current_ey; /* Mode information */
- wimp_t taskhandle;
-
- static int wimpmessages[]={ message_DATA_LOAD,
- message_DATA_SAVE_ACK,
- message_MENU_WARNING,
- message_TASK_WINDOW_OUTPUT,
- message_TASK_WINDOW_EGO,
- message_TASK_WINDOW_MORIO,
- message_TASK_WINDOW_NEW_TASK,
- message_MODE_CHANGE,
- message_PALETTE_CHANGE,
- message_TCL_SCRIPT,
- message_TCL_RESULT,
- 0 };
-
-
- static bits mask=wimp_MASK_NULL;
- static char *iconbar_clickproc,*iconbar_dragproc; /* tcl scripts */
- static int fontcount[256]; /* usage count of fonts */
- static osspriteop_area *userarea;
- static nullscript* nullscripts; /* The list of nullscripts */
- static os_t nulltime; /* Time for next null event */
- /*
- * msg --
- *
- * Reports an error consisting of at most three strings in a wimp
- * error box. The strings are concatenated and truncated to 250
- * characters.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- void msg(char *s1,char *s2,char *s3)
- { os_error e;
- int n=0;
- e.errnum=0;
- if(s1&&n<250) n+=sprintf(e.errmess,"%.*s",250-n,s1);
- if(s2&&n<250) n+=sprintf(e.errmess+n,"%.*s",250-n,s2);
- if(s2&&n<250) n+=sprintf(e.errmess+n,"%.*s",250-n,s3);
- wimp_report_error(&e,wimp_ERROR_BOX_OK_ICON,progname);
- }
-
- /*
- * wrong --
- *
- * Appends one or two strings to the result
- *
- * Results:
- * Returns TCL_ERROR.
- *
- * Side effects:
- * Changes w_Interp->result
- *
- */
-
- int wrong(char *m1,char *m2)
- { Tcl_AppendResult(w_Interp,m1,m2,0);
- return TCL_ERROR;
- }
-
- /*
- * wrong0 --
- *
- * Appends one or two strings to the result
- *
- * Results:
- * Returns 0.
- *
- * Side effects:
- * Changes w_Interp->result
- *
- */
-
- void *wrong0(char *m1,char *m2)
- { Tcl_AppendResult(w_Interp,m1,m2,0);
- return 0;
- }
-
- /*
- * spriteinfo --
- * Finds the sprite area and size of a named sprite
- * in os units if os is TRUE, otherwise pixels.
- *
- * Results:
- * Copies the size into xx and yy.
- * Returns a sprite area pointer, 1 for the wimp area, 0 for not found.
- *
- * Side effects:
- * None.
- *
- */
-
- osspriteop_area *spriteinfo(char *s,int *xx,int *yy,bool os)
- { int x=68,y=68,ex=0,ey=0;
- os_mode m;
- osspriteop_area *area=0;
- if(userarea&&
- !xosspriteop_read_sprite_size(
- osspriteop_USER_AREA,userarea,(osspriteop_id)s,&x,&y,0,&m))
- area=userarea;
- else
- if(!xwimpspriteop_read_sprite_size(s,&x,&y,0,&m)) area=(osspriteop_area*)1;
- if(area&&os)
- { os_read_mode_variable(m,os_MODEVAR_XEIG_FACTOR,&ex);
- os_read_mode_variable(m,os_MODEVAR_YEIG_FACTOR,&ey);
- *xx=x<<ex;
- *yy=y<<ey;
- }
- else
- { *xx=x;
- *yy=y;
- }
- return area;
- }
-
- /*
- * modeinfo --
- * Reads mode iformation for the currrent mode.
- *
- * Results:
- * Sets current_ex and current_ey.
- *
- * Side effects:
- * None.
- *
- */
-
- void modeinfo(void)
- { os_read_mode_variable(os_CURRENT_MODE,os_MODEVAR_XEIG_FACTOR,¤t_ex);
- os_read_mode_variable(os_CURRENT_MODE,os_MODEVAR_YEIG_FACTOR,¤t_ey);
- }
-
- /*
- * find_font --
- *
- * Searches for a font. The name is given in the form
- * <font> = f<name>?@<length>? or F<fontname>?@<length>?
- * If the length is not given the size is taken from the
- * variable size in 16ths of a point.
- * If the font cannot be found Trinity.Medium is used at the
- * required size. If this cannot be found 0 is returned.
- * The boolean table t records the fonts used in a particular document
- * or drawfile, so that they can be lost when it is closed.
- * The array fontcount holds the number of such tables keeping
- * a particular font.
- *
- * Results:
- * Returns a font handle or 0.
- *
- * Side effects:
- * May open a font. If it does and t->used[handle] is zero it sets
- * t->used[handle] to 1 and increments fontcount[handle]. Otherwise
- * it loses the font again, so that the program only contributes
- * use 1 to the *fontlist table.
- *
- */
-
- font_f find_font(char *name,int size,font_table *t)
- { font_f fontf;
- char *fname;
- char *p=strchr(name,'@');
- if(p)
- { size=getsize(p+1,16*72);
- *p=0; /* Terminates the font name temporarily */
- }
- switch(*name)
- { case 'f':fname=Tcl_GetVar2(w_Interp,"fonts",name+1,TCL_GLOBAL_ONLY);
- break;
- case 'F':fname=name+1;
- break;
- default:fname=0;
- }
- if(!fname||xfont_find_font(fname,size,size,0,0,&fontf,0,0))
- { if(xfont_find_font("Trinity.Medium",size,size,0,0,&fontf,0,0))
- fontf=0;
- }
- if(fontf)
- { if(t->used[fontf]) font_lose_font(fontf);
- else
- { t->used[fontf]=1;
- if(fontcount[fontf]>0) font_lose_font(fontf);
- fontcount[fontf]++;
- }
- }
- if(p) *p='@'; /* Restores the size part of the name */
- return fontf;
- }
-
- /*
- * wimp_losefont --
- *
- * Reduces the number of documents using a font.
- * If it becomes zero lose the font.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Decrements fontcount[fontf]. May lose a font.
- *
- */
-
- static void wimp_losefont(font_f fontf)
- { fontcount[fontf]--;
- if(fontcount[fontf]==0) font_lose_font(fontf);
- }
-
- /*
- * release_fonts --
- *
- * Lose all the fonts from a document.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Decrements fontcounts. May lose fonts.
- * Does not zero ft->usage. It is called when the document is closed!
- *
- */
-
- extern void release_fonts(font_table *ft)
- { int i;
- for(i=1;i<256;i++) if(ft->used[i]) wimp_losefont(i);
- }
-
- /*
- * lose_all_fonts --
- *
- * Closes all fonts when the program exits. (called by an atexit procedure)
- *
- * Results:
- * None.
- *
- * Side effects:
- * Closes all fonts.
- *
- */
-
- static void lose_all_fonts(void)
- { font_f i;
- for(i=1;i<255;i++) if(fontcount[i]>0) font_lose_font(i);
- }
-
- /*
- * getcolour --
- *
- * Translates a textual description of a colour
- * "none" gives -1 (transparent)
- *
- * Results:
- * returns a colour (may have odd bottom byte if the text is incorrect)
- *
- * Side effects:
- * None.
- *
- */
-
- os_colour getcolour(char *s)
- { int r=0,g=0,b=0;
- if(!strcmp(s,"none")) return os_COLOUR_TRANSPARENT;
- if(*s<'0'||*s>'9')
- { s=Tcl_GetVar2(w_Interp,"colours",s,TCL_GLOBAL_ONLY);
- if(!s) return 0;
- }
- r=strtol(s,&s,10);
- if(*s==':') g=strtol(++s,&s,10);
- if(*s==':') b=strtol(++s,&s,10);
- return r<<8|g<<16|b<<24;
- }
-
-
- /*
- * getconstant --
- *
- * Reads a small integer constant, possiby given as a name.
- *
- * Results:
- * returns an integer (-1 for unknown)
- *
- * Side effects:
- * None.
- *
- */
-
- int getconstant(char *s)
- { switch(s[0])
- { case 0:return 0;
- case '0':case'1':case'2':case'3':return s[0]-'0';
- case 'c':if(!strcmp(s,"close")) return 0;
- case 'o':if(!strcmp(s,"off")) return 0;
- if(!strcmp(s,"on")) return 1;
- break;
- case 'f':if(!strcmp(s,"failclose")) return 2;
- if(!strcmp(s,"failshow")) return 3;
- break;
- case 's':if(!strcmp(s,"show")) return 1;
- break;
- case 'h':if(!strcmp(s,"hide")) return 2;
- break;
- }
- return -1;
- }
-
- /*
- * unlink --
- *
- * Removes an object from a linked list.
- * The first field of the list structure must be the next pointer.
- * The list must be terminated with a zero pointer.
- * l points to a place holding a pointer to the first object in the list
- * v points to the object to be removed.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Object removed from list - error if object not on list
- *
- */
-
- void unlink(void *l,void *v)
- { view *w;
- for(w=l;w->next;w=w->next) if(w->next==v)
- { w->next=((view*)v)->next;
- return;
- }
- msg("unlink failed",0,0);
- }
-
- /*
- * screensize --
- *
- * Places the screen size in os units in x and y
- *
- * Results:
- * None.
- *
- * Side effects:
- * Changes the contents of x and y.
- *
- */
-
- void screensize(int *x,int *y)
- { int ib[]={ os_MODEVAR_XEIG_FACTOR,os_MODEVAR_YEIG_FACTOR,
- os_MODEVAR_XWIND_LIMIT,os_MODEVAR_YWIND_LIMIT,-1
- };
- int ob[4];
- os_read_vdu_variables((os_vdu_var_list*)ib,ob);
- *x=(ob[2]+1)<<ob[0];
- *y=(ob[3]+1)<<ob[1];
- }
-
- /*
- * W_Error --
- *
- * Sets the tcl global variable "where" to the input string.
- * Interpets the script pointed to by errorproc if there is
- * one. Otherwise exits.
- * If the errorproc script gives an error it displays a wimp error box
- * and then exits.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May interpret a script or exit.
- *
- */
-
- void W_Error(char *where)
- { char *errorproc;
- Tcl_SetVar2(w_Interp,"w_where",0,where,TCL_GLOBAL_ONLY);
- errorproc=Tcl_GetVar2(w_Interp,"w_debug",0,TCL_GLOBAL_ONLY);
- if(errorproc)
- { if(Tcl_Eval(w_Interp,errorproc))
- { msg("Quitting after error in w_debug:- ",w_Interp->result,0);
- exit(0);
- }
- }
- else exit(0);
- }
-
- /*
- * checkEval --
- *
- * Performs % substitution on the tcl script "s". Then evaluates it.
- * calls W_Error with "where" passed on if it fails.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Interprets a script
- *
- */
-
- void checkEval(char *s,char *where)
- { int code;
- char *p,*q=0,*r;
- int c;
- int n=0,m=0;
- for(p=s;*p;p++) if(*p=='%') /* find the length of the sustituted string */
- { c=*++p;
- m++;
- if(c==0) break;
- c-='a';
- if((c>=0&&c<26)&&substr[c]) n+=strlen(substr[c]);
- }
- if(m) /* copy s with substitution if needed */
- { q=ckalloc(strlen(s)+1+n-m); /* space for new s */
- p=s;r=q;
- for(p=s;*p;p++) if(*p=='%')
- { c=p[1]-'a';
- if(c>=0&&c<26)
- { p++;
- if(substr[c])
- { n=strlen(substr[c]);
- strcpy(r,substr[c]);
- r+=n;
- }
- }
- }
- else *r++=*p;
- *r=0;
- s=q;
- } /* script pointed to by s in either case */
- code=Tcl_Eval(w_Interp,s);
- if(code!=TCL_OK&&code!=TCL_RETURN) W_Error(where);
- ckfree(q); /* q may be zero! */
- }
-
- /*
- * scopy --
- *
- * make a new string identical to the input
- *
- * Results:
- * Returns the new string
- *
- * Side effects:
- * Calls malloc.
- *
- */
-
- char *scopy(char *in)
- { char *out=ckalloc(strlen(in)+1);
- strcpy(out,in);
- return out;
- }
-
- /*
- * gettime --
- *
- * Reads a time in centiseconds from a string.
- *
- * Results:
- * Returns the time or -1 for a bad time.
- *
- * Side effects:
- * None.
- *
- */
-
- static os_t gettime(char *s)
- { double d;
- if(!*s) return -1;
- d=strtod(s,&s);
- switch(*s)
- { case 'c':break;
- case 's':d=d*100;break;
- case 'm':d=d*6000;break;
- case 'h':d=d*360000;break;
- case 'd':d=d*360000*24;break;
- default:return -1;
- }
- return (os_t)d;
- }
-
- /*
- * addnull --
- *
- * Insert an entry in the null scripts list .
- *
- * Results:
- * None.
- *
- * Side effects:
- * Adjusts the nullscript list.
- *
- */
-
- static void freenull(nullscript *n)
- { ckfree(n->name);ckfree(n->script);
- ckfree(n);
- nulltime=(nullscripts)?(nullscripts->when):0;
- if(!nullscripts) mask|=wimp_MASK_NULL;
- }
-
-
- static void addnull(os_t when,nullscript* n)
- { nullscript **s=(nullscript**)&nullscripts;
- when+=os_read_monotonic_time();
- for(;*s&&(*s)->when<=when;s=&((*s)->next));
- n->next=*s;
- *s=n;
- n->when=when;
- nulltime=(nullscripts)?(nullscripts->when):0;
- }
-
- /*
- * null --
- *
- * Called on a null event.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Runs a script. Adjusts the nullscript list.
- *
- */
-
-
- static void null(void)
- { if(nullscripts)
- { nullscript *now=nullscripts;
- os_t again;
- nullscripts=now->next;
- checkEval(now->script,now->name);
- again=gettime(w_Interp->result);
- if(again<0) freenull(now);
- else addnull(again,now);
- }
- }
-
- /*
- * setbutton --
- *
- * Sets the %b substitution string according to the state of the mouse
- * buttons and the modifier keys.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Changes substr[1].
- *
- */
-
- void setbutton(void)
- { char *p=substr['b'-'a'];
- int k=osbyte_read(osbyte_VAR_KEYBOARD_STATE);
- if(block.pointer.buttons&wimp_CLICK_ADJUST) *p++='a';
- if(block.pointer.buttons&wimp_CLICK_SELECT) *p++='s';
- if(k&8) *p++='S';
- if(k&64) *p++='C';
- *p=0;
- }
-
- /*
- * mouse --
- *
- * Deals with mouse click events from wimp_poll.
- * Calls menu_open for a menu click.
- * Otherwise calls box_click. If this returns
- * FALSE it calls diagram_click. If this also returns FALSE it
- * checks for an iconbar click, sets the %b substitution
- * and interprets the iconbar-click script.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May interpret a script, or change substr[1] via setbutton.
- *
- */
-
- static void mouse(void)
- { if(block.pointer.buttons==wimp_CLICK_MENU) {menu_open();return;}
- if(box_click()) return;
- if(diagram_click()) return;
- if(block.pointer.w==wimp_ICON_BAR)
- { if(iconbar_clickproc)
- { setbutton();
- checkEval(iconbar_clickproc,"iconbar click");
- }
- return;
- }
- }
-
- /*
- * runs a script sent by another application with send --
- *
- * Results:
- * None.
- *
- * Side effects:
- * Interprets a script
- *
- */
-
- static void runscript(wimp_message *m)
- { wimp_message_tcl *t=(wimp_message_tcl *)&(m->data.data_request);
- wimp_t sender=m->sender;
- int your_ref=m->my_ref;
- char *s=ckalloc(t->len);
- int code;
- xwimp_transfer_block(sender,(byte*)(t->source),taskhandle,(byte*)s,t->len);
- code=Tcl_GlobalEval(w_Interp,s);
- ckfree(s);
- m->size=32;
- m->your_ref=your_ref;
- m->action=message_TCL_RESULT;
- t->source=w_Interp->result;
- t->len=strlen(w_Interp->result)+1;
- t->resultcode=code;
- xwimp_send_message(wimp_USER_MESSAGE,m,sender);
- }
-
- /*
- * message --
- * Deals with wimp message events from wimp poll, mainly by
- * calling the relevant procedure.
- * Handles drags to the iconbar by setting the w_file variable
- * and the %t substitution before evaluating the script.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May interpret a script
- *
- */
-
- static void message(void)
- { wimp_message *m=&(block.message);
- switch(m->action)
- { case message_QUIT:exit(0);
- case message_DATA_LOAD:
- { wimp_message_data_request *dr=&(m->data.data_request);
- if(dr->w==wimp_ICON_BAR)
- { if(iconbar_dragproc);
- { Tcl_SetVar2(w_Interp,"w_file",0,
- (char*)(dr->file_types+1),TCL_GLOBAL_ONLY);
- sprintf(substr['t'-'a'],"%d",dr->file_types[0]);
- checkEval(iconbar_dragproc,"file drag");
- }
- break;
- }
- if(box_dragload(m)) break;
- }
- break;
- case message_MENU_WARNING:
- { wimp_message_menu_warning *mw=(void*)&(m->data.reserved);
- box_submenu(mw->sub_menu,substr['w'-'a'],mw->pos.x,mw->pos.y);
- }
- break;
- case message_DATA_SAVE_ACK:box_dragsave(m);break;
- case message_TASK_WINDOW_OUTPUT:
- case message_TASK_WINDOW_EGO:
- case message_TASK_WINDOW_MORIO:
- case message_TASK_WINDOW_NEW_TASK:task_message(m);break;
- case message_MODE_CHANGE:diagram_modechange();break;
- case message_PALETTE_CHANGE:diagram_palettechange();break;
- case message_TCL_SCRIPT:runscript(m);break;
-
- }
- }
-
- /*
- * W_Poll --
- * Calls wimp poll and calls a suitable procedure to handle the
- * result.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Various.
- *
- */
-
- void W_Poll(void)
- { int e;
- if(!w_Interp) return;
- for(;;)
- { e=wimp_poll_idle(mask,&block,nulltime,0);
- switch(e)
- { case wimp_NULL_REASON_CODE:null();break;
- case wimp_REDRAW_WINDOW_REQUEST:if(document_redraw()) break;
- if(diagram_redraw()) break;
- break;
- case wimp_OPEN_WINDOW_REQUEST:wimp_open_window(&block.open);break;
- case wimp_CLOSE_WINDOW_REQUEST:if(diagram_close()) break;
- if(document_close()) break;
- if(box_close()) break;
- wimp_close_window(block.close.w);
- break;
- case wimp_MOUSE_CLICK:mouse();break;
- case wimp_USER_DRAG_BOX:box_dragged();break;
- case wimp_KEY_PRESSED:if(box_key()) break;
- wimp_process_key(block.key.c);
- break;
- case wimp_MENU_SELECTION:menu_select();break;
- case wimp_USER_MESSAGE:
- case wimp_USER_MESSAGE_RECORDED:message();break;
- }
- }
- }
-
- /*
- * w_SendCmd --
- * Implements the w_send command
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- *
- *
- */
-
- static int w_SendCmd(ClientData dummy,Tcl_Interp *interp,int argc,char **argv)
- { taskmanager_task tk;
- wimp_message *m=&(block.message);
- wimp_message_tcl *t=(wimp_message_tcl *)&(m->data.data_request);
- int more=0;
- int e;
- if(argc!=3) return wrong(WNA,"w_send <taskname> <script>");
- for(;;)
- { xtaskmanager_enumerate_tasks(more,&tk,sizeof(taskmanager_task),&more,0);
- if(!strcmp(tk.name,argv[1])) break;
- if(more<0) return wrong("Can't find task named ",argv[1]);
- }
- m->size=28;
- m->your_ref=0;
- m->action=message_TCL_SCRIPT;
- t->source=argv[2];
- t->len=strlen(argv[2])+1;
- xwimp_send_message(wimp_USER_MESSAGE,m,tk.task);
- for(;;)
- { e=wimp_poll(0x2173,&block,0);
- if(e==wimp_USER_MESSAGE||e==wimp_USER_MESSAGE_RECORDED)
- { m=&(block.message);
- if(m->action==message_TCL_RESULT)
- { wimp_message_tcl *t=(wimp_message_tcl *)&(m->data.data_request);
- char *res=ckalloc(t->len);
- xwimp_transfer_block(tk.task,(byte*)(t->source),taskhandle,
- (byte*)res,t->len);
- Tcl_SetResult(w_Interp,res,TCL_DYNAMIC);
- if(t->resultcode==TCL_ERROR) return TCL_REMOTEERROR;
- return t->resultcode;
- }
- message();continue;
- }
- switch(e)
- { case wimp_LOSE_CARET:/* Deliberate fall through */
- case wimp_GAIN_CARET:continue;
- case wimp_OPEN_WINDOW_REQUEST:wimp_open_window(&block.open);break;
- case wimp_CLOSE_WINDOW_REQUEST:if(diagram_close()) break;
- if(document_close()) break;
- if(box_close()) break;
- wimp_close_window(block.close.w);
- break;
- case wimp_USER_DRAG_BOX:box_dragged();break;
- case wimp_MENU_SELECTION:menu_select();break;
- }
- return wrong("No reply to send from ",argv[1]);
- }
- }
-
- /*
- * w_BarCmd --
- * Implements the w_bar command
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * May make a menu or set iconbar_clickproc or iconbar_dragproc.
- * Puts an icon on the bar.
- *
- */
-
- static int w_BarCmd(ClientData dummy,Tcl_Interp *interp,int argc,char **argv)
- { wimp_icon_create ic;
- int i;
- int x=68,y=68,ex=0,ey=0;
- os_mode m;
- for(i=1;i<argc-1;i++)
- { if(!strcmp(argv[i],"-menu"))
- { tcl_menu *tm;
- tm=menu_make(argv[++i],"bar");
- if(!tm) return TCL_ERROR;
- menu_bar(tm);
- continue;
- }
- if(!strcmp(argv[i],"-click"))
- { iconbar_clickproc=scopy(argv[++i]);
- continue;
- }
- if(!strcmp(argv[i],"-drag"))
- { iconbar_dragproc=scopy(argv[++i]);
- continue;
- }
- return wrong("Unknown w_bar option: ",argv[i]);
- }
- sprintf(ic.icon.data.text,"!%s",progname);
- if(!xwimpspriteop_read_sprite_size(ic.icon.data.text,&x,&y,0,&m))
- { os_read_mode_variable(m,os_MODEVAR_XEIG_FACTOR,&ex);
- os_read_mode_variable(m,os_MODEVAR_YEIG_FACTOR,&ey);
- }
- ic.w=wimp_ICON_BAR_RIGHT;
- ic.icon.extent.x0=0;ic.icon.extent.y0=0;
- ic.icon.extent.x1=x<<ex;ic.icon.extent.y1=y<<ey;
- ic.icon.flags=wimp_ICON_SPRITE|
- (wimp_BUTTON_CLICK<<wimp_ICON_BUTTON_TYPE_SHIFT);
- wimp_create_icon(&ic);
- return TCL_OK;
- }
-
- /*
- * w_NullCmd --
- * Implements the w_null command
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * May insert or remove an entry in the nullscript list.
- * Can change the wimp mask.
- *
- */
-
- static int w_NullCmd(ClientData dummy,Tcl_Interp *interp,int argc,char **argv)
- { if(argc<2||argc>4) return wrong(WNA,"w_null <name> ?<script> ?<time>??");
- if(argc==2)
- { nullscript *w=(nullscript*)&nullscripts;
- for(;w->next;w=w->next) if(!strcmp(w->next->name,argv[1]))
- { nullscript *n=w->next;
- w->next=(w->next)->next;
- freenull(n);
- break;
- }
- }
- else
- { os_t when=100;
- nullscript *n;
- if(argc==4) when=gettime(argv[3]);
- if(when<0) return wrong("Bad time ",argv[3]);
- n=ckalloc(sizeof(nullscript));
- n->name=scopy(argv[1]);
- n->script=scopy(argv[2]);
- addnull(when,n);
- mask&=~wimp_MASK_NULL;
- }
- return TCL_OK;
- }
-
- /*
- * w_ErrorCmd --
- * Implements the w_error command.
- *
- * Results:
- * A standard tcl result.
- *
- * Side effects:
- * Displays an error box.
- *
- */
-
- static int w_ErrorCmd(ClientData dummy,Tcl_Interp *interp,int argc,char **argv)
- { os_error e;
- bits flags=0;
- int i;
- e.errnum=0;
- if(argc>1) sprintf(e.errmess,"%.200s",argv[1]);
- else e.errmess[0]=0;
- for(i=2;i<argc;i++)
- { if(!strcmp(argv[i],"-ok")) { flags|=wimp_ERROR_BOX_OK_ICON;continue;}
- if(!strcmp(argv[i],"-cancel")) flags|=wimp_ERROR_BOX_CANCEL_ICON;
- }
- flags=wimp_report_error(&e,flags,progname);
- sprintf(interp->result,"%u",2-flags);
- return TCL_OK;
- }
-
- /*
- * getsprites --
- * Load a sprite file into the user area
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- static void getsprites(char *name)
- { char buf[256];
- int n;
- os_error *e;
- sprintf(buf,"<%s$Dir>.%.200s",progname,name);
- n=flen(buf);
- if(n<0) { msg("Couldn't find ",buf,0); return;}
- userarea=ckalloc(n+4);
- userarea->size=n+4;
- userarea->sprite_count=0;
- userarea->first=sizeof(osspriteop_area);
- userarea->used=sizeof(osspriteop_area);
- e=xosspriteop_load_sprite_file(osspriteop_USER_AREA,userarea,buf);
- if(e) wimp_report_error(e,wimp_ERROR_BOX_OK_ICON,progname);
- }
-
- /*
- * w_InitCmd --
- * Implements the w_init command.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * Sets w_Interp, progname,taskhandle.
- * Creates the other w_ commands.
- * Sets up the buffers to hold % substitutions.
- * Sets up exit handlers to lose fonts and kill any tasks still running.
- * Initialises variables w_debug and w_version
- *
- */
-
- int W_InitCmd(ClientData dummy,Tcl_Interp *interp,int argc,char **argv)
- { int version;
- if(argc<2||argc>3) return wrong(WNA,"w_init name ?sprites?");
- if(w_Interp) return wrong("w_init may only be called once",0);
- w_Interp=interp;
- strncpy(progname,argv[1],PNSIZE);progname[PNSIZE]=0;
- Tcl_InitHashTable(&documentTable,TCL_STRING_KEYS);
- Tcl_InitHashTable(&diagramTable,TCL_STRING_KEYS);
- Tcl_InitHashTable(&boxTable,TCL_STRING_KEYS);
- Tcl_InitHashTable(&taskTable,TCL_STRING_KEYS);
- Tcl_CreateCommand(interp,"w_bar",w_BarCmd,NULL,NULL);
- Tcl_CreateCommand(interp,"w_error",w_ErrorCmd,NULL,NULL);
- Tcl_CreateCommand(interp,"w_text",w_TextCmd,NULL,NULL);
- Tcl_CreateCommand(interp,"w_draw",w_DrawCmd,NULL,NULL);
- Tcl_CreateCommand(interp,"w_box",w_BoxCmd,NULL,NULL);
- Tcl_CreateCommand(interp,"w_task",w_TaskCmd,NULL,NULL);
- Tcl_CreateCommand(interp,"system",w_SystemCmd,NULL,NULL);
- Tcl_CreateCommand(interp,"w_send",w_SendCmd,NULL,NULL);
- Tcl_CreateCommand(interp,"w_null",w_NullCmd,NULL,NULL);
- Tcl_CreateCommand(interp,"w_info",w_InfoCmd,NULL,NULL);
- taskhandle=wimp_initialise(wimp_VERSION_RO3,progname,
- (wimp_message_list*)wimpmessages,&version);
- sprintf(interp->result,progname);
- substr['x'-'a']=subbuffer;
- substr['y'-'a']=subbuffer+12;
- substr['t'-'a']=subbuffer+24;
- substr['b'-'a']=subbuffer+36;
- atexit(lose_all_fonts);
- atexit(task_killall);
- modeinfo();
- Tcl_SetVar2(w_Interp,"w_debug",0,
- "if {![w_error \"Error in $w_where :- $errorInfo\" -ok -cancel]} exit",
- TCL_GLOBAL_ONLY);
- Tcl_SetVar2(w_Interp,"w_version",0,W_VERSION,TCL_GLOBAL_ONLY);
- if(argc==3) getsprites(argv[2]);
- return TCL_OK;
- }
-
-