void read_node_desc_from_pvm(dg_node *nod, window *win) { int key; receive_int_array(&nod->node_id, 1); receive_int_array(&nod->posx, 1); receive_int_array(&nod->posy, 1); receive_int_array(&key, 1); if ( key & 0x08 ){ receive_str(nod->weight); }else{ *nod->weight = 0; } if ( key & 0x04 ) { receive_str(nod->label); } else { sprintf(nod->label, "%i", nod->node_id); } if ( key & 0x02 ) { receive_str(nod->dash); } else { strcpy(nod->dash, win->desc.node_dash); } if ( key & 0x01 ) { receive_int_array(&nod->radius, 1); } else { nod->radius = win->desc.node_radius; } nod->deleted = FALSE; }
int user_dg_process_message(void *user, window *win, FILE *write_to) { cnrp_dg *win_cnrp = (cnrp_dg *)user; int msgtag; int length; int *xind; double *xval; receive_int_array(&msgtag, 1); switch (msgtag) { case CNRP_CTOI_DRAW_FRAC_GRAPH: receive_int_array(&length, 1); xind = (int *) malloc(length * ISIZE); xval = (double *) malloc(length * DSIZE); receive_int_array(xind, length); receive_dbl_array(xval, length); dg_freenet(win_cnrp->n); win_cnrp->n = dg_createnet(win->g.nodenum, length, xind, xval); FREE(xind); FREE(xval); dg_net_shrink_chains(win_cnrp->n); copy_network_into_graph(win_cnrp->n, &win->g); display_graph_on_canvas(win, write_to); break; } return(USER_SUCCESS); }
int user_receive_cg_data(void **user, int dg_id) { spp_cg_problem *spp; col_ordered *m; int colnum, rownum, info; spp = (spp_cg_problem *) calloc(1, sizeof(spp_cg_problem)); *user = spp; spp->par = (spp_cg_params *) calloc(1, sizeof(spp_cg_params)); receive_char_array((char *)spp->par, sizeof(spp_cg_params)); m = spp->cmatrix = (col_ordered *) calloc(1, sizeof(col_ordered)); receive_int_array(&m->colnum, 1); colnum = m->active_colnum = m->colnum; receive_int_array(&m->rownum, 1); rownum = m->rownum; receive_int_array(&m->nzcnt, 1); m->colnames = (int *) malloc(colnum * ISIZE); m->col_deleted = (char *) calloc(colnum/BITSPERBYTE + 1, CSIZE); /*calloc!*/ m->obj = (double *) malloc(colnum * DSIZE); m->matbeg = (int *) malloc((colnum + 1) * ISIZE); m->matind = (row_ind_type *) malloc(m->nzcnt * sizeof(row_ind_type)); receive_int_array(m->colnames, colnum); receive_dbl_array(m->obj, colnum); receive_int_array(m->matbeg, (colnum + 1)); receive_char_array((char *)m->matind, m->nzcnt * sizeof(row_ind_type)); spp->max_sol_length = rownum; /* allocate space for tmp arrays */ spp->tmp = (spp_cg_tmp *) calloc(1, sizeof(spp_cg_tmp)); spp->tmp->itmp_m = (int *) malloc(rownum * ISIZE); spp->tmp->istartmp_m = (int **) malloc(rownum * sizeof(int *)); spp->tmp->cuttmp = (cut_data *) calloc(1, sizeof(cut_data)); /* initialize cg data structures */ spp->fgraph = (frac_graph *) calloc(1, sizeof(frac_graph)); spp->cfgraph = (frac_graph *) calloc(1, sizeof(frac_graph)); spp->cm_frac = (col_ordered *) calloc(1, sizeof(col_ordered)); spp->rm_frac = (row_ordered *) calloc(1, sizeof(row_ordered)); spp->rm_frac->rmatbeg = (int *) malloc((rownum+1) * ISIZE); spp->lgraph = (level_graph *) calloc(1, sizeof(level_graph)); allocate_var_length_structures(spp, spp->max_sol_length); /* cut collection is a local cut pool that contains the cuts that have been sent back to the lp */ spp->cut_coll = (cut_collection *) calloc(1, sizeof(cut_collection)); spp->cut_coll->max_size = 1000; spp->cut_coll->cuts = (cut_data **) calloc(spp->cut_coll->max_size, sizeof(cut_data *)); spp->cut_coll->violation = (double *) malloc(spp->cut_coll->max_size * DSIZE); spp->cut_coll->mult = (int *) malloc(spp->cut_coll->max_size * ISIZE); return(USER_SUCCESS); }
void set_window_desc_pvm(int key, window *win) { win_desc *desc = &win->desc; switch ( key ) { case CANVAS_WIDTH: receive_int_array(&desc->canvas_width, 1); break; case CANVAS_HEIGHT: receive_int_array(&desc->canvas_height, 1); break; case VIEWABLE_WIDTH: receive_int_array(&desc->viewable_width, 1); break; case VIEWABLE_HEIGHT: receive_int_array(&desc->viewable_height, 1); break; case DISP_NODELABELS: receive_int_array(&desc->disp_nodelabels, 1); break; case DISP_NODEWEIGHTS: receive_int_array(&desc->disp_nodeweights, 1); break; case DISP_EDGEWEIGHTS: receive_int_array(&desc->disp_edgeweights, 1); break; case NODE_DASH: receive_str(desc->node_dash); break; case EDGE_DASH: receive_str(desc->edge_dash); break; case NODE_RADIUS: receive_int_array(&desc->node_radius, 1); break; case INTERACTIVE_MODE: receive_int_array(&desc->interactive_mode, 1); break; case MOUSE_TRACKING: receive_int_array(&desc->mouse_tracking, 1); break; case SCALE_FACTOR: receive_dbl_array(&desc->scale_factor, 1); break; case NODELABEL_FONT: receive_str(desc->nodelabel_font); break; case NODEWEIGHT_FONT: receive_str(desc->nodeweight_font); break; case EDGEWEIGHT_FONT: receive_str(desc->edgeweight_font); break; } }
void cg_initialize(cg_prob *p, int master_tid) { #ifndef COMPILE_IN_CG int bytes, msgtag; #if defined(COMPILE_IN_TM) && defined(COMPILE_IN_LP) int s_bufid, r_bufid, info; #endif #endif #if !defined(COMPILE_IN_TM) || !defined(COMPILE_IN_LP) int r_bufid, s_bufid = 0; #endif /*------------------------------------------------------------------------ * Receive the problem data *------------------------------------------------------------------------*/ #ifdef COMPILE_IN_CG p->master = master_tid; #else /* We only need to do this part if the CG is running as a separate process*/ /* Otherwise, all of this setup is done in the master in the function */ /* pack_cg_data_u()*/ /* set stdout to be line buffered */ setvbuf(stdout, (char *)NULL, _IOLBF, 0); register_process(); r_bufid = receive_msg(ANYONE, MASTER_TID_INFO); bufinfo(r_bufid, &bytes, &msgtag, &p->tree_manager); receive_int_array(&p->master, 1); receive_int_array(&p->proc_index, 1); freebuf(r_bufid); #endif #if !defined(COMPILE_IN_TM) || !defined(COMPILE_IN_LP) || \ !defined(COMPILE_IN_CG) /* This part, we only need to do if we are not running in full serial mode*/ s_bufid = init_send(DataInPlace); send_msg(p->master, REQUEST_FOR_CG_DATA); freebuf(s_bufid); receive_cg_data_u(p); #endif (void) used_time(&p->tt); }
int receive_cg_data_u(cg_prob *p) { int r_bufid; r_bufid = receive_msg(p->master, CG_DATA); receive_char_array((char *)&p->par, sizeof(cg_params)); receive_int_array(&p->draw_graph, 1); #ifdef USE_SYM_APPLICATION switch( user_receive_cg_data(&p->user, p->draw_graph) ){ case USER_SUCCESS: case USER_AND_PP: case USER_NO_PP: /* User function terminated without problems. No post-processing. */ case USER_DEFAULT: freebuf(r_bufid); return(TRUE); case USER_ERROR: default: freebuf(r_bufid); /* Unexpected return value. Do something!! */ return(FALSE); } #else freebuf(r_bufid); return(TRUE); #endif }
void unpack_double_array_desc(double_array_desc *dad, char explicit_packing) { receive_char_array(&dad->type, 1); receive_int_array(&dad->size, 1); if (dad->size > 0){ if (!explicit_packing && dad->type == WRT_PARENT){ dad->list = (int *) malloc(dad->size * ISIZE); receive_int_array(dad->list, dad->size); }else{ dad->list = NULL; } dad->stat = (int *) malloc(dad->size * ISIZE); receive_int_array(dad->stat, dad->size); }else{ dad->list = NULL; dad->stat = NULL; } }
int receive_feasible_solution_u(sym_environment *env, int msgtag) { receive_int_array(&(env->best_sol.xlevel), 1); receive_int_array(&(env->best_sol.xindex), 1); receive_int_array(&(env->best_sol.xiter_num), 1); receive_dbl_array(&(env->best_sol.lpetol), 1); receive_dbl_array(&(env->best_sol.objval), 1); receive_int_array(&(env->best_sol.xlength), 1); if (env->best_sol.xlength > 0){ FREE(env->best_sol.xind); FREE(env->best_sol.xval); env->best_sol.xind = (int *) malloc(env->best_sol.xlength * ISIZE); env->best_sol.xval = (double *) malloc(env->best_sol.xlength * DSIZE); receive_int_array(env->best_sol.xind, env->best_sol.xlength); receive_dbl_array(env->best_sol.xval, env->best_sol.xlength); } if (!env->has_ub || env->best_sol.objval < env->ub){ env->has_ub = TRUE; env->ub = env->best_sol.objval; } env->best_sol.has_sol = TRUE; switch (msgtag){ case FEASIBLE_SOLUTION_NONZEROS: break; case FEASIBLE_SOLUTION_USER: /* A feasible solution has been found in the LP process, and * it was packed by the user */ #ifdef USE_SYM_APPLICATION CALL_USER_FUNCTION( user_receive_feasible_solution(env->user, msgtag, env->best_sol.objval, env->best_sol.xlength, env->best_sol.xind, env->best_sol.xval) ); #endif break; } return(FUNCTION_TERMINATED_NORMALLY); }
void read_edge_desc_from_pvm(dg_edge *edg, window *win) { int key; receive_int_array(&edg->edge_id, 1); receive_int_array(&edg->tail, 1); receive_int_array(&edg->head, 1); receive_int_array(&key, 1); if ( key & 0x08 ){ receive_str(edg->weight); }else{ *edg->weight = 0; } if ( key & 0x02 ) { receive_str(edg->dash); } else { strcpy(edg->dash, win->desc.edge_dash); } edg->deleted = FALSE; }
array_desc *unpack_array_desc(array_desc *padesc) { array_desc *adesc = padesc ? padesc : (array_desc *) malloc( sizeof(array_desc) ); receive_char_array((char *)adesc, sizeof(array_desc)); if (adesc->type != NO_DATA_STORED && adesc->size > 0){ adesc->list = (int *) malloc(adesc->size * ISIZE); receive_int_array(adesc->list, adesc->size); }else{ adesc->list = NULL; } if (adesc->type == EXPLICIT_LIST) adesc->added = adesc->size; return(adesc); }
node_desc *create_explicit_node_desc(lp_prob *p) { LPdata *lp_data = p->lp_data; int m = lp_data->m, n = lp_data->n; int bvarnum = p->base.varnum; var_desc **extravars = lp_data->vars + bvarnum; int extravarnum = n - bvarnum; int bcutnum = p->base.cutnum; row_data *rows = lp_data->rows; int extrarownum = m - bcutnum; int cutindsize; node_desc *desc = (node_desc *) calloc(1, sizeof(node_desc)); /* Will need these anyway for basis */ int *rstat = (int *) malloc(m * ISIZE); int *cstat = (int *) malloc(n * ISIZE); int *erstat = (extrarownum == 0) ? NULL : (int *) malloc(extrarownum*ISIZE); int *ecstat = (extravarnum == 0) ? NULL : (int *) malloc(extravarnum*ISIZE); int *ulist, *clist; /* this later uses tmp.i1 */ int cutcnt, i, j; #ifndef COMPILE_IN_LP int s_bufid, r_bufid; #endif get_basis(lp_data, cstat, rstat); if (extrarownum > 0) memcpy(erstat, rstat + bcutnum, extrarownum * ISIZE); if (extravarnum > 0) memcpy(ecstat, cstat + bvarnum, extravarnum * ISIZE); /* To start with, send the non-indexed cuts (only those which will be saved) to the treemanager and ask for names */ for (cutcnt = cutindsize = 0, i = bcutnum; i < m; i++){ if ((rows[i].cut->branch & CUT_BRANCHED_ON) || !rows[i].free || (rows[i].free && rstat[i] != SLACK_BASIC)){ cutindsize++; if (rows[i].cut->name < 0) cutcnt++; } } if (cutcnt > 0){ #ifdef COMPILE_IN_LP row_data *tmp_rows = (row_data *) malloc(cutcnt*sizeof(row_data)); for (j = 0, i = bcutnum; j < cutcnt; i++){ if (rows[i].cut->name < 0 && (!rows[i].free || (rows[i].free && rstat[i] != SLACK_BASIC))) tmp_rows[j++] = rows[i]; } unpack_cut_set(p->tm, 0, cutcnt, tmp_rows); FREE(tmp_rows); #else s_bufid = init_send(DataInPlace); send_int_array(&cutcnt, 1); for (i = bcutnum; i < m; i++){ if (rows[i].cut->name < 0 && (!rows[i].free || (rows[i].free && rstat[i] != SLACK_BASIC))) pack_cut(rows[i].cut); } send_msg(p->tree_manager, LP__CUT_NAMES_REQUESTED); freebuf(s_bufid); #endif } /* create the uind list and the extravars basis description */ desc->uind.type = EXPLICIT_LIST; desc->uind.added = 0; desc->uind.size = extravarnum; desc->basis.extravars.type = EXPLICIT_LIST; desc->basis.extravars.size = extravarnum; desc->basis.extravars.list = NULL; if (extravarnum > 0){ desc->uind.list = ulist = (int *) malloc(extravarnum * ISIZE); desc->basis.extravars.stat = ecstat; for (i = extravarnum - 1; i >= 0; i--) ulist[i] = extravars[i]->userind; if (lp_data->ordering == COLIND_ORDERED) qsortucb_ii(ulist, ecstat, extravarnum); }else{ desc->uind.list = NULL; desc->basis.extravars.stat = NULL; } /* create the basevars basis description */ desc->basis.basevars.type = EXPLICIT_LIST; desc->basis.basevars.size = bvarnum; desc->basis.basevars.list = NULL; if (bvarnum) desc->basis.basevars.stat = cstat; else FREE(cstat); /* create the not_fixed list */ desc->nf_status = lp_data->nf_status; if (desc->nf_status == NF_CHECK_AFTER_LAST || desc->nf_status == NF_CHECK_UNTIL_LAST){ desc->not_fixed.type = EXPLICIT_LIST; desc->not_fixed.added = 0; if ((desc->not_fixed.size = lp_data->not_fixed_num) > 0){ desc->not_fixed.list = (int *) malloc(desc->not_fixed.size * ISIZE); memcpy(desc->not_fixed.list, lp_data->not_fixed, lp_data->not_fixed_num * ISIZE); }else{ desc->not_fixed.list = NULL; } } #ifndef COMPILE_IN_LP /* At this point we will need the missing names */ if (cutcnt > 0){ static struct timeval tout = {15, 0}; int *names = lp_data->tmp.i1; /* m */ double start = wall_clock(NULL); do{ r_bufid = treceive_msg(p->tree_manager, LP__CUT_NAMES_SERVED, &tout); if (! r_bufid){ if (pstat(p->tree_manager) != PROCESS_OK){ printf("TM has died -- LP exiting\n\n"); exit(-301); } } }while (! r_bufid); p->comp_times.idle_names += wall_clock(NULL) - start; receive_int_array(names, cutcnt); for (j = 0, i = bcutnum; j < cutcnt; i++){ if (rows[i].cut->name < 0 && (!rows[i].free || (rows[i].free && rstat[i] != SLACK_BASIC))) rows[i].cut->name = names[j++]; } } #endif /* create the cutind list and the extrarows basis description */ desc->cutind.type = EXPLICIT_LIST; desc->cutind.added = 0; desc->cutind.size = cutindsize; desc->basis.extrarows.type = EXPLICIT_LIST; desc->basis.extrarows.list = NULL; desc->basis.extrarows.size = cutindsize; if (cutindsize > 0){ desc->cutind.list = clist = (int *) malloc(cutindsize * ISIZE); desc->basis.extrarows.stat = erstat; for (cutindsize = 0, i = bcutnum; i < m; i++){ if ((rows[i].cut->branch & CUT_BRANCHED_ON) || !rows[i].free || (rows[i].free && rstat[i] != SLACK_BASIC)){ clist[cutindsize] = rows[i].cut->name; erstat[cutindsize++] = rstat[i]; } } qsortucb_ii(clist, erstat, cutindsize); }else{ desc->cutind.list = NULL; desc->basis.extrarows.stat = NULL; } /* create the baserows basis description */ desc->basis.baserows.type = EXPLICIT_LIST; desc->basis.baserows.size = bcutnum; desc->basis.baserows.list = NULL; if (bcutnum) desc->basis.baserows.stat = rstat; else FREE(rstat); /* Mark that there is a basis */ desc->basis.basis_exists = TRUE; /* Add user description */ add_to_desc_u(p, desc); return(desc); }
int lp_initialize(lp_prob *p, int master_tid) { #ifndef COMPILE_IN_LP int msgtag, bytes, r_bufid; #endif #if !defined(COMPILE_IN_TM) || !defined(COMPILE_IN_LP) int s_bufid; #endif int i; row_data *rows; var_desc **vars; int termcode = 0; #ifdef COMPILE_IN_LP p->master = master_tid; #else /* set stdout to be line buffered */ setvbuf(stdout, (char *)NULL, _IOLBF, 0); register_process(); /*------------------------------------------------------------------------*\ * Receive tid info; request and receive problem specific data \*------------------------------------------------------------------------*/ r_bufid = receive_msg(ANYONE, MASTER_TID_INFO); bufinfo(r_bufid, &bytes, &msgtag, &p->tree_manager); receive_int_array(&p->master, 1); receive_int_array(&p->proc_index, 1); freebuf(r_bufid); #endif p->lp_data = (LPdata *) calloc(1, sizeof(LPdata)); p->lp_data->mip = (MIPdesc *) calloc(1, sizeof(MIPdesc)); p->lp_data->par = p->par; #pragma omp critical (lp_solver) open_lp_solver(p->lp_data); (void) used_time(&p->tt); #if !defined(COMPILE_IN_TM) || !defined(COMPILE_IN_LP) s_bufid = init_send(DataInPlace); send_msg(p->master, REQUEST_FOR_LP_DATA); freebuf(s_bufid); CALL_WRAPPER_FUNCTION( receive_lp_data_u(p) ); #endif if (p->par.tailoff_gap_backsteps > 0 || p->par.tailoff_obj_backsteps > 1){ i = MAX(p->par.tailoff_gap_backsteps, p->par.tailoff_obj_backsteps); p->obj_history = (double *) malloc((i + 1) * DSIZE); } #ifndef COMPILE_IN_LP if (p->par.use_cg){ r_bufid = receive_msg(p->tree_manager, LP__CG_TID_INFO); receive_int_array(&p->cut_gen, 1); freebuf(r_bufid); } #endif p->lp_data->rows = (row_data *) malloc((p->base.cutnum + BB_BUNCH) * sizeof(row_data)); rows = p->lp_data->rows; for (i = p->base.cutnum - 1; i >= 0; i--){ ( rows[i].cut = (cut_data *) malloc(sizeof(cut_data)) )->coef = NULL; } if (p->base.varnum > 0){ vars = p->lp_data->vars = (var_desc **) malloc(p->base.varnum * sizeof(var_desc *)); for (i = p->base.varnum - 1; i >= 0; i--){ vars[i] = (var_desc *) malloc( sizeof(var_desc) ); vars[i]->userind = p->base.userind[i]; vars[i]->colind = i; } } /* Just to make sure this array is sufficently big */ p->lp_data->not_fixed = (int *) malloc(p->par.not_fixed_storage_size*ISIZE); p->lp_data->tmp.iv = (int *) malloc(p->par.not_fixed_storage_size* 2*ISIZE); p->lp_data->tmp.iv_size = 2*p->par.not_fixed_storage_size; #ifdef COMPILE_IN_CG if (!p->cgp){ p->cgp = (cg_prob *) calloc(1, sizeof(cg_prob)); } cg_initialize(p->cgp, p->master); #endif return(FUNCTION_TERMINATED_NORMALLY); }
int user_receive_cg_data(void **user, int dg_id) { int i, j, k; /* This is the user-defined data structure, a pointer to which will be passed to each user function. It must contain all the problem-specific data needed for computations within the CG */ vrp_cg_problem *vrp = (vrp_cg_problem *) malloc(sizeof(vrp_cg_problem)); int edgenum; *user = vrp; vrp->n = NULL; /*------------------------------------------------------------------------*\ * Receive the data \*------------------------------------------------------------------------*/ receive_char_array((char *)(&vrp->par), sizeof(vrp_cg_params)); receive_int_array(&vrp->dg_id, 1); receive_int_array(&vrp->numroutes, 1); receive_int_array(&vrp->vertnum, 1); vrp->demand = (int *) calloc(vrp->vertnum, sizeof(int)); receive_int_array(vrp->demand, vrp->vertnum); receive_int_array(&vrp->capacity, 1); edgenum = vrp->vertnum*(vrp->vertnum-1)/2; #ifdef CHECK_CUT_VALIDITY receive_int_array(&vrp->feas_sol_size, 1); if (vrp->feas_sol_size){ vrp->feas_sol = (int *) calloc(vrp->feas_sol_size, sizeof(int)); receive_int_array(vrp->feas_sol, vrp->feas_sol_size); } #endif /*------------------------------------------------------------------------*\ * Set up some data structures \*------------------------------------------------------------------------*/ /*__BEGIN_EXPERIMENTAL_SECTION__*/ #ifdef COMPILE_OUR_DECOMP if (vrp->par.do_our_decomp){ vrp->cost = (int *) calloc(edgenum, sizeof(int)); receive_int_array(vrp->cost, edgenum); usr_open_decomp_lp( get_cg_ptr(NULL), edgenum ); } vrp->last_decomp_index = -1; #endif /*___END_EXPERIMENTAL_SECTION___*/ vrp->in_set = (char *) calloc(vrp->vertnum, sizeof(char)); vrp->ref = (int *) malloc(vrp->vertnum*sizeof(int)); vrp->new_demand = (int *) malloc(vrp->vertnum*sizeof(int)); vrp->cut_val = (double *) calloc(vrp->vertnum, sizeof(double)); vrp->cut_list = (char *) malloc(((vrp->vertnum >> DELETE_POWER)+1)* (vrp->par.max_num_cuts_in_shrink + 1)* sizeof(char)); vrp->edges = (int *) calloc(2*edgenum, sizeof(int)); /*create the edge list (we assume a complete graph)*/ for (i = 1, k = 0; i < vrp->vertnum; i++){ for (j = 0; j < i; j++){ vrp->edges[k << 1] = j; vrp->edges[(k << 1) + 1] = i; k++; } } vrp->dg_id = dg_id; return(USER_SUCCESS); }
int main(void) { dg_prob *dgp; dg_params *par; FILE *read_from, *write_to; int childpid, sender; char tcl_msg[MAX_LINE_LENGTH +1]; char name[MAX_NAME_LENGTH +1], name2[MAX_NAME_LENGTH +1]; char source[MAX_NAME_LENGTH +1], target[MAX_NAME_LENGTH +1]; char title[MAX_TITLE_LENGTH +1], title2[MAX_TITLE_LENGTH +1]; char fname[MAX_FILE_NAME_LENGTH +1]; char old_weight[MAX_WEIGHT_LENGTH +1], new_weight[MAX_WEIGHT_LENGTH +1]; char new_label[MAX_LABEL_LENGTH +1]; char new_dash[MAX_DASH_PATTERN_LENGTH +1]; char *str; int msgtag, keyword, key, r_bufid, s_bufid, bufid, bytes, len; int i, j, k, number, add_nodenum, change_nodenum, delete_nodenum; int add_edgenum, change_edgenum, delete_edgenum; int nodenum, new_nodenum, edgenum, new_edgenum, node_id, edge_id; int new_radius, old_deleted_nodenum; unsigned int id; win_desc *desc; dg_graph *g; dg_node *nodes, *nod; dg_edge *edges, *edg; window *win, *new_win, *source_win, *target_win; register_process(); dgp = (dg_prob *) calloc(1, sizeof(dg_prob)); /* receive parameters from the master */ r_bufid = receive_msg(ANYONE, DG_DATA); bufinfo(r_bufid, &bytes, &msgtag, &dgp->master); receive_char_array((char *)&dgp->par, sizeof(dg_params)); freebuf(r_bufid); par = &(dgp->par); echo_commands = par->echo_commands; /* fork the wish shell */ childpid = start_child((char *)"wish", &read_from, &write_to); /* Source the tcl scripts into wish and invoke startUp*/ spprint(write_to, "source %s/Init.tcl\n", par->source_path); spprint(write_to, "source %s/Tools.tcl\n", par->source_path); spprint(write_to, "source %s/NodeEdgeBasics.tcl\n", par->source_path); spprint(write_to, "source %s/FileMenu.tcl\n", par->source_path); spprint(write_to, "source %s/WindowMenu.tcl\n", par->source_path); spprint(write_to, "source %s/NodeMenu.tcl\n", par->source_path); spprint(write_to, "source %s/EdgeMenu.tcl\n", par->source_path); spprint(write_to, "source %s/CAppl.tcl\n", par->source_path); spprint(write_to, "Igd_StartUp\n"); /* set application defaults to those stored in par */ spprint(write_to, "Igd_SetApplDefaults %i %i %i %i %i %i %i {%s} {%s} %i %i %i %f {%s} {%s} {%s}\n", par->canvas_width, par->canvas_height, par->viewable_width, par->viewable_height, par->disp_nodelabels, par->disp_nodeweights, par->disp_edgeweights, par->node_dash, par->edge_dash, par->node_radius, par->interactive_mode, par->mouse_tracking, par->scale_factor, par->nodelabel_font, par->nodeweight_font, par->edgeweight_font); /* invoke user initialization */ #ifdef USE_SYM_APPLICATION CALL_USER_FUNCTION( user_initialize_dg(&dgp->user) ); #endif while(TRUE){ msgtag = 0; if (dgp->waiting_to_die){ for ( i = 0; i < dgp->window_num; ){ if ( ! dgp->windows[i]->wait_for_click ){ spprint(write_to, "Igd_QuitWindow %u\n",dgp->windows[i]->id); free_window(&dgp->window_num, dgp->windows, i); }else{ i++; } } if ( ! dgp->window_num ) wait_for_you_can_die(dgp, write_to); } /* Interpret message coming from the tcl application. */ if (fgets(tcl_msg, 80, read_from) != NULL) { sscanf(tcl_msg, "%i", &msgtag); switch(msgtag){ case IGDTOI_CLICK_HAPPENED: /* if wait_for_click is 2, send a message to the owner */ fgets(name2, MAX_NAME_LENGTH +1, read_from); sscanf(name2, "%u", &id); for (i = dgp->window_num - 1; i >= 0; i-- ) if ( dgp->windows[i]->id == id ) break; if ( i < 0 ) { /* this should never happen */ printf("Window of id %u is not found\n", id); break; } if ( dgp->windows[i]->wait_for_click == 2 ) { s_bufid = init_send(DataInPlace); send_str(name); send_msg(dgp->windows[i]->owner_tid, ITOC_CLICK_HAPPENED); freebuf(s_bufid); } dgp->windows[i]->wait_for_click = 0; break; case IGDTOI_QUIT_WINDOW: /* delete data structure corresponding to this window */ fgets(name2, MAX_NAME_LENGTH +1, read_from); sscanf(name2, "%u", &id); for (i = dgp->window_num - 1; i >= 0; i-- ) if ( dgp->windows[i]->id == id ) break; if ( i < 0 ) { /* this should never happen */ printf("Window of id %u is not found\n", id); break; } spprint(write_to, "Igd_QuitWindow %u\n", id); free_window(&dgp->window_num, dgp->windows, i); break; case IGDTOI_QUIT_APPLICATION: /* delete all windows */ for ( i = 0; i < dgp->window_num; ){ if ( ! dgp->windows[i]->wait_for_click ){ spprint(write_to, "Igd_QuitWindow %u\n",dgp->windows[i]->id); free_window(&dgp->window_num, dgp->windows, i); }else{ i++; } } dgp->waiting_to_die = TRUE; break; case IGDTOI_TEXT_ENTERED: fgets(name2, MAX_NAME_LENGTH +1, read_from); sscanf(name2, "%u", &id); for (i = dgp->window_num - 1; i >= 0; i-- ) if ( dgp->windows[i]->id == id ) break; win = dgp->windows[i]; if ( i < 0 ) { /* this should never happen */ printf("Window of id %u is not found\n", id); break; } fgets(tcl_msg, MAX_LINE_LENGTH +1, read_from); sscanf(tcl_msg, "%i", &win->text_length); win->text = (char *) malloc( (win->text_length + 1) * CSIZE); fread(win->text, CSIZE, win->text_length, read_from); win->text[win->text_length] = 0; /* invoke function that interprets the message */ #ifdef USE_SYM_APPLICATION CALL_USER_FUNCTION( user_interpret_text(dgp->user, win->text_length, win->text, win->owner_tid) ); #endif break; case IGDTOI_REQUEST_GRAPH: fgets(name2, MAX_NAME_LENGTH +1, read_from); sscanf(name2, "%u", &id); for (i = dgp->window_num - 1; i >= 0; i-- ) if ( dgp->windows[i]->id == id ) break; if ( i < 0 ) { /* this should never happen */ printf("Window of id %u is not found\n", id); break; } display_graph_on_canvas(dgp->windows[i], write_to); break; default: printf("Unknown message type from IGD to I (%i)\n", msgtag); break; } /* end switch */ } /* end if */ if (dgp->waiting_to_die) continue; /* Interpret the message coming from the C application. All the messages except INITIALIZE_WINDOW and COPY_GRAPH and QUIT will be put on the pipe corresponding to the appropriate window (messages are processed in FIFO order In case of INITIALIZE_WINDOW the data structure associated with a winow is created (including the pipes. In case of COPY_GRAPH a message must be placed on both the source and the target window's pipe. In case of QUIT all data structures are disassembled and then the tcl application is killed. */ r_bufid = nreceive_msg(ANYONE, ANYTHING); if (r_bufid > 0){ bufinfo(r_bufid, &bytes, &msgtag, &sender); switch (msgtag){ case CTOI_INITIALIZE_WINDOW: /* get the name of the new window */ receive_str(name); receive_str(title); /* if a window with this name already exists: error */ i = find_window(dgp->window_num, dgp->windows, name); if ( i >= 0 ) { INTERMED_ERROR(name, msgtag, sender,ITOC_WINDOW_ALREADY_EXISTS); freebuf(r_bufid); break; } /* allocate space for the new window */ win = init_dgwin(dgp, sender, name, title); /* set up the window description */ receive_int_array(&number, 1); copy_win_desc_from_par(win, &dgp->par); for ( ; number > 0; number-- ) { /* read out the key - value pairs */ receive_int_array(&key, 1); set_window_desc_pvm(key, win); } freebuf(r_bufid); break; case CTOI_COPY_GRAPH: /* Copy source's graph into target's window. Here a message is placed onto both target's and source's pipe so that they can wait for each other before the actual copying happens (shake hands) */ receive_str(target); receive_str(source); i = find_window(dgp->window_num, dgp->windows, target); if (i < 0) { /* target doesn't exist, send error message */ INTERMED_ERROR(target, msgtag, sender,ITOC_WINDOW_DOESNT_EXIST); freebuf(r_bufid); break; } j = find_window(dgp->window_num, dgp->windows, source); if (j < 0) { /* source doesn't exist, send error message */ INTERMED_ERROR(source, msgtag, sender,ITOC_WINDOW_DOESNT_EXIST); freebuf(r_bufid); break; } bufid = init_send(DataInPlace); msgtag = WAITING_TO_GET_A_COPY; send_int_array(&msgtag, 1); send_str(source); add_msg(dgp->windows[i], bufid); setsbuf(0); bufid = init_send(DataInPlace); msgtag = WAITING_TO_BE_COPIED; send_int_array(&msgtag, 1); send_str(target); add_msg(dgp->windows[j], bufid); setsbuf(0); freebuf(r_bufid); break; case CTOI_QUIT: /* quit from all windows, disassemble data structures. * (actually, this will happen on the top of the while loop...) */ if (! dgp->waiting_to_die) dgp->waiting_to_die = TRUE; freebuf(r_bufid); break; case CTOI_YOU_CAN_DIE: /* quit from all windows, disassemble data structures. * (actually, this will happen on the top of the while loop...) * and die */ dgp->waiting_to_die = 2 * TRUE; freebuf(r_bufid); break; default: /* Check if window with name exists. If not, send back error message. If yes, copy the message over to window's pipe. */ receive_str(name); len = strlen(name); i = find_window(dgp->window_num, dgp->windows, name); if (i < 0){ /* there is no window of that name: send error message */ INTERMED_ERROR(name, msgtag, sender,ITOC_WINDOW_DOESNT_EXIST); freebuf(r_bufid); break; } add_msg(dgp->windows[i], r_bufid); setrbuf(0); break; } /* end switch */ } /* endif r_bufid > 0 */ if (dgp->waiting_to_die) continue; /* Process one message from each window's pipe. */ for ( i = 0; i < dgp->window_num; i++ ) { win = dgp->windows[i]; /* if wait_for_click is set, skip */ if ( win->wait_for_click ) continue; /* if window is waiting to be copied or waiting to get a copy, skip */ if ( win->copy_status ) continue; /* if no message in the pipe, skip */ if (win->buf.bufread == -1) continue; /* else: process the message .... */ msgtag = 0; r_bufid = get_next_msg(win); setrbuf(r_bufid); bufinfo(r_bufid, &bytes, &msgtag, &sender); if (msgtag == 0){ /* This means that the message was locally 'hand-packed' */ receive_int_array(&msgtag, 1); } switch ( msgtag ) { case CTOI_USER_MESSAGE: #ifdef USE_SYM_APPLICATION user_dg_process_message(win->user, win, write_to); #endif break; case CTOI_QUIT_WINDOW: /* delete this window */ spprint(write_to, "Igd_QuitWindow %u\n", win->id); free_window(&dgp->window_num, dgp->windows, i); i--; break; case CTOI_CHANGE_WINDOW_DESC: /* change window descriptions */ receive_int_array(&number, 1); for ( ; number > 0; number-- ) { /* read out the key - value pairs */ receive_int_array(&key, 1); set_window_desc_pvm(key, win); } desc = &(win->desc); if ( win->window_displayed ) { spprint(write_to, "Igd_SetAndExecuteWindowDesc %u %i %i %i %i %i %i %i {%s} {%s} %i %i %i %f {%s} {%s} {%s}\n", win->id, desc->canvas_width, desc->canvas_height, desc->viewable_width, desc->viewable_height, desc->disp_nodelabels, desc->disp_nodeweights, desc->disp_edgeweights, desc->node_dash, desc->edge_dash, desc->node_radius, desc->interactive_mode, desc->mouse_tracking, desc->scale_factor, desc->nodelabel_font, desc->nodeweight_font, desc->edgeweight_font); } break; case CTOI_SET_GRAPH: case CTOI_SET_AND_DRAW_GRAPH: /* define the graph corresponding to this window */ g = &(win->g); FREE(g->nodes); FREE(g->edges); receive_int_array(&g->nodenum, 1); if ( g->nodenum ) { nodes = g->nodes = (dg_node *) malloc(g->nodenum * sizeof(dg_node)); for ( j = 0; j < g->nodenum; j++ ) { read_node_desc_from_pvm(nodes+j, win); } } receive_int_array(&g->edgenum, 1); if ( g->edgenum ) { edges = g->edges = (dg_edge *) malloc(g->edgenum * sizeof(dg_edge)); for ( j = 0; j < g->edgenum; j++ ) { read_edge_desc_from_pvm(edges+j, win); } } if ( msgtag == CTOI_SET_AND_DRAW_GRAPH || win->window_displayed ) display_graph_on_canvas(win, write_to); break; case CTOI_DRAW_GRAPH: /* first erase/create the window itself, then display all the nodes and edges */ display_graph_on_canvas(win, write_to); break; case CTOI_DELETE_GRAPH: /* delete the data structure of the graph and erase its window if open */ FREE(win->g.nodes); FREE(win->g.edges); win->g.nodenum = win->g.deleted_nodenum = 0; win->g.edgenum = win->g.deleted_edgenum = 0; if ( win->window_displayed ){ spprint(write_to, "Igd_EraseWindow %u\n", win->id); } break; case CTOI_WAIT_FOR_CLICK_NO_REPORT: /* window will not get any messages until the Continue button is pressed. the window has to be open to have an effect */ if ( win->window_displayed ) { win->wait_for_click = 1; spprint(write_to, "Igd_CApplWaitForClick %u\n", win->id); } else { INTERMED_ERROR(win->name, msgtag, win->owner_tid, ITOC_WINDOW_ISNT_DISPLAYED); } break; case CTOI_WAIT_FOR_CLICK_AND_REPORT: /* window will not get any messages until the Continue button is pressed. the window has to be open to have an effect. the owner gets a message */ if ( win->window_displayed ) { win->wait_for_click = 2; spprint(write_to, "Igd_CApplWaitForClick %u\n", win->id); } else { INTERMED_ERROR(win->name, msgtag, win->owner_tid, ITOC_WINDOW_ISNT_DISPLAYED); } break; case CTOI_SAVE_GRAPH_TO_FILE: /* save the graph into a file (only if it is displayed!) */ receive_str(fname); if ( win->window_displayed ) { spprint(write_to, "Igd_SaveGraph %u {%s}\n", win->id, fname); } else { INTERMED_ERROR(win->name, msgtag, win->owner_tid, ITOC_WINDOW_ISNT_DISPLAYED); } break; case CTOI_SAVE_GRAPH_PS_TO_FILE: /* save postscript of the picture displayed. works only if window is displayed. */ receive_str(fname); if ( win->window_displayed ) { spprint(write_to, "Igd_SavePs %u {%s}\n", win->id, fname); } else { INTERMED_ERROR(win->name, msgtag, win->owner_tid, ITOC_WINDOW_ISNT_DISPLAYED); } break; case CTOI_CLONE_WINDOW: /* clone this window. if window is not displayed, only the graph data structure will be copied over. */ /* wait_for_click, copy_status and text will not be copied over. */ receive_str(name2); receive_str(title2); if ( find_window(dgp->window_num, dgp->windows, name2) >= 0 ) { INTERMED_ERROR(win->name, msgtag, sender, ITOC_WINDOW_ALREADY_EXISTS); break; } new_win = init_dgwin(dgp, sender, name2, title2); copy_window_structure(new_win, win); if ( win->window_displayed ) { spprint(write_to, "Igd_CopyWindowDesc %u %u\n", new_win->id, win->id); spprint(write_to, "Igd_InitWindow %u {%s}\n", new_win->id, title2); spprint(write_to, "Igd_DisplayWindow %u\n", new_win->id); spprint(write_to, "Igd_EnableCAppl %u\n", new_win->id); spprint(write_to, "Igd_CopyGraph %u %u\n", new_win->id,win->id); new_win->window_displayed = 1; } break; case CTOI_RENAME_WINDOW: /* change the title of the window */ receive_str(win->title); if ( win->window_displayed ){ spprint(write_to, "Igd_RenameWindow %u {%s}\n", win->id, win->title); } break; case CTOI_RESIZE_VIEWABLE_WINDOW: /* change the sizes of canvas */ receive_int_array(&win->desc.viewable_width, 1); receive_int_array(&win->desc.viewable_height, 1); if ( win->window_displayed ){ spprint(write_to, "Igd_ResizeViewableWindow %u %i %i\n", win->id, win->desc.viewable_width, win->desc.viewable_height); } break; case CTOI_RESIZE_CANVAS: /* change the size of the canvas */ receive_int_array(&win->desc.canvas_width, 1); receive_int_array(&win->desc.canvas_height, 1); if ( win->window_displayed ){ spprint(write_to, "Igd_ResizeCanvas %u %i %i\n", win->id, win->desc.canvas_width, win->desc.canvas_height); } break; case WAITING_TO_GET_A_COPY: /* Read out the name of the source-graph from the pipe. If the source-graph is waiting to be copied, source and target have found each other */ receive_str(win->source) ; win->copy_status = 2; j = find_window(dgp->window_num, dgp->windows, win->source); if ( j >= 0 && dgp->windows[j]->copy_status == 1 ) { /* source graph exists and it is waiting to be copied */ source_win = dgp->windows[j]; /* copy the data structure */ copy_window_structure(win, source_win); /* if the window is displayed, change picture */ if ( win->window_displayed ) { display_graph_on_canvas(win, write_to); } /* zero out the copy stati */ win->copy_status = 0; win->source[0] = 0; source_win->copy_status = 0; source_win->target[0] = 0; } break; case WAITING_TO_BE_COPIED: /* Read out the name of the target graph from the pipe. If the target-graph is waiting to get a copy, source and target have found each other. */ receive_str(win->target); win->copy_status = 1; j = find_window(dgp->window_num, dgp->windows, win->target); if ( j >= 0 && dgp->windows[j]->copy_status == 2 ) { /* target exists and waiting for a copy */ target_win = dgp->windows[j]; /* copy the data structure */ copy_window_structure(target_win, win); /* if the target window is displayed, update the picture */ if ( target_win->window_displayed ) { display_graph_on_canvas(target_win, write_to); } /* zero out the copy stati */ win->copy_status = 0; win->target[0] = 0; target_win->copy_status = 0; target_win->source[0] = 0; } break; case CTOI_MODIFY_GRAPH: /* Make changes in the graph. The data structure is updated, and if the window is displayed, the picture gets updated, too */ /* The message is in keyword - description pairs, with the END_OF_MESSAGE keyword at the end. We switch on the keyword */ do { receive_int_array(&keyword, 1); switch ( keyword ) { case MODIFY_ADD_NODES: /* same format as in SET_GRAPH */ receive_int_array(&add_nodenum, 1); if ( add_nodenum ) { g = &(win->g); nodenum = g->nodenum; nodes = g->nodes = (dg_node *) realloc(g->nodes, (nodenum + add_nodenum) * sizeof(dg_node)); for (j = 0, new_nodenum = nodenum; j < add_nodenum; j++) { read_node_desc_from_pvm(nodes+new_nodenum, win); if (find_node(nodes[new_nodenum].node_id, g) < 0) new_nodenum++; } g->nodenum = new_nodenum; if ( win->window_displayed ) { for ( j = nodenum; j < new_nodenum; j++ ) { nod = nodes + j; spprint(write_to, "Igd_MakeNode %u %i %i %i {%s} {%s} %i\n", win->id, nod->node_id, nod->posx, nod->posy, nod->label, nod->dash, nod->radius); if ( *nod->weight != 0 ){ spprint(write_to, "Igd_MakeNodeWeight %u %i {%s}\n", win->id, nod->node_id, nod->weight); } } } } break; case MODIFY_CHANGE_WEIGHTS_OF_NODES: /* change weights of nodes. nodes not in the graph or nodes already deleted are skipped, no error message is given. */ g = &(win->g); receive_int_array(&change_nodenum, 1); for ( j = 0; j < change_nodenum; j++ ) { receive_int_array(&node_id, 1); receive_str(new_weight); if ( (k = find_node(node_id, g)) >= 0 ) { strcpy(g->nodes[k].weight, new_weight); if ( win->window_displayed ) { strcpy(old_weight, g->nodes[k].weight); if ( *old_weight != 0 ) { if ( *new_weight != 0 ) { spprint(write_to, "Igd_ChangeOneNodeWeight %u %i {%s}\n" , win->id, node_id, new_weight); } else { /* new weight == 0 */ spprint(write_to, "Igd_DeleteNodeWeight %u %i\n", win->id, node_id); } } else { /* no weight before */ if ( *new_weight != 0 ) { spprint(write_to, "Igd_MakeNodeWeight %u %i {%s}\n", win->id, node_id, new_weight); } } } } } break; case MODIFY_CHANGE_LABELS_OF_NODES: /* change labels of nodes. nodes not in the graph or nodes already deleted are skipped, no error message is given */ g = &(win->g); receive_int_array(&change_nodenum, 1); for ( j = 0; j < change_nodenum; j++ ) { receive_int_array(&node_id, 1); receive_str(new_label); if ( (k = find_node(node_id, g)) >= 0 ) { strcpy(g->nodes[k].label, new_label); if ( win->window_displayed ) { spprint(write_to, "Igd_ChangeOneNodeLabel %u %i {%s}\n", win->id, node_id, new_label); } } } break; case MODIFY_CHANGE_DASH_OF_NODES: /* change dash pattern of individual nodes. nodes not in the graph will not cause error messages */ g = &(win->g); receive_int_array(&change_nodenum, 1); for ( j = 0; j < change_nodenum; j++ ) { receive_int_array(&node_id, 1); receive_str(new_dash); if ( (k = find_node(node_id, g)) >= 0 ) { strcpy(g->nodes[k].dash, new_dash); if ( win->window_displayed ){ spprint(write_to, "Igd_ChangeOneNodeDash %u %i {%s}\n", win->id, node_id, new_dash); } } } break; case MODIFY_CHANGE_RADII_OF_NODES: /* change radii of individual nodes. nodes not in the graph will not cause error messages */ g = &(win->g); receive_int_array(&change_nodenum, 1); for ( j = 0; j < change_nodenum; j++ ) { receive_int_array(&node_id, 1); receive_int_array(&new_radius, 1); if ( (k = find_node(node_id, g)) >= 0 ) { g->nodes[k].radius = new_radius; if ( win->window_displayed ){ spprint(write_to, "Igd_ChangeOneNodeRadius %u %i %i\n", win->id, node_id, new_radius); } } } break; case MODIFY_DELETE_NODES: /* nodes not in the graph will not cause error messages */ receive_int_array(&delete_nodenum, 1); if ( delete_nodenum ) { g = &(win->g); old_deleted_nodenum = g->deleted_nodenum; for ( j = 0; j < delete_nodenum; j++ ) { receive_int_array(&node_id, 1); if ( (k = find_node(node_id, g)) >= 0 ) { g->nodes[k].deleted = 1; g->deleted_nodenum++; if ( win->window_displayed ){ spprint(write_to, "Igd_DeleteNode %u %i\n", win->id, node_id); } } } if ( g->deleted_nodenum > old_deleted_nodenum ) { /* mark edges that have at least one deleted endpoint to be deleted. Igd_DeleteNode already took care of deleting these edges from the picture */ for (k=g->edgenum-1, edg=g->edges; k >= 0; k--, edg++) if ( ! edg->deleted && ((find_node(edg->tail, g) < 0) || (find_node(edg->head, g) < 0))){ edg->deleted = 1; g->deleted_edgenum++; } } /* if too many nodes and/or edges have been deleted, compress the graph */ if ( g->deleted_nodenum > 0.1 * g->nodenum || g->deleted_edgenum > 0.1 * g->edgenum ) compress_graph(g); } break; case MODIFY_ADD_EDGES: /* same format as in SET_GRAPH. Nonvalid edges (one or both endpoints is not in the graph will not cause an error message. */ receive_int_array(&add_edgenum, 1); if ( add_edgenum ) { g = &(win->g); edgenum = g->edgenum; edges = g->edges = (dg_edge *) realloc(g->edges, (edgenum+add_edgenum)*sizeof(dg_edge)); for (j = 0, new_edgenum = edgenum; j < add_edgenum; j++) { edg = edges + new_edgenum; read_edge_desc_from_pvm(edg, win); if ((find_edge(edg->edge_id, g) < 0) && (find_node(edg->tail, g) >= 0) && (find_node(edg->head, g) >= 0)) new_edgenum++; } g->edgenum = new_edgenum; if ( win->window_displayed ) { for ( j = edgenum; j < new_edgenum; j++ ) { edg = edges + j; spprint(write_to, "Igd_MakeEdge %u %i %i %i {%s}\n", win->id, edg->edge_id, edg->tail, edg->head, edg->dash); if ( *edg->weight != 0 ){ spprint(write_to, "Igd_MakeEdgeWeight %u %i {%s}\n", win->id, edg->edge_id, edg->weight); } } } } break; case MODIFY_CHANGE_WEIGHTS_OF_EDGES: /* change weights of edges. edges not in the graph or edges already deleted are skipped, no error message is given. */ g = &(win->g); receive_int_array(&change_edgenum, 1); for ( j = 0; j < change_edgenum; j++ ) { receive_int_array(&edge_id, 1); receive_str(new_weight); if ( (k = find_edge(edge_id, g)) >= 0 ) { strcpy(g->edges[k].weight, new_weight); if ( win->window_displayed ) { strcpy(old_weight, g->edges[k].weight); if ( *old_weight != 0 ) { if ( *new_weight != 0 ) { spprint(write_to, "Igd_ChangeOneEdgeWeight %u %i {%s}\n" , win->id, edge_id, new_weight); } else { /* new weight : 0 */ spprint(write_to, "Igd_DeleteEdgeWeight %u %i\n", win->id, edge_id); } } else { /* no weight before */ if ( *new_weight != 0 ) { spprint(write_to, "Igd_MakeEdgeWeight %u %i {%s}\n", win->id, edge_id, new_weight); } } } } } break; case MODIFY_CHANGE_DASH_OF_EDGES: /* change dash pattern of individual edges. edges not in the graph will not cause error messages */ g = &(win->g); receive_int_array(&change_edgenum, 1); for ( j = 0; j < change_edgenum; j++ ) { receive_int_array(&edge_id, 1); receive_str(new_dash); if ( (k = find_edge(edge_id, g)) >= 0 ) { strcpy(g->edges[k].dash, new_dash); if ( win->window_displayed ){ spprint(write_to, "Igd_ChangeOneEdgeDash %u %i {%s}\n", win->id, edge_id, new_dash); } } } break; case MODIFY_DELETE_EDGES: /* edges not in the graph will not cause error messages */ g = &(win->g); receive_int_array(&delete_edgenum, 1); for ( j = 0; j < delete_edgenum; j++ ) { receive_int_array(&edge_id, 1); if ( (k = find_edge(edge_id, g)) >= 0 ) { g->edges[k].deleted = 1; g->deleted_edgenum++; if ( win->window_displayed ) { spprint(write_to, "Igd_DeleteEdge %u %i\n", win->id, edge_id); } } } /* if too many edges have been deleted, compress the graph */ if ( g->deleted_edgenum > 0.1 * g->edgenum ) compress_graph(g); break; case MODIFY_DELETE_ALL_EDGES: /* will delete all edges from the graph */ g = &(win->g); if ( win->window_displayed ) { for ( j = 0; j < g->edgenum; j++ ) if ( ! g->edges[j].deleted ){ spprint(write_to, "Igd_DeleteEdge %u %i\n", win->id, g->edges[j].edge_id); } } FREE(g->edges); g->edgenum = 0; break; case MODIFY_END_OF_MESSAGE: break; default: printf("Unrecognized keyword %i\n", keyword); break; } /* end switch (keyword) */ } while ( keyword != MODIFY_END_OF_MESSAGE ); break; case CTOI_CLEAR_MESSAGE: if ( win->window_displayed ) { spprint(write_to, "Igd_CApplClearCmsg %u\n", win->id); } break; case CTOI_PRINT_MESSAGE: if ( win->window_displayed ) { str = malloc(bytes); receive_str(str); spprint(write_to, "Igd_CApplSetCmsg %u {%s}\n", win->id, str); FREE(str); } break; case CTOI_APPEND_MESSAGE: if ( win->window_displayed ) { str = malloc(bytes); receive_str(str); spprint(write_to, "Igd_CApplAppendCmsg %u {%s}\n", win->id,str); FREE(str); } break; default: printf("Unknown message tag: %i\n", msgtag); break; } /* end switch (msgtag) */ freebuf(r_bufid); } /* end for */ } /* end while */ return(0); }