/* * MapInfo.c -- MapInfo interface. * * Authors : Patrick Lecoanet. * Creation date : * * $Id$ */ /* * Copyright (c) 1993 - 2005 CENA, Patrick Lecoanet -- * * See the file "Copyright" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #ifndef _WIN32 #include #include #else #include #endif #include "MapInfo.h" #include "tkZinc.h" #include #include static const char rcsid[] = "$Id$"; static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $"; /* *----------------------------------------------------------------------- * * New types * *----------------------------------------------------------------------- */ typedef struct { ZnPtr tag; ZnMapInfoLineStyle style; int width; ZnPoint center; unsigned int radius; int start_angle; int extend; } ZnMapInfoArcStruct, *ZnMapInfoArc; typedef struct { ZnPtr tag; ZnMapInfoLineStyle style; int width; ZnPoint from; ZnPoint to; unsigned int num_marks; ZnPoint *marks; } ZnMapInfoLineStruct, *ZnMapInfoLine; typedef struct { ZnPtr tag; ZnPoint at; char symbol[2]; } ZnMapInfoSymbolStruct, *ZnMapInfoSymbol; typedef struct { ZnPtr tag; ZnMapInfoTextStyle text_style; ZnMapInfoLineStyle line_style; ZnPoint at; char *text; } ZnMapInfoTextStruct, *ZnMapInfoText; typedef struct { char *name; ZnList lines; ZnList symbols; ZnList texts; ZnList arcs; } ZnMapInfoStruct, *ZnMapInfo; #define MARKERS_SPACING 80.0 /* 10 nautic miles in 1/8 of a mile */ #define BASE_ALLOC_SIZE 8 /* *----------------------------------------------------------------------- * * Macros. * *----------------------------------------------------------------------- */ #define NOT_MARKED_STYLE(style) \ ((style) == ZnMapInfoLineMarked ? ZnMapInfoLineSimple : (style)); /* *----------------------------------------------------------------------- * * ComputeLineMarks -- * Add marks to a line in the marks substructure. * *----------------------------------------------------------------------- */ static void ComputeLineMarks(ZnMapInfoLine marked_line) { ZnDim length; ZnPos x_from = marked_line->from.x; ZnPos y_from = marked_line->from.y; ZnPos x_to = marked_line->to.x; ZnPos y_to = marked_line->to.y; ZnPos delta_x = x_from - x_to; ZnPos delta_y = y_from - y_to; ZnPos step_x, step_y; unsigned int j; length = sqrt(delta_x * delta_x + delta_y * delta_y); step_x = (x_to - x_from) * MARKERS_SPACING / length; step_y = (y_to - y_from) * MARKERS_SPACING / length; marked_line->num_marks = (int) (length / MARKERS_SPACING); /* We don't want markers at ends, so we get rid of the last one if it is at an end */ if (fmod(length, MARKERS_SPACING) == 0.0) { (marked_line->num_marks)--; } if (marked_line->num_marks) { marked_line->marks = ZnMalloc(marked_line->num_marks * sizeof(ZnPoint)); } for (j = 0; j < marked_line->num_marks; j++) { marked_line->marks[j].x = x_from + ((j + 1) * step_x); marked_line->marks[j].y = y_from + ((j + 1) * step_y); } } static ZnMapInfoId ZnMapInfoCreate(char *name) { ZnMapInfo new_map; new_map = ZnMalloc(sizeof(ZnMapInfoStruct)); memset((char *) new_map, 0, sizeof(ZnMapInfoStruct)); if (!name) { name = ""; } new_map->name = (char *) ZnMalloc(strlen(name)+1); /*printf("Nouvelle MapInfo: %s\n", name);*/ strcpy(new_map->name, name); return((ZnMapInfoId) new_map); } static char * ZnMapInfoName(ZnMapInfoId map_info) { if (!map_info) { return ""; } return ((ZnMapInfo) map_info)->name; } static ZnMapInfoId ZnMapInfoDuplicate(ZnMapInfoId map_info) { ZnMapInfo cur_map = map_info; ZnMapInfo new_map; unsigned int i, num_lines, num_texts; ZnMapInfoText new_texts, cur_texts; ZnMapInfoLine new_lines, cur_lines; if (!cur_map) { return ((ZnMapInfoId) NULL); } new_map = ZnMapInfoCreate(cur_map->name); if (cur_map->lines) { new_map->lines = ZnListDuplicate(cur_map->lines); cur_lines = ZnListArray(cur_map->lines); new_lines = ZnListArray(new_map->lines); num_lines = ZnListSize(cur_map->lines); for (i = 0; i < num_lines; i++) { if (new_lines[i].style == ZnMapInfoLineMarked) { new_lines[i].marks = ZnMalloc(new_lines[i].num_marks * sizeof(ZnPoint)); memcpy((char *) new_lines[i].marks, (char *) cur_lines[i].marks, new_lines[i].num_marks * sizeof(ZnPoint)); } } } if (cur_map->symbols) { new_map->symbols = ZnListDuplicate(cur_map->symbols); } if (cur_map->texts) { new_map->texts = ZnListDuplicate(cur_map->texts); cur_texts = ZnListArray(cur_map->texts); new_texts = ZnListArray(new_map->texts); num_texts = ZnListSize(cur_map->texts); for (i = 0; i < num_texts; i++) { new_texts[i].text = ZnMalloc(strlen(cur_texts[i].text) + 1); strcpy(new_texts[i].text, cur_texts[i].text); } } if (cur_map->arcs) { new_map->arcs = ZnListDuplicate(cur_map->arcs); } return((ZnMapInfoId) new_map); } static void ZnMapInfoDelete(ZnMapInfoId map_info) { ZnMapInfo cur_map = map_info; unsigned int i, num_texts, num_lines; ZnMapInfoText cur_texts; ZnMapInfoLine cur_lines; if (cur_map) { if (cur_map->texts) { num_texts = ZnListSize(cur_map->texts); cur_texts = ZnListArray(cur_map->texts); for (i = 0; i < num_texts; i++) { ZnFree(cur_texts[i].text); } ZnListFree(cur_map->texts); } if (cur_map->lines) { num_lines = ZnListSize(cur_map->lines); cur_lines = ZnListArray(cur_map->lines); for (i = 0; i < num_lines; i++) { if (cur_lines[i].style == ZnMapInfoLineMarked) { ZnFree(cur_lines[i].marks); } } ZnListFree(cur_map->lines); } if (cur_map->symbols) { ZnListFree(cur_map->symbols); } if (cur_map->arcs) { ZnListFree(cur_map->arcs); } ZnFree(cur_map->name); ZnFree(cur_map); } } static void ZnMapInfoEmpty(ZnMapInfoId map_info) { ZnMapInfo cur_map = map_info; if (cur_map) { if (cur_map->texts) { ZnListEmpty(cur_map->texts); } if (cur_map->lines) { ZnListEmpty(cur_map->lines); } if (cur_map->symbols) { ZnListEmpty(cur_map->symbols); } if (cur_map->arcs) { ZnListEmpty(cur_map->arcs); } } } static void ZnMapInfoAddLine(ZnMapInfoId map_info, unsigned int index, ZnPtr tag, ZnMapInfoLineStyle line_style, ZnDim line_width, ZnPos x_from, ZnPos y_from, ZnPos x_to, ZnPos y_to) { ZnMapInfo cur_map = map_info; ZnMapInfoLineStruct line_struct; if (cur_map) { if (!cur_map->lines) { cur_map->lines = ZnListNew(16, sizeof(ZnMapInfoLineStruct)); } line_struct.style = line_style; if (line_width == 1.0) { line_struct.width = 0; } else { line_struct.width = (int) line_width; } line_struct.tag = tag; line_struct.from.x = x_from; line_struct.from.y = y_from; line_struct.to.x = x_to; line_struct.to.y = y_to; /*printf("Ajout de la ligne: %d %d %d %d\n", x_from, y_from, x_to, y_to);*/ if (line_style == ZnMapInfoLineMarked) { ComputeLineMarks(&line_struct); } ZnListAdd(cur_map->lines, &line_struct, index); } } static void ZnMapInfoReplaceLine(ZnMapInfoId map_info, unsigned int index, ZnPtr tag, ZnMapInfoLineStyle line_style, ZnDim line_width, ZnPos x_from, ZnPos y_from, ZnPos x_to, ZnPos y_to) { ZnMapInfo cur_map = map_info; ZnMapInfoLine line_ptr; if (cur_map && cur_map->lines) { line_ptr = ZnListAt(cur_map->lines, index); if (line_ptr) { if (line_ptr->style == ZnMapInfoLineMarked) { ZnFree(line_ptr->marks); } line_ptr->style = line_style; if (line_width == 1.0) { line_ptr->width = 0; } else { line_ptr->width = (int) line_width; } line_ptr->tag = tag; line_ptr->from.x = x_from; line_ptr->from.y = y_from; line_ptr->to.x = x_to; line_ptr->to.y = y_to; if (line_ptr->style == ZnMapInfoLineMarked) { ComputeLineMarks(line_ptr); } } } } static void ZnMapInfoRemoveLine(ZnMapInfoId map_info, unsigned int index) { ZnMapInfo cur_map = map_info; ZnMapInfoLine line_ptr; if (cur_map && cur_map->lines) { line_ptr = ZnListAt(cur_map->lines, index); if (line_ptr) { if (line_ptr->style == ZnMapInfoLineMarked) { ZnFree(line_ptr->marks); } ZnListDelete(cur_map->lines, index); } } } void ZnMapInfoGetLine(ZnMapInfoId map_info, unsigned int index, ZnPtr *tag, ZnMapInfoLineStyle *line_style, ZnDim *line_width, ZnPos *x_from, ZnPos *y_from, ZnPos *x_to, ZnPos *y_to) { ZnMapInfo cur_map = map_info; ZnMapInfoLine line_ptr; if (cur_map && cur_map->lines) { line_ptr = ZnListAt(cur_map->lines, index); if (line_ptr) { if (tag) { *tag = line_ptr->tag; } if (line_style) { *line_style = line_ptr->style; } if (line_width) { if (line_ptr->width == 1.0) { *line_width = 0; } else { *line_width = line_ptr->width; } } if (x_from) { *x_from = line_ptr->from.x; } if (y_from) { *y_from = line_ptr->from.y; } if (x_to) { *x_to = line_ptr->to.x; } if (y_to) { *y_to = line_ptr->to.y; } } } } void ZnMapInfoGetMarks(ZnMapInfoId map_info, unsigned int index, ZnPoint **marks, unsigned int *num_marks) { ZnMapInfo cur_map = map_info; ZnMapInfoLine line_ptr; if (cur_map && cur_map->lines) { line_ptr = ZnListAt(cur_map->lines, index); if (line_ptr && line_ptr->style == ZnMapInfoLineMarked) { if (marks) { *marks = line_ptr->marks; } if (num_marks) { *num_marks = line_ptr->num_marks; } } } } unsigned int ZnMapInfoNumLines(ZnMapInfoId map_info) { ZnMapInfo cur_map = map_info; if (cur_map && cur_map->lines) { return ZnListSize(cur_map->lines); } else { return 0; } } static void ZnMapInfoAddSymbol(ZnMapInfoId map_info, unsigned int index, ZnPtr tag, ZnPos x, ZnPos y, int symbol) { ZnMapInfo cur_map = map_info; ZnMapInfoSymbolStruct symbol_struct; if (cur_map) { if (!cur_map->symbols) { cur_map->symbols = ZnListNew(16, sizeof(ZnMapInfoSymbolStruct)); } symbol_struct.tag = tag; symbol_struct.at.x = x; symbol_struct.at.y = y; symbol_struct.symbol[0] = symbol; symbol_struct.symbol[1] = '\0'; ZnListAdd(cur_map->symbols, &symbol_struct, index); } } static void ZnMapInfoReplaceSymbol(ZnMapInfoId map_info, unsigned int index, ZnPtr tag, ZnPos x, ZnPos y, int symbol) { ZnMapInfo cur_map = map_info; ZnMapInfoSymbolStruct symbol_struct; if (cur_map && cur_map->symbols) { symbol_struct.tag = tag; symbol_struct.at.x = x; symbol_struct.at.y = y; symbol_struct.symbol[0] = symbol; symbol_struct.symbol[1] = '\0'; ZnListAtPut(cur_map->symbols, &symbol_struct, index); } } static void ZnMapInfoRemoveSymbol(ZnMapInfoId map_info, unsigned int index) { ZnMapInfo cur_map = map_info; if (cur_map && cur_map->symbols) { ZnListDelete(cur_map->symbols, index); } } void ZnMapInfoGetSymbol(ZnMapInfoId map_info, unsigned int index, ZnPtr *tag, ZnPos *x, ZnPos *y, char *symbol) { ZnMapInfo cur_map = map_info; ZnMapInfoSymbol symbol_ptr; if (cur_map && cur_map->symbols) { symbol_ptr = ZnListAt(cur_map->symbols, index); if (symbol_ptr) { if (tag) { *tag = symbol_ptr->tag; } if (x) { *x = symbol_ptr->at.x; } if (y) { *y = symbol_ptr->at.y; } if (symbol) { *symbol = symbol_ptr->symbol[0]; } } } } unsigned int ZnMapInfoNumSymbols(ZnMapInfoId map_info) { ZnMapInfo cur_map = map_info; if (cur_map && cur_map->symbols) { return ZnListSize(cur_map->symbols); } else { return 0; } } static void ZnMapInfoAddText(ZnMapInfoId map_info, unsigned int index, ZnPtr tag, ZnMapInfoTextStyle text_style, ZnMapInfoLineStyle line_style, ZnPos x, ZnPos y, char *text) { ZnMapInfo cur_map = map_info; ZnMapInfoTextStruct text_struct; if (cur_map) { if (!cur_map->texts) { cur_map->texts = ZnListNew(16, sizeof(ZnMapInfoTextStruct)); } text_struct.tag = tag; text_struct.text_style = text_style; text_struct.line_style = NOT_MARKED_STYLE(line_style); text_struct.at.x = x; text_struct.at.y = y; text_struct.text = ZnMalloc(strlen(text) + 1); strcpy(text_struct.text, text); ZnListAdd(cur_map->texts, &text_struct, index); } } static void ZnMapInfoReplaceText(ZnMapInfoId map_info, unsigned int index, ZnPtr tag, ZnMapInfoTextStyle text_style, ZnMapInfoLineStyle line_style, ZnPos x, ZnPos y, char *text) { ZnMapInfo cur_map = map_info; ZnMapInfoText text_ptr; if (cur_map && cur_map->texts) { text_ptr = ZnListAt(cur_map->texts, index); if (text_ptr) { ZnFree(text_ptr->text); text_ptr->tag = tag; text_ptr->text_style = text_style; text_ptr->line_style = NOT_MARKED_STYLE(line_style); text_ptr->at.x = x; text_ptr->at.y = y; text_ptr->text = ZnMalloc(strlen(text) + 1); strcpy(text_ptr->text, text); } } } static void ZnMapInfoRemoveText(ZnMapInfoId map_info, unsigned int index) { ZnMapInfo cur_map = map_info; ZnMapInfoText text_ptr; if (cur_map && cur_map->texts) { text_ptr = ZnListAt(cur_map->texts, index); if (text_ptr) { ZnFree(text_ptr->text); ZnListDelete(cur_map->texts, index); } } } void ZnMapInfoGetText(ZnMapInfoId map_info, unsigned int index, ZnPtr *tag, ZnMapInfoTextStyle *text_style, ZnMapInfoLineStyle *line_style, ZnPos *x, ZnPos *y, char **text) { ZnMapInfo cur_map = map_info; ZnMapInfoText text_ptr; if (cur_map && cur_map->texts) { text_ptr = ZnListAt(cur_map->texts, index); if (text_ptr) { if (tag) { *tag = text_ptr->tag; } if (text_style) { *text_style = text_ptr->text_style; } if (line_style) { *line_style = text_ptr->line_style; } if (x) { *x = text_ptr->at.x; } if (y) { *y = text_ptr->at.y; } if (text) { *text = text_ptr->text; } } } } unsigned int ZnMapInfoNumTexts(ZnMapInfoId map_info) { ZnMapInfo cur_map = map_info; if (cur_map && cur_map->texts) { return ZnListSize(cur_map->texts); } else { return 0; } } static void ZnMapInfoAddArc(ZnMapInfoId map_info, unsigned int index, ZnPtr tag, ZnMapInfoLineStyle line_style, ZnDim line_width, ZnPos center_x, ZnPos center_y, ZnDim radius, ZnReal start_angle, ZnReal extend) { ZnMapInfo cur_map = map_info; ZnMapInfoArcStruct arc_struct; if (cur_map) { if (!cur_map->arcs) { cur_map->arcs = ZnListNew(16, sizeof(ZnMapInfoArcStruct)); } arc_struct.style = NOT_MARKED_STYLE(line_style); if (line_width == 1.0) { arc_struct.width = 0; } else { arc_struct.width = (int) line_width; } arc_struct.tag = tag; arc_struct.center.x = center_x; arc_struct.center.y = center_y; arc_struct.radius = (int) radius; arc_struct.start_angle = (int) start_angle; arc_struct.extend = (int) extend; ZnListAdd(cur_map->arcs, &arc_struct, index); } } static void ZnMapInfoReplaceArc(ZnMapInfoId map_info, unsigned int index, ZnPtr tag, ZnMapInfoLineStyle line_style, ZnDim line_width, ZnPos center_x, ZnPos center_y, ZnDim radius, ZnReal start_angle, ZnReal extend) { ZnMapInfo cur_map = map_info; ZnMapInfoArc arc_ptr; if (cur_map && cur_map->arcs) { arc_ptr = ZnListAt(cur_map->arcs, index); if (arc_ptr) { arc_ptr->style = NOT_MARKED_STYLE(line_style); if (line_width == 1.0) { arc_ptr->width = 0; } else { arc_ptr->width = (int) line_width; } arc_ptr->tag = tag; arc_ptr->center.x = center_x; arc_ptr->center.y = center_y; arc_ptr->radius = (int) radius; arc_ptr->start_angle = (int) start_angle; arc_ptr->extend = (int) extend; } } } static void ZnMapInfoRemoveArc(ZnMapInfoId map_info, unsigned int index) { ZnMapInfo cur_map = map_info; ZnMapInfoArc arc_ptr; if (cur_map && cur_map->arcs) { arc_ptr = ZnListAt(cur_map->arcs, index); if (arc_ptr) { ZnListDelete(cur_map->arcs, index); } } } void ZnMapInfoGetArc(ZnMapInfoId map_info, unsigned int index, ZnPtr *tag, ZnMapInfoLineStyle *line_style, ZnDim *line_width, ZnPos *center_x, ZnPos *center_y, ZnDim *radius, ZnReal *start_angle, ZnReal *extend) { ZnMapInfo cur_map = map_info; ZnMapInfoArc arc_ptr; if (cur_map && cur_map->arcs) { arc_ptr = ZnListAt(cur_map->arcs, index); if (arc_ptr) { if (tag) { *tag = arc_ptr->tag; } if (line_style) { *line_style = arc_ptr->style; } if (line_width) { if (arc_ptr->width == 1.0) { *line_width = 0; } else { *line_width = arc_ptr->width; } } if (center_x) { *center_x = arc_ptr->center.x; } if (center_y) { *center_y = arc_ptr->center.y; } if (radius) { *radius = arc_ptr->radius; } if (start_angle) { *start_angle = arc_ptr->start_angle; } if (extend) { *extend = arc_ptr->extend; } } } } unsigned int ZnMapInfoNumArcs(ZnMapInfoId map_info) { ZnMapInfo cur_map = map_info; if (cur_map && cur_map->arcs) { return ZnListSize(cur_map->arcs); } else { return 0; } } static void ZnMapInfoScale(ZnMapInfoId map_info, ZnReal factor) { ZnMapInfo mp = map_info; int i, num; ZnMapInfoLine line_ptr; ZnMapInfoSymbol sym_ptr; ZnMapInfoText text_ptr; ZnMapInfoArc arc_ptr; if (mp && mp->lines) { num = ZnListSize(mp->lines); line_ptr = ZnListArray(mp->lines); for (i = 0; i < num; i++, line_ptr++) { line_ptr->from.x *= factor; line_ptr->from.y *= factor; line_ptr->to.x *= factor; line_ptr->to.y *= factor; } } if (mp && mp->symbols) { num = ZnListSize(mp->symbols); sym_ptr = ZnListArray(mp->symbols); for (i = 0; i < num; i++, sym_ptr++) { sym_ptr->at.x *= factor; sym_ptr->at.y *= factor; } } if (mp && mp->texts) { num = ZnListSize(mp->texts); text_ptr = ZnListArray(mp->texts); for (i = 0; i < num; i++, text_ptr++) { text_ptr->at.x *= factor; text_ptr->at.y *= factor; } } if (mp && mp->arcs) { num = ZnListSize(mp->arcs); arc_ptr = ZnListArray(mp->arcs); for (i = 0; i < num; i++, arc_ptr++) { arc_ptr->center.x *= factor; arc_ptr->center.y *= factor; arc_ptr->radius = (unsigned int) (arc_ptr->radius * factor); } } } static void ZnMapInfoTranslate(ZnMapInfoId map_info, ZnPos x, ZnPos y) { ZnMapInfo mp = map_info; int i, num; ZnMapInfoLine line_ptr; ZnMapInfoSymbol sym_ptr; ZnMapInfoText text_ptr; ZnMapInfoArc arc_ptr; if (mp && mp->lines) { num = ZnListSize(mp->lines); line_ptr = ZnListArray(mp->lines); for (i = 0; i < num; i++, line_ptr++) { line_ptr->from.x += x; line_ptr->from.y += y; line_ptr->to.x += x; line_ptr->to.y += y; } } if (mp && mp->symbols) { num = ZnListSize(mp->symbols); sym_ptr = ZnListArray(mp->symbols); for (i = 0; i < num; i++, sym_ptr++) { sym_ptr->at.x += x; sym_ptr->at.y += y; } } if (mp && mp->texts) { num = ZnListSize(mp->texts); text_ptr = ZnListArray(mp->texts); for (i = 0; i < num; i++, text_ptr++) { text_ptr->at.x += x; text_ptr->at.y += y; } } if (mp && mp->arcs) { num = ZnListSize(mp->arcs); arc_ptr = ZnListArray(mp->arcs); for (i = 0; i < num; i++, arc_ptr++) { arc_ptr->center.x += x; arc_ptr->center.y += y; } } } #define TEXT_SIZE 256 #define ntohi(n) ntohl((n)) /* *----------------------------------------------------------------------- * * Videomap record definition. Ints are assumed to be 4 bytes. * *----------------------------------------------------------------------- */ typedef struct { int id; /* Map id (internal) */ int dashed; /* Tell if vectors are dashed (exclusive with marked) */ int expanded; /* Device coordinates or world coordinates (ignored now) */ int marked; /* Tell if vectors are marked (exclusive with dashed) */ int color; /* drawing color (ignored now) */ int elements[50]; /* Element type ('P', 'V', 'T') */ int x[50]; /* Coordinates if 'P' or 'V' */ int y[50]; int symbol[50]; /* Filled if 'P' or 'V' */ int text[50]; /* Low order byte is ascii char if 'T' */ int num_elements; /* Number of elements */ } VideoMap; /* *----------------------------------------------------------------------- * * ReorderVidomap - reorder integers according to the endianess * *----------------------------------------------------------------------- */ static void ReorderVidomap(VideoMap *vm) { int loop; vm->id = ntohi((unsigned int) vm->id); vm->dashed = ntohi((unsigned int) vm->dashed); vm->expanded = ntohi((unsigned int) vm->expanded); vm->marked = ntohi((unsigned int) vm->marked); vm->color = ntohi((unsigned int) vm->color); for (loop = 0; loop < 50; loop++) { vm->elements[loop] = ntohi((unsigned int) vm->elements[loop]); vm->x[loop] = ntohi((unsigned int) vm->x[loop]); vm->y[loop] = ntohi((unsigned int) vm->y[loop]); vm->symbol[loop] = ntohi((unsigned int) vm->symbol[loop]); vm->text[loop] = ntohi((unsigned int) vm->text[loop]); } vm->num_elements = ntohi((unsigned int) vm->num_elements); } /* *----------------------------------------------------------------------- * * FillMap - Fill map with data in Videomap record vm. * *----------------------------------------------------------------------- */ static void FillMap(ZnMapInfoId map, VideoMap *vm) { int i; ZnBool has_start_pos = False; ZnPos x_cur=0, y_cur=0; char ch; ZnPos text_x=0, text_y=0; char text[TEXT_SIZE]; ZnBool in_text = False; ZnBool in_mod_text = False; unsigned int text_size=0; for (i = 0; i < vm->num_elements; i++) { switch(vm->elements[i] & 0xFF) { case 'p': case 'P': if (in_text) { in_text = in_mod_text = False; while (text[text_size - 1] == ' ') { text_size--; } text[text_size] = (char) 0; ZnMapInfoAddText(map, ZnMapInfoNumTexts(map), NULL, ZnMapInfoNormalText, ZnMapInfoLineSimple, text_x, text_y, text); } x_cur = (int) (short) vm->x[i]; y_cur = (int) (short) vm->y[i]; has_start_pos = True; if (vm->symbol[i]) { ZnMapInfoAddSymbol(map, ZnMapInfoNumSymbols(map), NULL, x_cur, y_cur, (char) vm->symbol[i]); } break; /* We gather consecutive 'T' elements in a text. We skip leading and trailing spaces and mod texts (between '@' and now obsolete) */ case 't': case 'T': if (!has_start_pos) { ZnWarning("Bogus map block, it has been discarded\n"); return; } if (in_text == False) { ch = (char) vm->text[i] & 0xFF; if (ch == '@') { if (in_mod_text == True) { in_mod_text = False; } else { in_mod_text = True; } } else if (in_mod_text == False) { in_text = True; text_size = 0; text_x = x_cur; text_y = y_cur; text[0] = (char) 0; } } if (in_text) { text[text_size] = (char) vm->text[i] & 0xFF; text_size++; } break; case 'v': case 'V': if (!has_start_pos) { ZnWarning("Bogus map block, it has been discarded\n"); return; } if (in_text) { in_text = in_mod_text = False; while (text[text_size - 1] == ' ') { text_size--; } text[text_size] = (char) 0; ZnMapInfoAddText(map, ZnMapInfoNumTexts(map), NULL, ZnMapInfoNormalText, ZnMapInfoLineSimple, text_x, text_y, text); } if (vm->dashed) { ZnMapInfoAddLine(map, ZnMapInfoNumLines(map), NULL, ZnMapInfoLineDashed, 0, x_cur, y_cur, (int) (short) vm->x[i], (int) (short) vm->y[i]); } else if (vm->marked) { ZnMapInfoAddLine(map, ZnMapInfoNumLines(map), NULL, ZnMapInfoLineMarked, 0, x_cur, y_cur, (int) (short) vm->x[i], (int) (short) vm->y[i]); } else { ZnMapInfoAddLine(map, ZnMapInfoNumLines(map), NULL, ZnMapInfoLineSimple, 0, x_cur, y_cur, (int) (short) vm->x[i], (int) (short) vm->y[i]); } x_cur = (int) (short) vm->x[i]; y_cur = (int) (short) vm->y[i]; if (vm->symbol[i]) { ZnMapInfoAddSymbol(map, ZnMapInfoNumSymbols(map), NULL, x_cur, y_cur, (char) vm->symbol[i]); } break; } } if (in_text) { in_text = in_mod_text = False; while (text[text_size - 1] == ' ') { text_size--; } text[text_size] = (char) 0; ZnMapInfoAddText(map, ZnMapInfoNumTexts(map), NULL, ZnMapInfoNormalText, ZnMapInfoLineSimple, text_x, text_y, text); } } /* *----------------------------------------------------------------------- * * ZnMapInfoGetVideomap - Load a mapinfo with the content of a videomap * file named 'filename'. Only the sub map 'index' will be loaded. * If successful a new mapinfo is returned, NULL otherwise. The * index is zero based. * *----------------------------------------------------------------------- */ static int ZnMapInfoGetVideomap(ZnMapInfoId map, char *filename, unsigned int index) { VideoMap current_vm; Tcl_Channel chan; unsigned int cur_index, cur_id; /* Open the specified map file. */ chan = Tcl_OpenFileChannel(NULL, filename, "r", 0); if (chan == NULL) { return TCL_ERROR; } if (Tcl_SetChannelOption(NULL, chan, "-translation", "binary") == TCL_ERROR) { return TCL_ERROR; } /* Load the map */ /* First skip the leading maps up to index. */ cur_index = 0; if (Tcl_Read(chan, (char *) ¤t_vm, sizeof(VideoMap)) != sizeof(VideoMap)) { goto error; } cur_id = ntohi((unsigned int) current_vm.id); while (cur_index != index) { if (Tcl_Read(chan, (char *) ¤t_vm, sizeof(VideoMap)) != sizeof(VideoMap)) { goto error; } if (cur_id != ntohi((unsigned int) current_vm.id)) { cur_index++; cur_id = ntohi((unsigned int) current_vm.id); } }; /* Then load all the map modules. */ do { ReorderVidomap(¤t_vm); FillMap(map, ¤t_vm); if ((Tcl_Read(chan, (char *) ¤t_vm, sizeof(VideoMap)) != sizeof(VideoMap)) && !Tcl_Eof(chan)) { goto error; } } while ((cur_id == ntohi((unsigned int) current_vm.id)) && !Tcl_Eof(chan)); Tcl_Close(NULL, chan); return TCL_OK; error: Tcl_Close(NULL, chan); return TCL_ERROR; } /* *----------------------------------------------------------------------- * * ZnMapInfoVideomapIds - Return the list of sub map ids contained in a * videomap file. This makes it possible to iterate through such * a file without stumbling on an error, to know how much maps * are there and to sort them according to their ids. * *----------------------------------------------------------------------- */ static ZnList ZnMapInfoVideomapIds(char *filename) { Tcl_Channel chan; VideoMap current_vm; unsigned int cur_id; ZnList ids; /* Open the specified map file. */ chan = Tcl_OpenFileChannel(NULL, filename, "r", 0); if (chan == NULL) { return NULL; } if (Tcl_SetChannelOption(NULL, chan, "-translation", "binary") == TCL_ERROR) { return NULL; } if (Tcl_Read(chan, (char *) ¤t_vm, sizeof(VideoMap)) != sizeof(VideoMap)) { error: Tcl_Close(NULL, chan); return NULL; } cur_id = ntohi((unsigned int) current_vm.id); ids = ZnListNew(16, sizeof(int)); /*printf("id %d\n", cur_id);*/ ZnListAdd(ids, &cur_id, ZnListTail); do { if (Tcl_Read(chan, (char *) ¤t_vm, sizeof(VideoMap)) != sizeof(VideoMap)) { ZnListFree(ids); goto error; } if (cur_id != ntohi((unsigned int) current_vm.id)) { cur_id = ntohi((unsigned int) current_vm.id); /*printf("id %d\n", cur_id);*/ ZnListAdd(ids, &cur_id, ZnListTail); } } while (!Tcl_Eof(chan)); Tcl_Close(NULL, chan); return ids; } /* *-------------------------------------------------------------------------- * * ZnMapInfo and Videomapstuff that should go eventually in its own file. * *-------------------------------------------------------------------------- */ static Tcl_HashTable mapInfoTable; static ZnBool map_info_inited = False; typedef struct { ClientData client_data; ZnMapInfoChangeProc proc; } ZnMapInfoClient; typedef struct { ZnMapInfoId map_info; ZnBool deleted; ZnList clients; } ZnMapInfoMaster; static void ZnMapInfoInit() { Tcl_InitHashTable(&mapInfoTable, TCL_ONE_WORD_KEYS); map_info_inited = True; } static void UpdateMapInfoClients(ZnMapInfoMaster *master) { int i, num; ZnMapInfoClient *client; num = ZnListSize(master->clients); client = ZnListArray(master->clients); for (i = 0; i < num; i++, client++) { (*client->proc)(client->client_data, master->map_info); } } static int ZnCreateMapInfo(Tcl_Interp *interp, char *name, ZnMapInfoId *map_info) { Tk_Uid uid = Tk_GetUid(name); Tcl_HashEntry *entry; int new; ZnMapInfoMaster *master; if (!map_info_inited) { ZnMapInfoInit(); } entry = Tcl_CreateHashEntry(&mapInfoTable, uid, &new); if (!new) { /* * Empty the map info if it is not. */ master = (ZnMapInfoMaster *) Tcl_GetHashValue(entry); if (master->deleted) { master->deleted = False; } else { ZnMapInfoEmpty(master->map_info); UpdateMapInfoClients(master); } } else { master = (ZnMapInfoMaster *) ZnMalloc(sizeof(ZnMapInfoMaster)); master->map_info = ZnMapInfoCreate(name); master->deleted = False; master->clients = ZnListNew(1, sizeof(ZnMapInfoClient)); Tcl_SetHashValue(entry, master); } if (map_info) { *map_info = master->map_info; } return TCL_OK; } static int ZnDuplicateZnMapInfo(Tcl_Interp *interp, char *name, ZnMapInfoId map_info) { Tk_Uid uid = Tk_GetUid(name); Tcl_HashEntry *entry; int new; ZnMapInfoMaster *master; if (!map_info_inited) { ZnMapInfoInit(); } entry = Tcl_CreateHashEntry(&mapInfoTable, uid, &new); if (!new) { Tcl_AppendResult(interp, "duplicate mapinfo \"", name, "\" already exists", NULL); return TCL_ERROR; } master = (ZnMapInfoMaster *) ZnMalloc(sizeof(ZnMapInfoMaster)); master->map_info = ZnMapInfoDuplicate(map_info); master->deleted = False; master->clients = ZnListNew(1, sizeof(ZnMapInfoClient)); Tcl_SetHashValue(entry, master); return TCL_OK; } static ZnMapInfoMaster * LookupMapInfoMaster(Tcl_Interp *interp, char *name) { Tk_Uid uid = Tk_GetUid(name); Tcl_HashEntry *entry; ZnMapInfoMaster *master; if (!map_info_inited) { ZnMapInfoInit(); } entry = Tcl_FindHashEntry(&mapInfoTable, uid); if (entry == NULL) { mp_error: Tcl_AppendResult(interp, "mapinfo \"", name, "\" doesn't exist", NULL); return NULL; } master = (ZnMapInfoMaster *) Tcl_GetHashValue(entry); if (master->deleted) { goto mp_error; } return master; } static int ZnDeleteMapInfo(Tcl_Interp *interp, char *name) { ZnMapInfoMaster *master; Tk_Uid uid = Tk_GetUid(name); Tcl_HashEntry *entry; if (!map_info_inited) { ZnMapInfoInit(); } entry = Tcl_FindHashEntry(&mapInfoTable, uid); if (entry == NULL) { return TCL_ERROR; } master = (ZnMapInfoMaster *) Tcl_GetHashValue(entry); if (ZnListSize(master->clients) != 0) { master->deleted = True; ZnMapInfoEmpty(master->map_info); UpdateMapInfoClients(master); } else { ZnMapInfoDelete(master->map_info); ZnListFree(master->clients); Tcl_DeleteHashEntry(entry); ZnFree(master); } return TCL_OK; } ZnMapInfoId ZnGetMapInfo(Tcl_Interp *interp, char *name, ZnMapInfoChangeProc proc, ClientData client_data) { ZnMapInfoMaster *master; ZnMapInfoClient client; master = LookupMapInfoMaster(interp, name); if (master == NULL) { return NULL; } client.proc = proc; client.client_data = client_data; ZnListAdd(master->clients, &client, ZnListTail); return master->map_info; } void ZnFreeMapInfo(ZnMapInfoId map_info, ZnMapInfoChangeProc proc, ClientData client_data) { Tk_Uid uid = Tk_GetUid(ZnMapInfoName(map_info)); Tcl_HashEntry *entry; ZnMapInfoMaster *master; ZnMapInfoClient *client; unsigned int num, i; if (!map_info_inited) { ZnMapInfoInit(); } entry = Tcl_FindHashEntry(&mapInfoTable, uid); if (entry == NULL) { return; } master = (ZnMapInfoMaster *) Tcl_GetHashValue(entry); client = ZnListArray(master->clients); num = ZnListSize(master->clients); for (i = 0; i < num; i++, client++) { if ((client->client_data == client_data) && (client->proc == proc)) { ZnListDelete(master->clients, i); return; } } } static void ZnUpdateMapInfoClients(ZnMapInfoId map_info) { Tk_Uid uid = Tk_GetUid(ZnMapInfoName(map_info)); Tcl_HashEntry *entry; ZnMapInfoMaster *master; if (!map_info_inited) { ZnMapInfoInit(); } entry = Tcl_FindHashEntry(&mapInfoTable, uid); if (entry == NULL) { return; } master = (ZnMapInfoMaster *) Tcl_GetHashValue(entry); UpdateMapInfoClients(master); } /* * These arrays must be kept in sync with the ZnMapInfoLineStyle * and ZnMapInfoTextStyle enums. */ static char *line_style_strings[] = { "simple", "dashed", "dotted", "mixed", "marked", }; static char *text_style_strings[] = { "normal", "underlined" }; static char * ZnMapInfoLineStyleToString(ZnMapInfoLineStyle line_style) { return line_style_strings[line_style]; } static int ZnMapInfoLineStyleFromString(Tcl_Interp *interp, char *str, ZnMapInfoLineStyle *line_style) { int i, num = sizeof(line_style_strings)/sizeof(char *); for (i = 0; i < num; i++) { if (strcmp(str, line_style_strings[i]) == 0) { *line_style = i; return TCL_OK; } } Tcl_AppendResult(interp, " incorrect mapinfo line style \"", str,"\"", NULL); return TCL_ERROR; } static char * ZnMapInfoTextStyleToString(ZnMapInfoTextStyle text_style) { return text_style_strings[text_style]; } static int ZnMapInfoTextStyleFromString(Tcl_Interp *interp, char *str, ZnMapInfoTextStyle *text_style) { int i, num = sizeof(text_style_strings)/sizeof(char *); for (i = 0; i < num; i++) { if (strcmp(str, text_style_strings[i]) == 0) { *text_style = i; return TCL_OK; } } Tcl_AppendResult(interp, " incorrect mapinfo text style \"", str,"\"", NULL); return TCL_ERROR; } int ZnMapInfoObjCmd(ClientData client_data, Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ Tcl_Obj *CONST args[]) { ZnPos x, y; int index, index2, result; ZnMapInfoMaster *master; Tcl_Obj *l; #ifdef PTK_800 static char *sub_cmd_strings[] = #else static CONST char *sub_cmd_strings[] = #endif { "add", "count", "create", "delete", "duplicate", "get", "remove", "replace", "scale", "translate", NULL }; #ifdef PTK_800 static char *e_type_strings[] = #else static CONST char *e_type_strings[] = #endif { "arc", "line", "symbol", "text", NULL }; enum sub_cmds { ZN_MI_ADD, ZN_MI_COUNT, ZN_MI_CREATE, ZN_MI_DELETE, ZN_MI_DUPLICATE, ZN_MI_GET, ZN_MI_REMOVE, ZN_MI_REPLACE, ZN_MI_SCALE, ZN_MI_TRANSLATE }; enum e_types { ZN_E_ARC, ZN_E_LINE, ZN_E_SYMBOL, ZN_E_TEXT }; if (argc < 3) { Tcl_WrongNumArgs(interp, 1, args, "mapInfo/name subCmd ?args?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, args[2], sub_cmd_strings, "subCmd", 0, &index) != TCL_OK) { return TCL_ERROR; } result = TCL_OK; /*printf("mapinfo command \"%s\", argc=%d\n", Tcl_GetString(args[2]), argc);*/ switch((enum sub_cmds) index) { /* * create */ case ZN_MI_CREATE: { if (argc != 3) { Tcl_WrongNumArgs(interp, 1, args, "name create"); return TCL_ERROR; } if (ZnCreateMapInfo(interp, Tcl_GetString(args[1]), NULL) == TCL_ERROR) { return TCL_ERROR; } } break; /* * delete */ case ZN_MI_DELETE: { if (argc != 3) { Tcl_WrongNumArgs(interp, 1, args, "mapInfo delete"); return TCL_ERROR; } if (ZnDeleteMapInfo(interp, Tcl_GetString(args[1])) == TCL_ERROR) { return TCL_ERROR; } } break; /* * duplicate */ case ZN_MI_DUPLICATE: { if (argc != 4) { Tcl_WrongNumArgs(interp, 1, args, "mapInfo duplicate name"); return TCL_ERROR; } master = LookupMapInfoMaster(interp, Tcl_GetString(args[1])); if (master == NULL) { return TCL_ERROR; } if (ZnDuplicateZnMapInfo(interp, Tcl_GetString(args[3]), master->map_info) == TCL_ERROR) { return TCL_ERROR; } } break; /* * add/replace */ case ZN_MI_ADD: case ZN_MI_REPLACE: { ZnMapInfoLineStyle line_style; ZnMapInfoTextStyle text_style; int i, insert, val; ZnPos coords[6]; ZnBool add_cmd = (enum sub_cmds) index == ZN_MI_ADD; int num_param = add_cmd ? 4 : 5; if (argc < num_param) { Tcl_WrongNumArgs(interp, 3, args, add_cmd ? "elementType ?args?" : "elementType index ?args?"); return TCL_ERROR; } master = LookupMapInfoMaster(interp, Tcl_GetString(args[1])); if (master == NULL) { return TCL_ERROR; } if (!add_cmd) { if (Tcl_GetIntFromObj(interp, args[4], &insert) == TCL_ERROR) { return TCL_ERROR; } } if (Tcl_GetIndexFromObj(interp, args[3], e_type_strings, "elementType", 0, &index2) != TCL_OK) { return TCL_ERROR; } switch ((enum e_types) index2) { case ZN_E_LINE: { if (argc != (num_param+6)) { Tcl_WrongNumArgs(interp, 4, args, add_cmd ? "style width x1 y1 x2 y2" : "index style width x1 y1 x2 y2"); return TCL_ERROR; } if (ZnMapInfoLineStyleFromString(interp, Tcl_GetString(args[num_param]), &line_style) == TCL_ERROR) { return TCL_ERROR; } for (i = 0; i < 5; i++) { if (Tcl_GetDoubleFromObj(interp, args[num_param+i+1], &coords[i]) == TCL_ERROR) { return TCL_ERROR; } } if (coords[0] < 0) { coords[0] = 0; } if (add_cmd) { ZnMapInfoAddLine(master->map_info, ZnListTail, NULL, line_style, coords[0], coords[1], coords[2], coords[3], coords[4]); } else { ZnMapInfoReplaceLine(master->map_info, insert, NULL, line_style, coords[0], coords[1], coords[2], coords[3], coords[4]); } } break; case ZN_E_SYMBOL: { if (argc != (num_param+3)) { Tcl_WrongNumArgs(interp, 4, args, add_cmd ? "x y intVal" : "index x y intVal"); return TCL_ERROR; } for (i = 0; i < 2; i++) { if (Tcl_GetDoubleFromObj(interp, args[num_param+i], &coords[i]) == TCL_ERROR) { return TCL_ERROR; } } if (Tcl_GetIntFromObj(interp, args[num_param+2], &val) == TCL_ERROR) { return TCL_ERROR; } if (val < 0) { val = 0; } if (add_cmd) { ZnMapInfoAddSymbol(master->map_info, ZnListTail, NULL, coords[0], coords[1], (char) val); } else { ZnMapInfoReplaceSymbol(master->map_info, insert, NULL, coords[0], coords[1], (char) val); } } break; case ZN_E_TEXT: { if (argc != (num_param+5)) { Tcl_WrongNumArgs(interp, 4, args, add_cmd ? "textStyle lineStyle x y string" : "index textStyle lineStyle x y string"); return TCL_ERROR; } if (ZnMapInfoTextStyleFromString(interp, Tcl_GetString(args[num_param]), &text_style) == TCL_ERROR) { return TCL_ERROR; } if (ZnMapInfoLineStyleFromString(interp, Tcl_GetString(args[num_param+1]), &line_style) == TCL_ERROR) { return TCL_ERROR; } for (i = 0; i < 2; i++) { if (Tcl_GetDoubleFromObj(interp, args[num_param+i+2], &coords[i]) == TCL_ERROR) { return TCL_ERROR; } } if (add_cmd) { ZnMapInfoAddText(master->map_info, ZnListTail, NULL, text_style, line_style, coords[0], coords[1], Tcl_GetString(args[num_param+4])); } else { /*printf("replace text ts %d ls %d %g %g %s\n", text_style, line_style, coords[0], coords[1], Tcl_GetString(args[num_param+4]));*/ ZnMapInfoReplaceText(master->map_info, insert, NULL, text_style, line_style, coords[0], coords[1], Tcl_GetString(args[num_param+4])); } } break; case ZN_E_ARC: { if (argc != (num_param+7)) { Tcl_WrongNumArgs(interp, 4, args, add_cmd ? "style width cx cy radius start extent" : "index style width cx cy radius start extent"); return TCL_ERROR; } if (ZnMapInfoLineStyleFromString(interp, Tcl_GetString(args[num_param]), &line_style) == TCL_ERROR) { return TCL_ERROR; } for (i = 0; i < 6; i++) { if (Tcl_GetDoubleFromObj(interp, args[num_param+i+1], &coords[i]) == TCL_ERROR) { return TCL_ERROR; } } if (coords[0] < 0) { coords[0] = 0; } if (coords[3] < 0) { coords[3] = 0; } if (add_cmd) { ZnMapInfoAddArc(master->map_info, ZnListTail, NULL, line_style, coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); } else { ZnMapInfoReplaceArc(master->map_info, insert, NULL, line_style, coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); } } break; } UpdateMapInfoClients(master); } break; /* * count */ case ZN_MI_COUNT: { int count = 0; if (argc != 4) { Tcl_WrongNumArgs(interp, 1, args, "mapInfo count type"); return TCL_ERROR; } master = LookupMapInfoMaster(interp, Tcl_GetString(args[1])); if (master == NULL) { return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, args[3], e_type_strings, "elementType", 0, &index2) != TCL_OK) { return TCL_ERROR; } switch ((enum e_types) index2) { case ZN_E_LINE: count = ZnMapInfoNumLines(master->map_info); break; case ZN_E_SYMBOL: count = ZnMapInfoNumSymbols(master->map_info); break; case ZN_E_TEXT: count = ZnMapInfoNumTexts(master->map_info); break; case ZN_E_ARC: count = ZnMapInfoNumArcs(master->map_info); break; } l = Tcl_NewIntObj(count); Tcl_SetObjResult(interp, l); } break; /* * get */ case ZN_MI_GET: { int insert; if (argc != 5) { Tcl_WrongNumArgs(interp, 1, args, "mapInfo get type index"); return TCL_ERROR; } master = LookupMapInfoMaster(interp, Tcl_GetString(args[1])); if (master == NULL) { return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, args[4], &insert) == TCL_ERROR) { return TCL_ERROR; } if (insert < 0) { insert = 0; } if (Tcl_GetIndexFromObj(interp, args[3], e_type_strings, "elementType", 0, &index2) != TCL_OK) { return TCL_ERROR; } switch ((enum e_types) index2) { case ZN_E_LINE: { ZnMapInfoLineStyle line_style; ZnDim line_width; ZnPos x_to, y_to; ZnMapInfoGetLine(master->map_info, insert, NULL, &line_style, &line_width, &x, &y, &x_to, &y_to); l = Tcl_GetObjResult(interp); Tcl_ListObjAppendElement(interp, l, Tcl_NewStringObj(ZnMapInfoLineStyleToString(line_style), -1)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(line_width)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(x)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(y)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(x_to)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(y_to)); } break; case ZN_E_SYMBOL: { char symbol; ZnMapInfoGetSymbol(master->map_info, insert, NULL, &x, &y, &symbol); l = Tcl_GetObjResult(interp); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(x)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(y)); Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(symbol)); } break; case ZN_E_TEXT: { char *text; ZnMapInfoTextStyle text_style; ZnMapInfoLineStyle line_style; ZnMapInfoGetText(master->map_info, insert, NULL, &text_style, &line_style, &x, &y, &text); l = Tcl_GetObjResult(interp); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(x)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(y)); Tcl_ListObjAppendElement(interp, l, Tcl_NewStringObj(ZnMapInfoTextStyleToString(text_style), -1)); Tcl_ListObjAppendElement(interp, l, Tcl_NewStringObj(ZnMapInfoLineStyleToString(line_style), -1)); Tcl_ListObjAppendElement(interp, l, Tcl_NewStringObj(text, -1)); } break; case ZN_E_ARC: { ZnMapInfoLineStyle line_style; ZnDim line_width, radius; ZnPos start, extent; ZnMapInfoGetArc(master->map_info, insert, NULL, &line_style, &line_width, &x, &y, &radius, &start, &extent); l = Tcl_GetObjResult(interp); Tcl_ListObjAppendElement(interp, l, Tcl_NewStringObj(ZnMapInfoLineStyleToString(line_style), -1)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(line_width)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(x)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(y)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(radius)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(start)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(extent)); } break; } } break; /* * remove */ case ZN_MI_REMOVE: { int insert; if (argc != 5) { Tcl_WrongNumArgs(interp, 1, args, "mapInfo remove type index"); return TCL_ERROR; } master = LookupMapInfoMaster(interp, Tcl_GetString(args[1])); if (master == NULL) { return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, args[4], &insert) == TCL_ERROR) { return TCL_ERROR; } if (insert < 0) { insert = 0; } if (Tcl_GetIndexFromObj(interp, args[3], e_type_strings, "elementType", 0, &index2) != TCL_OK) { return TCL_ERROR; } switch ((enum e_types) index2) { case ZN_E_LINE: ZnMapInfoRemoveLine(master->map_info, insert); break; case ZN_E_SYMBOL: ZnMapInfoRemoveSymbol(master->map_info, insert); break; case ZN_E_TEXT: ZnMapInfoRemoveText(master->map_info, insert); break; case ZN_E_ARC: ZnMapInfoRemoveArc(master->map_info, insert); break; } UpdateMapInfoClients(master); } break; /* * scale */ case ZN_MI_SCALE: { double factor; if (argc != 4) { Tcl_WrongNumArgs(interp, 1, args, "mapInfo scale factor"); return TCL_ERROR; } master = LookupMapInfoMaster(interp, Tcl_GetString(args[1])); if (master == NULL) { return TCL_ERROR; } if (Tcl_GetDoubleFromObj(interp, args[3], &factor) == TCL_ERROR) { return TCL_ERROR; } ZnMapInfoScale(master->map_info, factor); UpdateMapInfoClients(master); } break; /* * translate */ case ZN_MI_TRANSLATE: { if (argc != 5) { Tcl_WrongNumArgs(interp, 1, args, "mapInfo translate xAmount yAmount"); return TCL_ERROR; } master = LookupMapInfoMaster(interp, Tcl_GetString(args[1])); if (master == NULL) { return TCL_ERROR; } if (Tcl_GetDoubleFromObj(interp, args[3], &x) == TCL_ERROR) { return TCL_ERROR; } if (Tcl_GetDoubleFromObj(interp, args[4], &y) == TCL_ERROR) { return TCL_ERROR; } ZnMapInfoTranslate(master->map_info, x, y); UpdateMapInfoClients(master); } break; } return TCL_OK; } /* *---------------------------------------------------------------------- * * VideomapObjCmd -- * * *---------------------------------------------------------------------- */ int ZnVideomapObjCmd(ClientData client_data, Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ Tcl_Obj *CONST args[]) { ZnList ids; int index; int *id_array, id_num, i; Tcl_Obj *l; #ifdef PTK_800 static char *sub_cmd_strings[] = #else static CONST char *sub_cmd_strings[] = #endif { "ids", "load", NULL }; enum sub_cmds { ZN_V_IDS, ZN_V_LOAD }; if (argc < 2) { Tcl_WrongNumArgs(interp, 1, args, "?subCmd? filename $args?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, args[1], sub_cmd_strings, "subCmd", 0, &index) != TCL_OK) { return TCL_ERROR; } switch((enum sub_cmds) index) { /* * ids */ case ZN_V_IDS: { if (argc != 3) { Tcl_WrongNumArgs(interp, 1, args,"ids filename"); return TCL_ERROR; } ids = ZnMapInfoVideomapIds(Tcl_GetString(args[2])); if (ids == NULL) { Tcl_AppendResult(interp, "unable to look at videomap file \"", Tcl_GetString(args[2]), "\"", NULL); return TCL_ERROR; } id_array = ZnListArray(ids); id_num = ZnListSize(ids); l = Tcl_GetObjResult(interp); for (i = 0; i < id_num; i++) { Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(id_array[i])); } ZnListFree(ids); } break; /* * load */ case ZN_V_LOAD: { ZnMapInfoId map_info; int insert; if (argc != 5) { Tcl_WrongNumArgs(interp, 1, args, "load filename index mapInfo"); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, args[3], &insert) == TCL_ERROR) { return TCL_ERROR; } if (insert < 0) { insert = 0; } if (ZnCreateMapInfo(interp, Tcl_GetString(args[4]), &map_info) == TCL_ERROR) { return TCL_ERROR; } if (ZnMapInfoGetVideomap(map_info, Tcl_GetString(args[2]), insert) == TCL_ERROR) { Tcl_AppendResult(interp, "unable to load videomap file \"", Tcl_GetString(args[2]), ":", Tcl_GetString(args[3]), "\"", NULL); return TCL_ERROR; } ZnUpdateMapInfoClients(map_info); } break; } return TCL_OK; }