1*37da2899SCharles.Forsythimplement TclLib; 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsythinclude "sys.m"; 4*37da2899SCharles.Forsyth sys: Sys; 5*37da2899SCharles.Forsyth 6*37da2899SCharles.Forsythinclude "draw.m"; 7*37da2899SCharles.Forsyth 8*37da2899SCharles.Forsythinclude "string.m"; 9*37da2899SCharles.Forsyth str : String; 10*37da2899SCharles.Forsyth 11*37da2899SCharles.Forsythinclude "tk.m"; 12*37da2899SCharles.Forsyth tk: Tk; 13*37da2899SCharles.Forsyth 14*37da2899SCharles.Forsythinclude "tkclient.m"; 15*37da2899SCharles.Forsyth tkclient: Tkclient; 16*37da2899SCharles.Forsyth 17*37da2899SCharles.Forsythinclude "tcl.m"; 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsythinclude "tcllib.m"; 20*37da2899SCharles.Forsyth 21*37da2899SCharles.Forsytherror,started : int; 22*37da2899SCharles.Forsythw_cfg := array[] of { 23*37da2899SCharles.Forsyth "pack .Wm_t -side top -fill x", 24*37da2899SCharles.Forsyth "update", 25*37da2899SCharles.Forsyth}; 26*37da2899SCharles.Forsyth 27*37da2899SCharles.Forsythtclmod : ref Tcl_Core->TclData; 28*37da2899SCharles.Forsyth 29*37da2899SCharles.Forsythwindows := array[100] of (string, ref Tk->Toplevel, chan of string); 30*37da2899SCharles.Forsyth 31*37da2899SCharles.Forsythvalid_commands:= array[] of { 32*37da2899SCharles.Forsyth "bind" , "bitmap" , "button" , 33*37da2899SCharles.Forsyth "canvas" , "checkbutton" , "destroy" , 34*37da2899SCharles.Forsyth "entry" , "focus", "frame" , "grab", "image" , "label" , 35*37da2899SCharles.Forsyth "listbox" ,"lower", "menu" , "menubutton" , 36*37da2899SCharles.Forsyth "pack" , "radiobutton" , "raise", "scale" , 37*37da2899SCharles.Forsyth "scrollbar" , "text" , "update" , 38*37da2899SCharles.Forsyth "toplevel" , "variable" 39*37da2899SCharles.Forsyth}; 40*37da2899SCharles.Forsyth 41*37da2899SCharles.Forsythabout() : array of string { 42*37da2899SCharles.Forsyth return valid_commands; 43*37da2899SCharles.Forsyth} 44*37da2899SCharles.Forsyth 45*37da2899SCharles.Forsythinit() : string { 46*37da2899SCharles.Forsyth sys = load Sys Sys->PATH; 47*37da2899SCharles.Forsyth str = load String String->PATH; 48*37da2899SCharles.Forsyth tk = load Tk Tk->PATH; 49*37da2899SCharles.Forsyth tkclient = load Tkclient Tkclient->PATH; 50*37da2899SCharles.Forsyth if (tkclient==nil || str==nil || tk==nil) 51*37da2899SCharles.Forsyth return "Not Initialised"; 52*37da2899SCharles.Forsyth # set up Draw context 53*37da2899SCharles.Forsyth tkclient->init(); 54*37da2899SCharles.Forsyth started=1; 55*37da2899SCharles.Forsyth return nil; 56*37da2899SCharles.Forsyth} 57*37da2899SCharles.Forsyth 58*37da2899SCharles.Forsythexec(tcl : ref Tcl_Core->TclData,argv : array of string) : (int,string) { 59*37da2899SCharles.Forsyth retval : string; 60*37da2899SCharles.Forsyth retval=""; 61*37da2899SCharles.Forsyth han,whan : ref Tk->Toplevel; 62*37da2899SCharles.Forsyth whan=nil; 63*37da2899SCharles.Forsyth msg : string; 64*37da2899SCharles.Forsyth c : chan of string; 65*37da2899SCharles.Forsyth msg=nil; 66*37da2899SCharles.Forsyth error=0; 67*37da2899SCharles.Forsyth tclmod=tcl; 68*37da2899SCharles.Forsyth if (!started) 69*37da2899SCharles.Forsyth if (init()!=nil) 70*37da2899SCharles.Forsyth return (1,"Can't Initialise TK"); 71*37da2899SCharles.Forsyth if (argv[0][0]!='.') 72*37da2899SCharles.Forsyth case argv[0] { 73*37da2899SCharles.Forsyth "destroy" => 74*37da2899SCharles.Forsyth for (j:=1;j<len argv;j++){ 75*37da2899SCharles.Forsyth (msg,han)=sweepthru(argv[j]); 76*37da2899SCharles.Forsyth if (msg==nil){ 77*37da2899SCharles.Forsyth if (argv[j][0]=='.') 78*37da2899SCharles.Forsyth argv[j]=argv[j][1:]; 79*37da2899SCharles.Forsyth for(i:=0;i<100;i++){ 80*37da2899SCharles.Forsyth (retval,nil,c)=windows[i]; 81*37da2899SCharles.Forsyth if (retval==argv[1]){ 82*37da2899SCharles.Forsyth c <-= "exit"; 83*37da2899SCharles.Forsyth break; 84*37da2899SCharles.Forsyth } 85*37da2899SCharles.Forsyth } 86*37da2899SCharles.Forsyth } 87*37da2899SCharles.Forsyth else 88*37da2899SCharles.Forsyth msg=tkcmd(whan,"destroy "+msg); 89*37da2899SCharles.Forsyth } 90*37da2899SCharles.Forsyth return (error,msg); 91*37da2899SCharles.Forsyth "bind" or "bitmap" or "button" or 92*37da2899SCharles.Forsyth "canvas" or "checkbutton" or "entry" or 93*37da2899SCharles.Forsyth "focus" or "frame" or "grab" or 94*37da2899SCharles.Forsyth "image" or "label" or "listbox" or "lower" or 95*37da2899SCharles.Forsyth "menu" or "menubutton" or "pack" or 96*37da2899SCharles.Forsyth "radiobutton" or "raise" or "scale" or 97*37da2899SCharles.Forsyth "scrollbar" or "text" or "update" or 98*37da2899SCharles.Forsyth "variable" => 99*37da2899SCharles.Forsyth ; # do nothing 100*37da2899SCharles.Forsyth "toplevel" => 101*37da2899SCharles.Forsyth msg=do_toplevel(argv); 102*37da2899SCharles.Forsyth return (error,msg); 103*37da2899SCharles.Forsyth * => 104*37da2899SCharles.Forsyth return (0,"Unknown"); 105*37da2899SCharles.Forsyth } 106*37da2899SCharles.Forsyth # so it's a tk-command ... replace any -command with 107*37da2899SCharles.Forsyth # a send on the tcl channel. 108*37da2899SCharles.Forsyth if (argv[0]=="bind") 109*37da2899SCharles.Forsyth argv[3]="{send Tcl_Chan "+argv[3]+"}"; 110*37da2899SCharles.Forsyth for (i:=0;i<len argv;i++){ 111*37da2899SCharles.Forsyth (argv[i],han)=sweepthru(argv[i]); 112*37da2899SCharles.Forsyth if (han!=nil) whan=han; 113*37da2899SCharles.Forsyth if (argv[i]!="-tcl") 114*37da2899SCharles.Forsyth retval+=argv[i]; 115*37da2899SCharles.Forsyth if (i+1<len argv && 116*37da2899SCharles.Forsyth (argv[i]=="-command" || argv[i]=="-yscrollcommand" 117*37da2899SCharles.Forsyth || argv[i]=="-tcl" || argv[i]=="-xscrollcommand")) 118*37da2899SCharles.Forsyth argv[i+1]="{send Tcl_Chan "+argv[i+1]+"}"; 119*37da2899SCharles.Forsyth if (argv[i]!="-tcl") 120*37da2899SCharles.Forsyth retval[len retval]=' '; 121*37da2899SCharles.Forsyth } 122*37da2899SCharles.Forsyth retval=retval[0:len retval -1]; 123*37da2899SCharles.Forsyth if (tclmod.debug==1) 124*37da2899SCharles.Forsyth sys->print("Sending [%s] to tkcmd.\n",retval); 125*37da2899SCharles.Forsyth msg=tkcmd(whan,retval); 126*37da2899SCharles.Forsyth if (msg!="" && msg[0]=='!') 127*37da2899SCharles.Forsyth error=1; 128*37da2899SCharles.Forsyth return (error,msg); 129*37da2899SCharles.Forsyth} 130*37da2899SCharles.Forsyth 131*37da2899SCharles.Forsyth 132*37da2899SCharles.Forsythsweepthru(s: string) : (string,ref Tk->Toplevel) { 133*37da2899SCharles.Forsyth han : ref Tk->Toplevel; 134*37da2899SCharles.Forsyth ret : string; 135*37da2899SCharles.Forsyth if (s=="" || s=="." || s[0]!='.') 136*37da2899SCharles.Forsyth return (s,nil); 137*37da2899SCharles.Forsyth (wname,rest):=str->splitl(s[1:],"."); 138*37da2899SCharles.Forsyth for (i:=0;i<len windows;i++){ 139*37da2899SCharles.Forsyth (ret,han,nil)=windows[i]; 140*37da2899SCharles.Forsyth if (ret==wname) 141*37da2899SCharles.Forsyth break; 142*37da2899SCharles.Forsyth } 143*37da2899SCharles.Forsyth if (i==len windows) 144*37da2899SCharles.Forsyth return (s,nil); 145*37da2899SCharles.Forsyth return (rest,han); 146*37da2899SCharles.Forsyth} 147*37da2899SCharles.Forsyth 148*37da2899SCharles.Forsythdo_toplevel(argv : array of string): string 149*37da2899SCharles.Forsyth{ 150*37da2899SCharles.Forsyth name : string; 151*37da2899SCharles.Forsyth whan : ref Tk->Toplevel; 152*37da2899SCharles.Forsyth if (len argv!=2) 153*37da2899SCharles.Forsyth return notify(1,"toplevel name"); 154*37da2899SCharles.Forsyth if (argv[1][0]=='.') 155*37da2899SCharles.Forsyth argv[1]=argv[1][1:]; 156*37da2899SCharles.Forsyth for(i:=0;i<len windows;i++){ 157*37da2899SCharles.Forsyth (name,whan,nil)=windows[i]; 158*37da2899SCharles.Forsyth if(whan==nil || name==argv[1]) 159*37da2899SCharles.Forsyth break; 160*37da2899SCharles.Forsyth } 161*37da2899SCharles.Forsyth if (i==len windows) 162*37da2899SCharles.Forsyth return notify(0,"Too many top level windows"); 163*37da2899SCharles.Forsyth if (name==argv[1]) 164*37da2899SCharles.Forsyth return notify(0,argv[1]+" is already a window name in use."); 165*37da2899SCharles.Forsyth 166*37da2899SCharles.Forsyth (top, menubut) := tkclient->toplevel(tclmod.context, "", argv[1], Tkclient->Appl); 167*37da2899SCharles.Forsyth whan = top; 168*37da2899SCharles.Forsyth 169*37da2899SCharles.Forsyth windows[i]=(argv[1],whan,menubut); 170*37da2899SCharles.Forsyth if (tclmod.debug==1) 171*37da2899SCharles.Forsyth sys->print("creating window %d, name %s, handle %ux\n",i,argv[1],whan); 172*37da2899SCharles.Forsyth cmd := chan of string; 173*37da2899SCharles.Forsyth tk->namechan(whan, cmd, argv[1]); 174*37da2899SCharles.Forsyth for(i=0; i<len w_cfg; i++) 175*37da2899SCharles.Forsyth tk->cmd(whan, w_cfg[i]); 176*37da2899SCharles.Forsyth tkclient->onscreen(whan, nil); 177*37da2899SCharles.Forsyth tkclient->startinput(whan, "kbd"::"ptr"::nil); 178*37da2899SCharles.Forsyth stop := chan of int; 179*37da2899SCharles.Forsyth spawn tkclient->handler(whan, stop); 180*37da2899SCharles.Forsyth spawn menulisten(whan,menubut, stop); 181*37da2899SCharles.Forsyth return nil; 182*37da2899SCharles.Forsyth} 183*37da2899SCharles.Forsyth 184*37da2899SCharles.Forsyth 185*37da2899SCharles.Forsythmenulisten(t : ref Tk->Toplevel, menubut : chan of string, stop: chan of int) { 186*37da2899SCharles.Forsyth for(;;) alt { 187*37da2899SCharles.Forsyth menu := <-menubut => 188*37da2899SCharles.Forsyth if(menu == "exit"){ 189*37da2899SCharles.Forsyth for(i:=0;i<len windows;i++){ 190*37da2899SCharles.Forsyth (name,whan,nil):=windows[i]; 191*37da2899SCharles.Forsyth if(whan==t) 192*37da2899SCharles.Forsyth break; 193*37da2899SCharles.Forsyth } 194*37da2899SCharles.Forsyth if (i!=len windows) 195*37da2899SCharles.Forsyth windows[i]=("",nil,nil); 196*37da2899SCharles.Forsyth stop <-= 1; 197*37da2899SCharles.Forsyth exit; 198*37da2899SCharles.Forsyth } 199*37da2899SCharles.Forsyth tkclient->wmctl(t, menu); 200*37da2899SCharles.Forsyth } 201*37da2899SCharles.Forsyth} 202*37da2899SCharles.Forsyth 203*37da2899SCharles.Forsythtkcmd(t : ref Tk->Toplevel, cmd: string): string { 204*37da2899SCharles.Forsyth if (len cmd ==0 || tclmod.top==nil) return nil; 205*37da2899SCharles.Forsyth if (t==nil){ 206*37da2899SCharles.Forsyth t=tclmod.top; 207*37da2899SCharles.Forsyth #sys->print("Sending to WishPad\n"); 208*37da2899SCharles.Forsyth } 209*37da2899SCharles.Forsyth s := tk->cmd(t, cmd); 210*37da2899SCharles.Forsyth tk->cmd(t,"update"); 211*37da2899SCharles.Forsyth return s; 212*37da2899SCharles.Forsyth} 213*37da2899SCharles.Forsyth 214*37da2899SCharles.Forsythnotify(num : int,s : string) : string { 215*37da2899SCharles.Forsyth error=1; 216*37da2899SCharles.Forsyth case num{ 217*37da2899SCharles.Forsyth 1 => 218*37da2899SCharles.Forsyth return sys->sprint( 219*37da2899SCharles.Forsyth "wrong # args: should be \"%s\"",s); 220*37da2899SCharles.Forsyth * => 221*37da2899SCharles.Forsyth return s; 222*37da2899SCharles.Forsyth } 223*37da2899SCharles.Forsyth} 224