#include #include #include #include #include #include #include #include #include struct ScreenMate { FILE * rc; int PNum; GdkPixmap ** Pix; GdkBitmap ** Mask; } SM; struct SM_MenuItem { char * label; char * text; }; struct SM_MenuItem * SM_MenuPtr=0; int SM_MenuSize=0; GtkWidget * SM_Menu=NULL; int WndWidth=0,WndHeight=0,WMH=0,WMW=0,no_exit_flag=0; GdkWindow * RootWnd=NULL,*RWnd=NULL; GtkWidget *Main=NULL; GdkWindowAttr attr; char * Btn1_ClickLbl=NULL,* Btn2_ClickLbl=NULL,* Btn3_ClickLbl=NULL; gint click_btn_callback(GtkWidget *w, GdkEventButton *event, gpointer data); void unspace(char * buf); int interp_seek_line(struct ScreenMate * sm,int line); int interp_seek_label(struct ScreenMate * sm,char * label); int check_eat_token(char * buf,char * tok); gint interpreter_callback(); void interpreter(struct ScreenMate * sm); void interpreter_fetch(char * startlabel); int isfile(char *s); void wrap_exit(); void init_window() { Main = gtk_window_new ( GTK_WINDOW_TOPLEVEL ); gtk_signal_connect( GTK_OBJECT(Main), "destroy", GTK_SIGNAL_FUNC(wrap_exit), NULL); gtk_widget_set_events (Main,GDK_BUTTON_PRESS_MASK); gtk_signal_connect(GTK_OBJECT(Main),"button_press_event",(GtkSignalFunc)click_btn_callback, NULL); gtk_widget_set_usize( Main, WndWidth, WndHeight ); attr.window_type = GDK_WINDOW_CHILD; attr.wclass = GDK_INPUT_OUTPUT; attr.width = WndWidth; attr.height = WndHeight; Main->window = gdk_window_new( NULL, &attr, 0); gtk_widget_show(Main); gdk_window_show(Main->window); for(RootWnd=Main->window;(RootWnd!=NULL)&(RWnd!=RootWnd);RootWnd=gdk_window_get_parent(RootWnd)) RWnd=RootWnd; gdk_window_get_size(RWnd,&WMW,&WMH); //printf("Root window:%dx%d\n",WMW,WMH); return; } gint display_pixmap(GdkPixmap *DisplayPixmap, GdkBitmap *DisplayMask ) { gdk_window_set_back_pixmap( Main->window, DisplayPixmap, 0); gdk_window_shape_combine_mask( Main->window, DisplayMask, 0,0); gdk_window_clear(Main->window); gdk_flush(); return(TRUE); } int isfile(char *s) { struct stat st; if ((!s)||(!*s)) return 0; if (stat(s,&st)<0) return 0; if (S_ISREG(st.st_mode)) return st.st_size; return 0; } int interp_seek_line(struct ScreenMate * sm,int line) { char buf[200],* bptr; if(sm==NULL) return 0; if(sm->rc==NULL) return 0; if(!line) return 0; rewind(sm->rc); line--; if(!line) return 1; for(;((bptr=fgets(buf,sizeof(buf),sm->rc))!=NULL)&(!!line);line--); return !line; } int interp_seek_label(struct ScreenMate * sm,char * label) { char buf[200],* bptr; if(sm==NULL) return 0; if(sm->rc==NULL) return 0; if(label==NULL) return 0; rewind(sm->rc); while((bptr=fgets(buf,sizeof(buf),sm->rc))!=NULL) { if(check_eat_token(buf,"label")) { unspace(buf); if(!strncasecmp(buf,label,strlen(label))) return 1; } else if(check_eat_token(buf,"emb_image")) { char * pos,xbuf[200]; unspace(buf); pos=buf; while((!!*pos)&(*pos!=' ')) pos++; if(!*pos) exit(fprintf(stderr,"Syntax error while bypassing \"emb_image\" in label scaner\n")); while(pos>=buf) { *pos=' '; pos--; }; unspace(buf); memset(xbuf,0,sizeof(xbuf)); while((bptr=fgets(xbuf,sizeof(xbuf),sm->rc))!=NULL) if(check_eat_token(xbuf,buf)) break; if(bptr==NULL) exit(fprintf(stderr,"End of file while \"emb_image\" in label scaner\n")); }; }; return 0; } void unspace(char * buf) { while(*buf==' ') memmove(buf,buf+1,strlen(buf)); } int check_eat_token(char * buf,char * tok) { if((tok==NULL)||(buf==NULL)) return 0; if(!!strncasecmp(buf,tok,strlen(tok))) return 0; memmove(buf,buf+strlen(tok),strlen(buf)-strlen(tok)+1); return 1; } gint handle_menu(GtkWidget *widget, gpointer data) { interpreter_fetch(data); gtk_widget_destroy(SM_Menu); SM_Menu=NULL; gtk_timeout_add( 50,interpreter_callback, NULL ); return(FALSE); } gint interpreter_callback() { if(Main!=NULL) gdk_window_raise(Main->window); interpreter(&SM); return(FALSE); } void interpreter_fetch(char * startlabel) { if(startlabel==NULL) startlabel="main"; if(!interp_seek_label(&SM,startlabel)) exit(fprintf(stderr,"Can't locate label %s\n",startlabel)); return; } gint click_btn_callback(GtkWidget *w, GdkEventButton *event, gpointer data) { switch(event->button) { case 1: if(Btn1_ClickLbl!=NULL) interpreter_fetch(Btn1_ClickLbl); break; case 2: if(Btn2_ClickLbl!=NULL) interpreter_fetch(Btn2_ClickLbl); break; case 3: if(Btn3_ClickLbl!=NULL) interpreter_fetch(Btn3_ClickLbl); break; }; return(FALSE); } void interpreter(struct ScreenMate * sm) { char buf[200],*bptr; if(sm==NULL) exit(fprintf(stderr,"No screenmate descriptor\n")); if(sm->rc==NULL) exit(fprintf(stderr,"No screenmate rc file opened\n")); memset(buf,0,sizeof(buf)); while((bptr=fgets(buf,sizeof(buf),sm->rc))!=NULL) { if(buf[strlen(buf)-1]=='\n') buf[strlen(buf)-1]=0; unspace(buf); if(*buf=='#') continue; if(check_eat_token(buf,"label")) continue; else if(check_eat_token(buf,"exit")) exit(0); else if(check_eat_token(buf,"init_window")) { if((!WndHeight)||(!WndWidth)) exit(fprintf(stderr,"Set window height and width first !\n")); init_window(); } else if(check_eat_token(buf,"close_window")) { no_exit_flag=1; gtk_widget_destroy(Main); Main=NULL; } else if(check_eat_token(buf,"goto")) { unspace(buf); if(!interp_seek_label(sm,buf)) exit(fprintf(stderr,"Can't locate label %s\n",buf)); } else if(check_eat_token(buf,"print ")) puts(buf); else if(check_eat_token(buf,"exec")) { unspace(buf); system(buf); } else if(check_eat_token(buf,"test")) { char * pos; unspace(buf); pos=buf; while((!!*pos)&(*pos!=' ')) pos++; if(!*pos) exit(fprintf(stderr,"Syntax: TEST