/* $Id: mfile.c,v 10.1 92/10/06 23:03:29 ca Exp $ */ /* * MaRS Maryland Routing Simulator * Copyright (c) 1991 University of Maryland * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of U.M. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. U.M. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Eric Bull * Systems Design and Analysis Group * Department of Computer Science * University of Maryland at College Park. */ #include #include #include #include #include #include #include #include #include #include #include "sim.h" #include "xm-mfile.h" #include "xm-util.h" #include "xm-network.h" #include "xm-main_w.h" #include "list.h" #include "xm-info_w.h" #include "comptypes.h" #include "xm-meters.h" /* This file contains functions associated with the file submenu. It also handles loading and saving the .motif information file. */ void record(Widget, int, XmFileSelectionBoxCallbackStruct *); void play(Widget, int, XmFileSelectionBoxCallbackStruct *); void print(Widget, int, XmFileSelectionBoxCallbackStruct *); void save_network(Widget, int, XmFileSelectionBoxCallbackStruct *); void load_network(Widget, int, XmFileSelectionBoxCallbackStruct *); void file_new_cb(Widget); void file_quit_cb(Widget); void confirm_quit(Widget w,int item); void confirm_clear_network(Widget w,int item); void file_cb(Widget, int); void cancel_file_selection(Widget w); void initialize_record_button(Widget w); /* FILE menu */ #define F_NEW 1 #define F_OPEN 2 #define F_SAVE 3 #define F_SNAP 4 #define F_PRINT 5 #define F_RECORD 6 #define F_PLAY 7 #define F_QUIT 8 MenuItem file_items[] = { {"",&xmSeparatorGadgetClass,'\0',NULL,NULL,NULL,NULL,NULL,(MenuItem *)NULL,NULL}, {"New",&xmPushButtonGadgetClass,'\0',NULL,NULL,XmNactivateCallback,confirm_clear_network,(XtPointer)F_NEW,(MenuItem *)NULL,NULL}, {"Open",&xmPushButtonGadgetClass,'\0',NULL,NULL,XmNactivateCallback,file_cb,(XtPointer)F_OPEN,(MenuItem *)NULL,NULL}, {"Save",&xmPushButtonGadgetClass,'\0',NULL,NULL,XmNactivateCallback,file_cb,(XtPointer)F_SAVE,(MenuItem *)NULL,NULL}, {"Snap",&xmPushButtonGadgetClass,'\0',NULL,NULL,XmNactivateCallback,file_cb,(XtPointer)F_SNAP,(MenuItem *)NULL,NULL}, {"Print",&xmPushButtonGadgetClass,'\0',NULL,NULL,XmNactivateCallback,file_cb,(XtPointer)F_PRINT,(MenuItem *)NULL,NULL}, {"",&xmSeparatorGadgetClass,'\0',NULL,NULL,NULL,NULL,NULL,(MenuItem *)NULL,NULL}, {"Stop Record",&xmPushButtonGadgetClass,'\0',NULL,NULL,XmNactivateCallback,record,(XtPointer)F_RECORD,(MenuItem *)NULL,initialize_record_button}, {"Play",&xmPushButtonGadgetClass,'\0',NULL,NULL,XmNactivateCallback,file_cb,(XtPointer)F_PLAY,(MenuItem *)NULL,NULL}, {"",&xmSeparatorGadgetClass,'\0',NULL,NULL,NULL,NULL,NULL,(MenuItem *)NULL,NULL}, {"Quit",&xmPushButtonGadgetClass,'\0',NULL,NULL,XmNactivateCallback,confirm_quit,(XtPointer)F_QUIT,(MenuItem *)NULL,NULL}, NULL }; extern char eventfilename[]; Widget file_selection_dialog=NULL; list *info_windows; list *param_windows; list *group_windows; void save_component_info(MComponent *comp, FILE *fp); int load_motif_info(char *filename); MComponent *find_group(list *l, char *name); Widget record_button; /*================================================ Function declarations ===============================================*/ void initialize_record_button(Widget w) { record_button=w; if(!record_flag) SetLabelString(record_button,"Record"); } void record(w,data,cbs) Widget w; int data; XmFileSelectionBoxCallbackStruct *cbs; { record_flag = 1 - record_flag; if (record_flag) { if ((record_file = fopen(eventfilename, "a")) == NULL) { record_flag = 0; return; } SetLabelString(record_button,"Stop Record"); } else { fclose(record_file); SetLabelString(record_button,"Record"); } } /*************************************************************************************************************************/ void play(w,data,cbs) Widget w; int data; XmFileSelectionBoxCallbackStruct *cbs; { char *filename; XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&filename); strncpy(playfilename, filename, 128); playfilename[127]='\0'; play_flag = 1; xprintclear(); printx("You need to re-start for actual playing of the file "); printx(playfilename); sleep (3); xprintclear(); XtUnmanageChild(file_selection_dialog); XtFree(filename); } /*************************************************************************************************************************/ void print(w,data,cbs) Widget w; int data; XmFileSelectionBoxCallbackStruct *cbs; { char *filename; XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&filename); if (create_PS_file(comps, filename)) { printx("Topology printout saved; use 'lpr' to print"); XtUnmanageChild(file_selection_dialog); } else /* Leave the file selection box up if the operation failed. */ printx("Print out failed"); sleep(2); xprintclear(); XtFree(filename); } /*************************************************************************************************************************/ /* This routine calls save_snapshot to write the world file, and calls save_motif_info to write the .motif file. This routine is a callback function, called by the ok button in the file selection dialog. */ void save_network(w,snap,cbs) Widget w; int snap; XmFileSelectionBoxCallbackStruct *cbs; { char *filename; char *motif_filename; int result; TRACE("save_network"); XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&filename); motif_filename=(char *)sim_malloc(strlen(filename)+7); strcpy(motif_filename, filename); strcat(motif_filename, ".motif"); if (snap) result=save_snapshot(comps, filename); else result=save_world(comps, filename); if (result) if (save_motif_info(motif_filename,snap)) { XtUnmanageChild(file_selection_dialog); xprintclear(); printx("Setup saved in file "); printx(filename); sleep (2); xprintclear(); } XtFree(filename); free(motif_filename); } /*************************************************************************************************************************/ /* This is used to uniquely identify parameters that don't have unique names. Given an scomponent and a parameter, this function starts at the head of the component's parameter list and counts the number of parameters with the same name as the given parameter. It stops counting when it reaches the given parameter. It returns the number of identical names found (including the given parameter's name). */ int get_parameter_number(COMPONENT *scomponent, PARAM *parameter) { PARAM *p; char *pname=parameter->p_name; char buf[80]; int count=1; for (p=(PARAM *)scomponent->co_params->q_head; p!=NULL; p=p->p_next) { if (!strcmp(p->p_name, pname)) { if (parameter!=p) count++; else break; } } return(count); } /*************************************************************************************************************************/ /* This finds a parameter with the given name in a component's parameter list. If count is greater than 1, then it skips over count-1 identical parameter names before returning the parameter found. */ PARAM *find_parameter(COMPONENT *scomponent, char *pname, int count) { PARAM *p; for (p=(PARAM *)scomponent->co_params->q_head; p!=NULL; p=p->p_next) { if (!strcmp(p->p_name, pname)) { if (--count==0) return(p); } } return(NULL); } /*************************************************************************************************************************/ /* This function saves all the necessary information to .motif file. */ extern Log debug_log; int global_snap; /* This flag is set if we are doing save snapshot. The flag is checked by the save_component_info() function. */ int save_motif_info(char *filename,int snap) { FILE *fp; int i; int num_types; /* Open file */ if (!(fp = fopen(filename, "w"))) { #ifdef DEBUG dbg_write(debug_log, DBG_ERR, (Component *)NULL, "save_motif_info: couldn't open %s for writing", filename); #endif return(FALSE); } /* Count the number of component types. */ for (num_types = 0; component_types[num_types].action; ++num_types); /* Save global hide_components settings */ if (snap) { fprintf(fp,"global_hide_settings\n"); for (i=0;il_head; le!=NULL; le=le->le_next) { PARAM *parameter; METER *meter; char *pname; int count; parameter = (PARAM *)le->le_data; meter = (METER *) parameter->p_my_picture; count=get_parameter_number(meter->scomponent, meter->parameter); fprintf(fp,"meter '%s' '%s' %d '%s' %lg %d %d %d %d ", meter->scomponent->co_name, parameter->p_name, count, meter->name, parameter->p_scale, meter->x, meter->y, meter->width, meter->height); if (meter->type==TIME_HISTORY) { fprintf(fp,"- %.2lf", meter->th->time_increment); } else if (meter->type==HISTOGRAM) { HISTO_METER *hist=meter->hist; fprintf(fp,"+ %lg %lg %d %d", hist->hist_min, hist->hist_max, hist->hist_cells, hist->data_samples); } fprintf(fp,"\n"); } } fclose(fp); return(TRUE); } /*************************************************************************************************************************/ char *get_component_name(MComponent *comp) { if (comp->type==TYPE_GROUP) { return(comp->name); } else { COMPONENT *scomponent; PARAM *parameter; scomponent=(COMPONENT *)comp->scomponent; parameter=(PARAM *)scomponent->co_params->q_head; return(parameter->p_make_short_text(scomponent,parameter)); } } /*************************************************************************************************************************/ /* This routine saves all the necessary information for a single component. */ void save_component_info(MComponent *comp, FILE *fp) { l_elt *le; switch(comp->type) { case TYPE_GROUP: fprintf(fp, "group '%s' %s\n", comp->name, (CompGroupOpen(comp) && global_snap)? "open" : "closed"); if (global_snap) { if (CompInfoWindowOpen(comp)) { int x,y; GetWidgetCoordinates(((InfoWinData *)comp->info_window)->dialog_widget,x,y); fprintf(fp,"infowindow %d %d\n",x,y); } } for(le=comp->children->l_head; le!=NULL; le=le->le_next) { MComponent *child; child=(MComponent *)le->le_data; switch(child->type) { case TYPE_GROUP: fprintf(fp, "childgroup '%s'\n", child->name); break; case TYPE_METER: /* ???????????????? */ break; default: fprintf(fp, "child %s\n",get_component_name(child)); break; } } break; case TYPE_METER: /* ?????????????? */ break; default: fprintf (fp, "component %s %s\n", get_component_name(comp), (!CompVisible(comp) && global_snap)? "not_visible" : "visible"); if (global_snap) { if (CompInfoWindowOpen(comp)) { int x,y; GetWidgetCoordinates(((InfoWinData *)comp->info_window)->dialog_widget,x,y); fprintf(fp,"infowindow %d %d\n",x,y); } if (CompParamWindowOpen(comp)) { int x,y; GetWidgetCoordinates(((InfoWinData *)comp->param_window)->dialog_widget,x,y); fprintf(fp,"paramwindow %d %d\n",x,y); } if (CompChildrenHidden(comp)) fprintf(fp, "hide_children\n"); if (CompMetersHidden(comp)) fprintf(fp, "hide_meters\n"); } } fprintf(fp, "\n"); } /*************************************************************************************************************************/ /* This routine calls read_world to read the world file, and calls load_motif_info to read the .motif file. This routine is a callback function, called by the ok button in the file selection dialog. */ void load_network(w,data,cbs) Widget w; int data; XmFileSelectionBoxCallbackStruct *cbs; { char *filename; char *motif_filename; int min_width; int min_height; TRACE("load_network"); XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&filename); if (access(filename, R_OK) == -1) { /* file does not exist */ xprintclear(); printx("Can't access file, aborting..."); sleep(2); xprintclear(); goto END; } XtUnmanageChild(file_selection_dialog); /* File found, drop the file selection box. */ if (ev_now() != 0) sim_stop(comps); destroy_world(); comps = (list *) read_world(filename); if (comps == NULL) { xprintclear(); printx("Error creating new world."); sleep(2); xprintclear(); goto END; } else /* Load the motif stuff */ { extern list *network_components; char *motif_filename; int result; motif_filename=(char *)sim_malloc(strlen(filename)+7); strcpy(motif_filename, filename); strcat(motif_filename, ".motif"); result=load_motif_info(motif_filename); free(motif_filename); /* Expand the network if necessary. */ GetMinimumNetworkSize(&min_width, &min_height); if (min_width>the_environment.network_width || min_height>the_environment.network_height) { ResizeNetwork(max(the_environment.network_width,min_width), max(the_environment.network_height,min_height)); } /* Draw Everything */ if (!result) /* Then we have to make all the component's visible before we draw them. */ MakeComponentsVisible(network_components); DrawComponents(network_components); if (result) OpenInformationWindowsFromFile(); } END: XtFree(filename); } /*******************************************************************************************************************************************/ MComponent *find_group(list *l, char *name) { l_elt *le; if (l_empty(l)) return(NULL); for(le=l->l_head; le!=NULL; le=le->le_next) { MComponent *comp; comp=(MComponent *)le->le_data; if (comp->type==TYPE_GROUP) { if (!strcmp(comp->name,name)) { return(comp); } else { if ((comp=find_group(comp->children, name))!=NULL) return(comp); } } } return(NULL); } extern list *read_line(); extern COMPONENT *find_comp(); typedef struct { MComponent *comp; int x,y; } WindowInformation; /*******************************************************************************************************************************************/ /* This routine reads the .motif file. It must be called after read_world. */ int load_motif_info(char *filename) { FILE *fp; char b[1024]; list *l; if (!(fp = fopen(filename, "r"))) { #ifdef DEBUG dbg_write(debug_log, DBG_ERR, (Component *)NULL, "read_world: couldn't open motif world file '%s'", filename); #endif return(FALSE); } info_windows=l_create(); param_windows=l_create(); group_windows=l_create(); while (l = read_line(fp, b)) { if (l->l_len < 1) { /* Blank line */ lq_delete(l); continue; } ucase(l->l_head->le_data); if (!strcmp(l->l_head->le_data, "METER_WINDOW")) { l_elt *le; int x,y,width,height; char buf[50]; le=l->l_head->le_next; sscanf(le->le_data,"%d",&x); sscanf(le->le_next->le_data,"%d",&y); sscanf(le->le_next->le_next->le_data,"%d",&width); sscanf(le->le_next->le_next->le_next->le_data,"%d",&height); if (!the_environment.meter_window_open) { sprintf(buf,"%dx%d+%d+%d",width,height,x,y); XtVaSetValues(XtParent(meter_w), XmNgeometry, buf, NULL); } else XtVaSetValues(XtParent(meter_w), XmNx, x, XmNy, y, XmNwidth, width, XmNheight, height, NULL); lq_delete(l); continue; } if (!strcmp(l->l_head->le_data, "METER")) { l_elt *le; COMPONENT *scomponent; char *cname,*pname, *mname; PARAM *p, *param=NULL; int x, y, width, height, count; le = l->l_head->le_next; cname= (char *)le->le_data; le = le->le_next; pname= (char *)le->le_data; le = le->le_next; if ((scomponent=find_comp(comps, cname))==NULL) { WARNING("While loading a meter, could not find component in comps."); lq_delete(l); continue; } sscanf(le->le_data,"%d",&count); le = le->le_next; if ((param=find_parameter(scomponent, pname, count))==NULL) { WARNING("While loading a meter, could not find parameter."); lq_delete(l); continue; } mname = (char *)le->le_data; le = le->le_next; sscanf(le->le_data,"%lf",¶m->p_scale); le = le->le_next; sscanf(le->le_data,"%d",&x); sscanf(le->le_next->le_data,"%d",&y); sscanf(le->le_next->le_next->le_data,"%d",&width); sscanf(le->le_next->le_next->le_next->le_data,"%d",&height); CreateMeter(scomponent, param, mname, x, y, width, height, FALSE); lq_delete(l); continue; } if (!strcmp(l->l_head->le_data, "GLOBAL_HIDE_SETTINGS")) { char typename[40]; lq_delete(l); while (l = read_line(fp, b)) { if (l->l_len < 1) break; sscanf(l->l_head->le_data,"%s",&typename); SetGlobalHidden(GetTypeNumber(typename)); lq_delete(l); continue; } continue; } if (!strcmp(l->l_head->le_data, "DEFAULT_NAMES")) { char typename[40]; int number; lq_delete(l); while (l = read_line(fp, b)) { if (l->l_len < 1) break; sscanf(l->l_head->le_data,"%s",&typename); sscanf(l->l_head->le_next->le_data,"%d",&number); SetDefaultNumber(typename,number); lq_delete(l); continue; } continue; } if (!strcmp(l->l_head->le_data, "COMPONENT")) { l_elt *le; COMPONENT *scomponent; char *cname; int visible=FALSE; le = l->l_head->le_next; cname= (char *)le->le_data; le = le->le_next; ucase(le->le_data); if (!strcmp(le->le_data,"VISIBLE")) visible=TRUE; lq_delete(l); if ((scomponent=find_comp(comps, cname))!=NULL) { MComponent *comp; comp=(MComponent *)scomponent->co_picture; while (l = read_line(fp, b)) { if (l->l_len < 1) break; ucase(l->l_head->le_data); if (!strcmp(l->l_head->le_data, "INFOWINDOW")) { int x,y; WindowInformation *w_info; sscanf(l->l_head->le_next->le_data,"%d",&x); sscanf(l->l_head->le_next->le_next->le_data,"%d",&y); w_info=(WindowInformation *)sim_malloc(sizeof(WindowInformation)); w_info->comp=comp; w_info->x=x; w_info->y=y; l_addt(info_windows,w_info); lq_delete(l); continue; } if (!strcmp(l->l_head->le_data, "PARAMWINDOW")) { int x,y; WindowInformation *w_info; sscanf(l->l_head->le_next->le_data,"%d",&x); sscanf(l->l_head->le_next->le_next->le_data,"%d",&y); w_info=(WindowInformation *)sim_malloc(sizeof(WindowInformation)); w_info->comp=comp; w_info->x=x; w_info->y=y; l_addt(param_windows, w_info); lq_delete(l); continue; } if (!strcmp(l->l_head->le_data, "HIDE_CHILDREN")) { SetStatusChildrenHidden(comp); lq_delete(l); continue; } if (!strcmp(l->l_head->le_data, "HIDE_METERS")) { SetStatusMetersHidden(comp); lq_delete(l); continue; } } if (visible) SetStatusVisible(comp); else SetStatusInvisible(comp); } else WARNING("In load_motif_info, could not find component in comps\n"); continue; } if (!strcmp(l->l_head->le_data, "GROUP")) { MComponent *group; WindowInformation *w_info=NULL; l_elt *le; char *cname; list *childlist; int open=FALSE; le = l->l_head->le_next; cname = new_string((char *)le->le_data); le = le->le_next; ucase(le->le_data); if (!strcmp(le->le_data,"OPEN")) open=TRUE; lq_delete(l); childlist=l_create(); while (l = read_line(fp, b)) { if (l->l_len < 1) break; ucase(l->l_head->le_data); if (!strcmp(l->l_head->le_data, "INFOWINDOW")) { int x,y; sscanf(l->l_head->le_next->le_data,"%d",&x); sscanf(l->l_head->le_next->le_next->le_data,"%d",&y); w_info=(WindowInformation *)sim_malloc(sizeof(WindowInformation)); w_info->x=x; w_info->y=y; l_addt(group_windows, w_info); lq_delete(l); continue; } if (!strcmp(l->l_head->le_data, "CHILD")) { COMPONENT *scomponent; char *cname; cname=l->l_head->le_next->le_data; if ((scomponent=find_comp(comps, cname))!=NULL) { MComponent *comp; comp=(MComponent *)scomponent->co_picture; l_addh(childlist,comp); } else WARNING("In load_motif_info, could not find component in comps\n"); lq_delete(l); continue; } if (!strcmp(l->l_head->le_data, "CHILDGROUP")) { MComponent *group; char *cname; cname=l->l_head->le_next->le_data; if ((group=find_group(network_components,cname))!=NULL) { l_addh(childlist,group); } else WARNING("In load_motif_info, could not find group in network_components\n"); lq_delete(l); continue; } lq_delete(l); } group=NewGroup(cname,childlist); /* NewGroup leaves the group open. */ free(cname); if (w_info!=NULL) /* An information window may not have been opened. */ w_info->comp=group; if (!open) CloseGroup(group); } } return(TRUE); } /*******************************************************************************************************************************************/ /* This is called after reading the world file, if there no .motif file. This function sets the visible flag on all components. */ void MakeComponentsVisible(list *complist) { l_elt *le; for(le=complist->l_head; le!=NULL; le=le->le_next) { MComponent *comp; comp=(MComponent *)le->le_data; if (comp->type!=TYPE_GROUP) { if (comp->type!=TYPE_METER || the_environment.draw_meter_component) SetStatusVisible(comp); } MakeComponentsVisible(comp->children); } } /*******************************************************************************************************************************************/ /* This is called after load_motif_info to open up all the information windows found in the .motif file. */ void OpenInformationWindowsFromFile() { /* Open information windows. */ l_elt *le; for (le=info_windows->l_head; le!=NULL; le=le->le_next) { WindowInformation *w_info; w_info=(WindowInformation *)le->le_data; OpenComponentInformationWindow(w_info->comp,w_info->x,w_info->y,TRUE); /* TRUE means use the given coordinates. */ } for (le=param_windows->l_head; le!=NULL; le=le->le_next) { WindowInformation *w_info; w_info=(WindowInformation *)le->le_data; OpenParameterWindow(w_info->comp,w_info->x,w_info->y,TRUE); } for (le=group_windows->l_head; le!=NULL; le=le->le_next) { WindowInformation *w_info; w_info=(WindowInformation *)le->le_data; OpenGroupInformationWindow(w_info->comp,w_info->x,w_info->y,TRUE); /* TRUE means use the given coordinates. */ } l_obliterate(info_windows); l_obliterate(param_windows); l_obliterate(group_windows); } /*******************************************************************************************************************************************/ void file_new_cb(widget) Widget widget; { TRACE("file_new_cb"); if (ev_now() != 0) sim_stop(comps); destroy_world(); comps=l_create(); } /*******************************************************************************************************************************************/ void confirm_clear_network(Widget w,int item) { static Widget question_dialog=NULL; if (!question_dialog) { question_dialog=XmCreateQuestionDialog(main_w_shell,"confirm_clear_network_dialog",NULL,0); XtAddCallback(question_dialog,XmNokCallback,(XtCallbackProc)file_new_cb,NULL); XtAddCallback(question_dialog,XmNokCallback,(XtCallbackProc)XtUnmanageChild,NULL); XtAddCallback(question_dialog,XmNcancelCallback,(XtCallbackProc)XtUnmanageChild,NULL); } XtManageChild(question_dialog); XRaiseWindow(the_environment.the_display, XtWindow(XtParent(question_dialog))); } /*************************************************************************************************************************/ void file_quit_cb(widget) Widget widget; { TRACE("file_quit_cb"); if (ev_now() != 0) sim_stop(comps); print_end_stat(stderr); if (profile_flag) { print_end_stat(profilefile); print_rusage(profilefile); fclose(profilefile); } exit(0); } /*******************************************************************************************************************************************/ void confirm_quit(Widget w,int item) { static Widget question_dialog=NULL; if (!the_environment.quitwarn) { file_quit_cb(NULL); return; } if (!question_dialog) { question_dialog=XmCreateQuestionDialog(main_w_shell,"confirm_quit_dialog",NULL,0); XtAddCallback(question_dialog,XmNokCallback,(XtCallbackProc)file_quit_cb,NULL); XtAddCallback(question_dialog,XmNokCallback,(XtCallbackProc)XtUnmanageChild,NULL); XtAddCallback(question_dialog,XmNcancelCallback,(XtCallbackProc)XtUnmanageChild,NULL); } XtManageChild(question_dialog); XRaiseWindow(the_environment.the_display, XtWindow(XtParent(question_dialog))); } /*************************************************************************************************************************/ void file_cb(widget,item) Widget widget; int item; { extern Widget main_w_shell; static Widget label; static Widget fs_box; Widget sep; if (!file_selection_dialog) { file_selection_dialog = XmCreateFormDialog(main_w_shell,"file_selection_dialog",NULL,0); XtVaSetValues(file_selection_dialog, XmNautoUnmanage, False, NULL); label=XtVaCreateManagedWidget("title", xmLabelWidgetClass, file_selection_dialog, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); sep=CreateSeparator(file_selection_dialog, XmDOUBLE_LINE, label); fs_box = XmCreateFileSelectionBox(file_selection_dialog,"file_selection_box",NULL,0); XtVaSetValues(fs_box, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, sep, NULL); XtAddCallback(fs_box, XmNcancelCallback, (XtCallbackProc)cancel_file_selection, NULL); XtManageChild(fs_box); } else { XtRemoveAllCallbacks(fs_box,XmNokCallback); } switch(item) { case F_OPEN: XtAddCallback(fs_box, XmNokCallback, (XtCallbackProc)load_network, NULL); SetLabelString(label, "Open Network"); break; case F_SAVE: XtAddCallback(fs_box, XmNokCallback, (XtCallbackProc)save_network, FALSE); SetLabelString(label, "Save Network"); break; case F_SNAP: XtAddCallback(fs_box, XmNokCallback, (XtCallbackProc)save_network, (XtPointer) TRUE); SetLabelString(label, "Save Snapshot"); break; case F_PRINT: XtAddCallback(fs_box, XmNokCallback, (XtCallbackProc)print, NULL); SetLabelString(label, "Print Network"); break; case F_PLAY: XtAddCallback(fs_box, XmNokCallback, (XtCallbackProc)play, NULL); SetLabelString(label, "Playback Events"); break; default: WARNING("Unexpected item no. in file_cb.\n"); break; } XtManageChild(file_selection_dialog); XRaiseWindow(the_environment.the_display, XtWindow(XtParent(file_selection_dialog))); } void cancel_file_selection(Widget w) { XtUnmanageChild(file_selection_dialog); }