/* * LIL - Little Interpreted Language * Copyright (C) 2010 Kostas Michalopoulos * */ #include #include #include #include #include #include #include #include "paneltk.h" #include "lil.h" #include #include #include static Mouse m; static Image *red, *blue; static Panel *root,*cmd,*menu3,*list,*msg,*cururl,*text; char *buttons[] = { "Test 1", "Test 2", " -- 99 --", "The end", }; void wishexit(Panel *p, int buttons) { USED(p,buttons); exit(0); } char *testgen(Panel *,int idx) { static char buff[100]; if(idx > 10) return 0; snprint(buff,sizeof(buff)," [ %06d ] - Test ",idx); return buff; } void hit3(int button,int item) { } void nullcmd(int,int) {} void nullcmden(Panel *,char *) {} void nullcmdlst(Panel *,int,int) {} void nullcmdtxt(Panel *,int,Rtext *) {} void mkpanels(void){ root=plgroup(root, PACKN|FILLX); plgrabkb(root); } #define VAL_T size_t #define smatch strcasecmp #define RETERROR 0 #define PRINTMSG(STR) #define ERRORRETURN(i,MSG) {lil_set_error(i,MSG); return 0;} typedef struct opt_t opt_t; struct opt_t { char *string; VAL_T value; }; typedef struct useraux_t useraux_t; struct useraux_t { lil_t lil; char *name; void *appaux; char *cmd; char *var; char *tmpstr; lil_value_t liltmp; int spare; }; useraux_t *newuseraux(lil_t lil,char *name,char *cmd,char *var) { useraux_t *a ; a = calloc(1,sizeof(useraux_t)); if(name) a->name=strdup(name); if(cmd) a->cmd=strdup(cmd); if(var) a->var=strdup(var); a->lil=lil; return a; } static lil_value_t pack(lil_t lil, VAL_T argc, lil_value_t *argv) { Panel *t; useraux_t *u; if(argc == 0) ERRORRETURN(lil,"config: no widget ptr"); t = (Panel *)lil_to_integer(*argv); u = t->userp; if(t == NULL) ERRORRETURN(lil,"pack: invalid widget ptr"); plpack(t, screen->r); draw(screen, screen->r, display->black, nil, ZP); pldraw(t, screen); flushimage(display, 1); return 0; } static lil_value_t toplevel(lil_t lil, VAL_T argc, lil_value_t *argv) { Panel *t; if(argc < 1) ERRORRETURN(lil,"toplevel: No widget ptr"); t = (Panel *)lil_to_integer(*argv++); root = t; plpack(root,screen->r); eresized(0); return 0; } static int cvtint(char *x) { return atoi(x); } static unsigned long int cvtul(char *x) { return strtoul(x,NULL,10); } static lil_value_t focus(lil_t lil, VAL_T argc, lil_value_t *argv) { Panel *t; if(argc == 0) return lil_alloc_integer((VAL_T)plkbfocus); t = (Panel *)lil_to_integer(*argv); if(t == NULL) ERRORRETURN(lil,"focus: invalid widget ptr"); /* Need to validate the address*/ plgrabkb(t); return lil_alloc_integer((VAL_T)t); } static lil_value_t lilcd(lil_t lil, VAL_T argc, lil_value_t *argv) { char buff[257]; getcwd(buff,256); if(argc == 0) return lil_alloc_string(buff); char *dir=lil_to_string(*argv++); if(chdir(dir)< 0) ERRORRETURN(lil,"cd: invalid directory"); return 0; } static lil_value_t image(lil_t lil, VAL_T argc, lil_value_t *argv) { Panel *t; if(argc == 0) ERRORRETURN(lil,"image: specify image file to load"); char *file = lil_to_string(*argv); int fd=open(file,O_RDONLY); if( fd== -1) ERRORRETURN(lil,"image: File does not exist"); Image *i=readimage(display,fd,0); if(! i) ERRORRETURN(lil,"image: error reading image file"); if(argc >1) { int rep = lil_to_integer(*argv); if (rep) replclipr(i,1,i->clipr); } return lil_alloc_integer((VAL_T)i); } static lil_value_t lilrfork(lil_t lil, VAL_T argc, lil_value_t *argv) ; static lil_value_t imageinfo(lil_t lil, VAL_T argc, lil_value_t *argv) { char buff[200]; if(argc == 0) ERRORRETURN(lil,"imageinfo: specify image"); Image *i = (Image *)lil_to_integer(*argv); snprintf(buff,199,"%d %d %d %d %d %d %d",i->id,i->repl,i->depth, i->r.min.x,i->r.min.y,i->r.max.x,i->r.max.y); return lil_alloc_string(buff); } static lil_value_t config(lil_t lil, VAL_T argc, lil_value_t *argv) { Panel *t; useraux_t *u; if(argc == 0) ERRORRETURN(lil,"config: no widget ptr"); t = (Panel *)lil_to_integer(*argv++); if(t == NULL) ERRORRETURN(lil,"config: invalid widget ptr"); u= t->userp; if(argc > 1 && smatch(lil_to_string(*argv),"bbox")==0) { char buff[100]; snprintf(buff,99,"%s %d %d %d %d ", u->name,t->r.min.x, t->r.min.y, t->r.max.x, t->r.max.y); return lil_alloc_string(buff); } if(argc > 1 && smatch(lil_to_string(*argv),"screen")==0) { char buff[100]; snprintf(buff,99,"screen %d %d %d %d ", screen->r.min.x, screen->r.min.y, screen->r.max.x, screen->r.max.y); return lil_alloc_string(buff); } char buff[100]; snprintf(buff,99,"%p Kind %s of %p: (%d,%d,%d,%d) size(%d,%d) name (%s) cmd (%s) var (%s)\n", t,t->kind,t->parent,t->r.min.x,t->r.min.y,t->r.max.x,t->r.max.y, Dx(t->r),Dy(t->r), u->name,u->cmd,u->var); return lil_alloc_string(buff); return 0; } void plsetslider(Panel *p, int value, int range); int plgetslider(Panel *p, int range); static lil_value_t reconfig(lil_t lil, VAL_T argc, lil_value_t *argv) { Panel *t; useraux_t *ua; if(argc == 0) ERRORRETURN(lil,"reconfig: no widget ptr"); t = (Panel *)lil_to_integer(*argv++); if(t == NULL) ERRORRETURN(lil,"reconfig: invalid widget ptr"); ua= t->userp; if( smatch(t->kind,"slider") == 0) { if(argc == 1) { return lil_alloc_integer(plgetslider(t, 100)); } if(smatch(lil_to_string(*argv),"-value")==0) { plsetslider(t, lil_to_integer(argv[1]), 100); plpack(t->parent,t->parent->r); pldraw(t,t->b); return 0; } ERRORRETURN(ua->lil,"reconfig: only slider value can be configured"); } if( smatch(t->kind,"label") != 0) ERRORRETURN(ua->lil,"reconfig: not a label"); if(argc > 2 && smatch(lil_to_string(*argv),"-image")==0) { VAL_T img = lil_to_integer(argv[1]); if( ! img) ERRORRETURN(ua->lil,"reconfig: bad image ptr"); t->flags |= BITMAP; plinitlabel(t,t->flags,(char *)img); // plpack(t,screen->r); pldraw(t,t->b); flushimage(display, 1); return 0; } if(argc > 2 && smatch(lil_to_string(*argv),"-text")==0) { char *txt = lil_to_string(argv[1]); t->flags &= ~ BITMAP; plinitlabel(t,t->flags,txt); // plpack(t,t->parent->r); pldraw(t,t->b); return 0; } ERRORRETURN(ua->lil,"reconfigure only -image and -text supported"); return 0; } static lil_value_t tkevent(lil_t lil, size_t argc, lil_value_t *argv) { Event e; if(! (ecanmouse() | ecankbd() | argc ) ) {return 0;} switch(event(&e)) { case Ekeyboard: plkeyboard(e.kbdc); break; case Emouse: plmouse(root,&e.mouse); break; } return 0; } static void xx(Panel *p,int a,int b) { useraux_t *ua = p->userp; lil_value_t ret; char val[200]; if(! ua) return; if(ua->cmd) { snprintf(val,199,"%s %s %d %d",ua->cmd,ua->name,a,b); ret=lil_parse(ua->lil,val,0,1); lil_free_value(ret); } } static char* lcall(Panel *p,int a) { char *rp; char val[60]; useraux_t *ua = p->userp; lil_value_t cmd,ret; if(! ua ) return a < 100 ? "Unknown # " : 0; if( ua->var) { lil_list_t lst = lil_subst_to_list(ua->lil,lil_get_var(ua->lil,ua->var)); if(! lst) return 0; cmd = lil_list_get(lst,a); if( !cmd) return 0; lil_free_list(lst); return strdup(lil_to_string(cmd)); } if( ! ua->cmd ) return 0; snprintf(val,59,"%d ",a); cmd = lil_alloc_string(ua->cmd); lil_append_string(cmd," "); lil_append_string(cmd,ua->name); lil_append_string(cmd," "); lil_append_string(cmd,val); ret=lil_parse_value(ua->lil,cmd,1); rp = lil_to_string(ret); lil_free_value(ret); return strdup(rp); } static void cb_null(Panel *p,char *) {} static void cb_button(Panel *p,int a) {xx(p,a,0);} static void cb_buttonrc(Panel *p,int a,int b) {xx(p,a,b);} static void cb_list(Panel *p,int a,int b) {xx(p,a,b);} static char *cb_listfill(Panel *p,int a) {return lcall(p,a);} static void cb_text(Panel *p,int a,Rtext *) {} static void cb_canvas(Panel *p,Mouse *) {} static void cb_drawcanvas(Panel *p) {} static void cb_edit(Panel *p) {xx(p,0,0);} static void cb_slider(Panel *p,int a,int b,int c) { xx(p,a,100*b/c); } static void cb_entry(Panel *p,char *) {xx(p,0,0);} static void cb_menuFIX(Panel *p,int a,int b) {} static void cb_menu(int a,int b) {} static void cb_textview(Panel *p,int,Rtext *) {} Rune *txt2runes(char *txt) { Rune *r,*runes = malloc(strlen(txt)*sizeof(Rune)+10); int err; r = runes; while( *txt) { err = chartorune(r++,txt); if (err == -1) { fprintf(stderr,"Convert rune failed with [%s]\n",txt); break; } txt += err; } *r++=0; *r++=0; return (Rune *)runes; } Rtext *newrtext(Panel *p) { return 0; } #include "tk.inc" void wishinit(lil_t lil) { if(newwindow(0) < 0) { printf("newwindow failed %d\n",errno); exit(-1); } if(initdraw(0,0,"Wish") <0) { printf("Init draw failed %d\n",errno); exit(-1); } einit(Emouse|Ekeyboard); plinit(screen->depth); red = allocimagemix(display, DRed, DRed); blue = allocimagemix(display, DBlue, DBlue); lil_register(lil, "event", tkevent); lil_register(lil, "focus", focus); lil_register(lil, "toplevel", toplevel); lil_register(lil, "widget", newwidget); lil_register(lil, "cfgwidget", cfgwidget); lil_register(lil, "pack", pack); lil_register(lil, "config", config); lil_register(lil, "image", image); lil_register(lil, "imageinfo", imageinfo); lil_register(lil, "cfg", reconfig); lil_register(lil, "rfork", lilrfork); lil_register(lil, "cd", lilcd); mkpanels(); eresized(0); } void eresized(int new) { Rectangle r; if(new && getwindow(display, Refnone) < 0) { fprint(2,"can't reattach to window"); exit(-1); } /* FIXME: Pack and draw appropriate items Should callback Lil and it should call pldraw with what it wants */ if(! root) return; r = screen->r; if(new) plpack(root, r); pldraw(root, screen); flushimage(display, 1); } #include static lil_value_t lilrfork(lil_t lil, VAL_T argc, lil_value_t *argv) { Panel *t; char *file; int flags = 0; if(argc == 0) ERRORRETURN(lil,"rfork missing flags"); while( *argv ) { file = lil_to_string(*argv); if(*file == 'e') flags |= RFENVG; if(*file == 'n') flags |= RFNAMEG; if(*file == 's') flags |= RFNOTEG; if(*file == 'f') flags |= RFFDG; if(*file == 'm') flags |= RFNOMNT; if(*file == 'N') flags |= RFCNAMEG; if(*file == 'E') flags |= RFCENVG; if(*file == 'F') flags |= RFCFDG; argv++; } if(rfork(flags) < 0) ERRORRETURN(lil,"rfork failed, wrongflags"); return 0; }