/* xrmap - vector based global map generating program * * Copyright (C) 2001-2003 Jean-Pierre Demailly * ftp://ftp.ac-grenoble.fr/ge/geosciences * * loosely derived from "rmap" * Copyright (C) 2000 Reza Naima * http://www.reza.net/rmap/ * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* #define DEBUG */ /* #define TRACE */ /* #define SUPERTRACE */ #define ARCINFO /* #include */ #include #include #include #include #include #include #include #ifdef ZLIB #include #endif #include "xrmap.h" #include "version.h" #include "bitmaps.h" #include "menudefs.h" /* Extended ascii conversion for search routine ('192 and more) */ /* ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ */ /* AAAAAAACEEEEIIIIDNOOOOO×OUUUUYPSaaaaaaaceeeeiiiitnooooo÷ouuuuyhy */ char cvs[] = "aaaaaaaceeeeiiiidnooooo×ouuuuypsaaaaaaaceeeeiiiitnooooo÷ouuuuyhy"; char *continent[] = { "AF", "AS", "EU", "NA", "SA", "OC" }; char *flag_formats[] = { "xpm", "gif", "png", "jpg", "eps", "svg" }; int flag_rev[] = { 3, 2, 1, 0, 5, 4}; char *flag_ordering; char *flag_descr; char **flag_type; char **flag_dir; int flag_size = 0; int num_flag_dirs; int num_flag_types; /* Global variables */ Display * dpy; Visual * visual; Window Root, mainwin = 0, datawin = 0, cmdwin = 0, explwin = 0, flagwin = 0; Colormap cmap = 0; GC gc = 0; Atom wm_delete_window, wm_protocols; Pixel black, white; Pixmap datapix = None; Pixmap cmdpix = None; Pixmap explpix = None; Pixmap butpix[3] = { None, None, None }; XImage *flag_image[2] = { NULL, NULL}; XImage *big_flag_image = NULL; int scr; int color_depth; int color_pad; int bigendian; unsigned char *color_table; char language[4]; XFontStruct * xfont[6]; int fontasc[6], fonth[6], fontasc[6], char_width; char *file_filter = NULL; char *expl_implicit; char expl_currdir[256]; int expl_table_entries; int expl_lines; int expl_shift = 0; int expl_output = 0; char *error_msg = NULL; char **expl_dirtable = NULL; char **msg = NULL; short country_table[676]; char **feature_descr[6]; int feature_length[6] = { C_ENDCOLOR-C_FG_TEXT, C_CITY_CIRCLE-C_BG_MAP, C_FG_TEXT-C_CITY_CIRCLE, 5, 11, 12}; int feature_index[6] = { C_FG_TEXT, C_BG_MAP, C_CITY_CIRCLE, 0, 5, 16}; char lineorder0[6] = "01234"; int mark_step0[5] = { 150, 1200, 3000, 6000, 10000}; int name_step0[5] = { 400, 3000, 8000, 15000, 25000}; int city_mark0[5] = { 1, 2, 3, 4, 5 }; int city_size0[5] = { 3000000, 700000, 300000, 100000, 0}; int airport_mark0[5] = { 1, 2, 3, 4, 5 }; int airport_size0[5] = { 3500, 3000, 2500, 1500, 0}; int peak_mark0[5] = { 1, 2, 3, 4, 5 }; int peak_size0[5] = { 6500, 4000, 1000, 500, -500}; char city_filter0[4] = "CR*"; char loc_filter0[16] = "BCIKLORSTV*"; char cmd_killed_char; #ifdef ARCINFO char dump_precision[20] = "%.5f %.5f\n"; char *dump_file = NULL; int dump_format = DUMP_JPD; int dump_split = 0; int dump_verbose = 1; char *arc_file = NULL; int *arc_numseg = NULL; char ***arc_index = NULL; int arc_lambert = 0; int arc_start = 0; int arc_precision = 6; int arc_search = 0; double arc_x, arc_y; double arc_transl = 0; double arc_scale = 1.0/6378000.0; double arc_lat0 = 60.0; double arc_lon0 = 0.0; #endif char *search_string; int *loc_pointer = NULL; int *presel_pointer = NULL; char *data_text = NULL; int search_index = -1; int search_by = 1; int num_found; int num_listed; int start_list; int start_shortcut = 0; int datawin_on = 0; int flagwin_on = 0; int cmdwin_on = 0; int explwin_on = 0; int exposed = 0; int notified = 0; int escape_length = 0; int ranking = 0; int expert = 0; int brief_menu = 0; int secure = 0; int dms = 0; int theming = 0; int num_msg = 0; int time_count = 0; int numcountry = 0, numtz = 0, numloc = 0, numpresel = 0; int runlevel = 0; int path_start; int img_output = 0; int reverse = 0; int but_main_pressed = 0; int but_data_pressed = 0; int but_expl_pressed = 0; int control_pressed = 0; int line_clicked; int overwrite = 1; int visible = 0; int point_shown = 0; int setup_change = 0; int caret_pos = 0; int w_button = 0; int h_button = 0; int w_buttons = 0; int cmd_killed_pos = 0; int cmd_killed_length = 0; int action_width = 0; int use_memory = 1; int start_menu = 0; int im_compress = 0; int box_x, box_y, box_width, box_height, box_spacing, box_numitems; int mouse_x1, mouse_y1, mouse_x2, mouse_y2, maxmove; int datawin_x=-1000000, datawin_y; int flagwin_x=-1000000, flagwin_y; int cmdwin_x=-1000000, cmdwin_y; int explwin_x=-1000000, explwin_y; int pixmap_width[2], pixmap_height[2]; int pixmap_height_max = 0; unsigned int datawin_width, datawin_height; unsigned int flagwin_width, flagwin_height; unsigned int cmdwin_width, cmdwin_height, cmdwin_height0 = 480; unsigned int explwin_width, explwin_height, explwin_height0 = 320; int cmd_mode = MODE_RUN, cmd_type = M_RUN_START; int spacing_generalmenu; int spacing_filemenu; int spacing_optionmenu; int spacing_colormenu; int spacing_helpmenu; int line_pos; int old_city_shown = -2; int city_shown = 0; int city_shown_box_x, city_shown_box_y, city_shown_box_w, city_shown_box_h; int city_already_shown = 0; int city_found = -1; int text_shown; int num_doc; int tb_width; /* textbox width */ int text_drawn; /* is text really drawn ? */ char * cmd_string; double preview; double ps_width=150.0, ps_lm=30.0, ps_bm=30.0, ps_lw=1.0; int ps_rot = 0, ps_grayscale = 0, ps_frame = 1; char * print_cmd; char * editor_cmd; char * im_viewer; char * ps_viewer; char * svg_viewer; char * svg_convert; char * html_viewer; char * midi_cmd; char * prog_cmd[7]; char * list_lang; char time_string[80] = ""; char * datapix_name = NULL; char * cmdpix_name = NULL; char * explpix_name = NULL; char * flag_name = NULL; char * butpix_name[3] = { NULL, NULL, NULL }; Country **countries = NULL; Timezone **timezones = NULL; Location **locations = NULL; Header * header = NULL; Segment_index * segment_index = NULL; signed char * segment_buffer = NULL; signed char * fullmap_buffer = NULL; int *textboxes = NULL; void * out_fd = NULL; #define SEG_SELECT #ifdef SEG_SELECT int seg_mode = 0; int seg_nummarked = 0; char *seg_marked = NULL; int *seg_specified = NULL; #endif /* forward references */ #define forward extern forward int set_flag_dirs(); forward void free_flag_data(); forward void list_flag_dirs(); forward void fix_features_description(ImageLayout * scene); forward void search_city(ImageLayout * scene); forward void search_output(ImageLayout * scene, int force); forward void show_datawin(ImageLayout * scene, int raise); forward void show_flagwin(ImageLayout * scene, int raise); forward void update_auxil_windows(ImageLayout *scene); forward void edit_rc_output(ImageLayout * scene); forward int parse_pixmaps(ImageLayout *scene, char *str); forward int parse_cmd_line(ImageLayout * scene, char *string, char *sep); forward void generate(ImageLayout *scene); forward void show_mark(ImageLayout *scene); /* * SECTION 0 : A FEW BASIC ROUTINES */ int round2int(double x) { if (x>0) return (int)(x+0.5) ; else return -(int)(-x+0.5); } short double2short(double x) { if (x>32767.0) return 32767; if (x<-32767.0) return -32767; return (short)x; } double dms2decim(char * str) { double eps=1.0, deg=0.0, min=0.0, sec=0.0; if (*str == '-') { ++str; eps = -1.0; } if (index(str, '°')) { sscanf(str, "%lf°%lf'%lf", °, &min, &sec); return eps*(deg+(min+sec/60.0)/60.0); } else if (index(str, '\'')) { sscanf(str, "%lf'%lf", &min, &sec); return eps*((min+sec/60.0)/60.0); } else if (index(str, '\"')) { sscanf(str, "%lf", &sec); return eps*(sec/3600.0); } else return eps*atof(str); } void decim2dms(double value, char * str) { int eps, d, m, s; if (dms!=1) { sprintf(str, (dms==-1)?"%.6f":"%.3f", value); return; } if (value<0) { value = -value; eps = -1; } else eps = 1; value = value+1/7200.0; d = (int) value; value = 60.0 * (value - d); m = (int) value; value = 60 * (value - m); s = (int) value; sprintf(str, "%s%d°%02d'%02d\"", (eps==1)?"":"-", d, m, s); } /* Is it really more secure than plain tmpnam() ?? */ void secure_tmpnam(char *name) { char compl[4]; static int order = 0; compl[0] = 'a' + ((order/676)%26); compl[1] = 'a' + ((order/26)%26); compl[2] = 'a' + (order%26); compl[3] = '\0'; ++order; sprintf(name, "%s/XXXXXX", P_tmpdir); close(mkstemp(name)); unlink(name); strcat(name, compl); } /* This tells us whether user should enter text or not */ int text_input_mode() { return cmd_mode==MODE_CMD || (cmd_mode==MODE_MENU && cmd_type==M_MENU_SEARCH) || (cmd_mode==MODE_FILE && cmd_type>M_FILE_START && cmd_typeM_OPTION_START) || (cmd_mode==MODE_COLOR && cmd_type>M_COLOR_START); } /* This tells us whether user should click on a box */ int click_input_mode() { return (cmd_mode==MODE_FILE && cmd_type==M_FILE_DATA) || (cmd_mode==MODE_FILE && cmd_type==M_FILE_EXTERNAL) || (cmd_mode==MODE_FILE && cmd_type==M_FILE_PRINTCFG) || (cmd_mode==MODE_FILE && cmd_type==M_FILE_SAVE) || (cmd_mode==MODE_MENU && cmd_type==M_MENU_SEARCH) || (cmd_mode==MODE_MENU && cmd_type==M_MENU_LIST) || (cmd_mode==MODE_HELP && cmd_type==M_HELP_SHORTCUTS) || (cmd_mode==MODE_HELP && cmd_type==M_HELP_DOC) || (cmd_mode==MODE_HELP && cmd_type==M_HELP_EXTRA) || (cmd_mode==MODE_HELP && cmd_type==M_HELP_EDIT) || cmd_mode==MODE_OPTION || cmd_mode==MODE_COLOR; } int wild_strcmp(char * string, char * needle) { int i, j, l; i = 0; while (string[i]!='\0' && needle[i]!='\0' && string[i]==needle[i] && needle[i]!='*') ++i; if (needle[i]=='\0') return (string[i]!='\0'); if (needle[i]!='*') return 1; l = strlen(string+i); for (j=0; j<=l; j++) if (!wild_strcmp(string+i+j, needle+i+1)) return 0; return 1; } int string_cmp(char * string, char * needle) { int i, l; char *ptr; unsigned char c; l = strlen(string); ptr = NULL; for (i=0; i='A' && c<='Z') c += 32; else if (c=='-') c=' '; else if (c=='(') { c='\0'; ptr = string+i+1; } else if (c==')') c='\0'; string[i] = c; } else if (c>=192) string[i] = cvs[c-192]; } if (!wild_strcmp(string, needle)) return 0; if (ptr && !wild_strcmp(ptr, needle)) return 0; return 1; } /* * SECTION 1 : LOW LEVEL X11 ROUTINES */ /* Read primary selection buffer (Copy/Paste X Buffer) */ char * read_primary() { Atom actual_type; int actual_format; long nitem, bytes_after, nread; unsigned char *data; char *outdata; nread = 0; outdata = malloc(2); *outdata = '\0'; /* X-selection paste loop */ do { /* get remaining selection max 1024 chars */ if (XGetWindowProperty (dpy, DefaultRootWindow(dpy), XA_CUT_BUFFER0, nread / 4, 1024, False, AnyPropertyType, &actual_type, &actual_format, &nitem, &bytes_after, (unsigned char **) &data) != Success) return(0); /* paste last batch one char at a time */ nread += nitem; outdata = realloc(outdata, (nread+2) * sizeof(char)); strcat(outdata, data); XFree(data); } while (bytes_after > 0); return(outdata); } /* Write primary selection buffer (Copy/Paste X Buffer) */ void write_primary(char *text) { XChangeProperty(dpy, DefaultRootWindow(dpy), XA_CUT_BUFFER0, XA_STRING, 8, PropModeReplace, text, strlen(text)); } void get_color(char* c, ImageLayout * scene, int i) { XColor color, exact; Colormap ncmap; Colordata *colors; unsigned char r, g, b; int bool = 0; if (!c) return; colors = &scene->color[i]; if (*c == '+') { colors->bool = ON; bool = 1; ++c; } if (*c == '-') { colors->bool = OFF; bool = 1; ++c; } if (!(*c)) return; if (color_depth <= 8) ncmap = XCreateColormap(dpy, Root, visual, AllocNone); else ncmap = cmap; if (ncmap) { XAllocNamedColor(dpy, ncmap, c, &color, &exact); colors->r = exact.red; colors->g = exact.green; colors->b = exact.blue; if (color_depth <= 8) { r = exact.red >> 8; g = exact.green >> 8; b = exact.blue >> 8; if (XAllocColor(dpy, cmap, &exact)) colors->pix = exact.pixel; else colors->pix = color_table[(((6*g)>>8)*36)+(((6*r)>>8)*6)+((6*b)>>8)]; } else colors->pix = exact.pixel; if (reverse && i> 8; g = color.green >> 8; b = color.blue >> 8; if (XAllocColor(dpy, cmap, &color)) colors->pix = color.pixel; else colors->pix = color_table[(((6*g)>>8)*36)+(((6*r)>>8)*6)+((6*b)>>8)]; } else { XAllocColor(dpy, cmap, &color); colors->pix = color.pixel; } } } if (color_depth <= 8) XFreeColormap(dpy, ncmap); strncpy(colors->name, c, 39); colors->name[39] = '\0'; } void set_bg_fg(ImageLayout * scene) { if (gc) { XSetBackground(dpy, gc, scene->color[C_BG_TEXT].pix); XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); } } void get_all_colors(ImageLayout * scene) { int i, j, r, g, b; XColor color; if (color_depth<=8) { if (cmap) XFreeColormap(dpy, cmap); cmap = XCreateColormap(dpy, Root, visual, AllocNone); /* first create color cube 6 x 6 x 6 */ for (i=0; i<216; i++) { r = (i / 6) % 6; g = i / 36; b = i % 6; color.red = r * 51 * 257; color.green = g * 51 * 257; color.blue = b * 51 * 257; XAllocColor(dpy, cmap, &color); color_table[i] = color.pixel; } } /* complete other colors, starting with special menu colors (just for the case of pseudo-colors being handled adequately) */ for (j=0; jcolor[i].bool != INACTIVE) { if (i>=C_FG_TEXT) scene->color[i].bool = 1; get_color(scene->color[i].name, scene, i); } } if (color_depth<=8) { if (mainwin) XSetWindowColormap(dpy, mainwin, cmap); if (datawin) XSetWindowColormap(dpy, datawin, cmap); if (cmdwin) XSetWindowColormap(dpy, cmdwin, cmap); if (explwin) XSetWindowColormap(dpy, explwin, cmap); if (flagwin) XSetWindowColormap(dpy, flagwin, cmap); } set_bg_fg(scene); } int get_window_placement(Window win, int *x, int *y, unsigned int *w, unsigned int *h) { unsigned int b, d; Window root, junk; XFlush(dpy); XGetGeometry(dpy, win, &root, x, y, w, h, &b, &d); XTranslateCoordinates(dpy, win, RootWindow(dpy, scr), 0, 0, x, y, &junk); return 1; } void draw_separator(ImageLayout *scene, int x, int position) { int y; y = (position-TOP)*(fonth[0]+16); XClearArea(dpy, cmdwin, x, y, 3, fonth[0]+6, False); } void draw_tick(ImageLayout *scene, int mode, int num, int position) { int i, a, d, x1, x2, y, spacing = 0; char *str = ""; if (num<=0) return; y = (position-TOP)*(fonth[0]+16)+fonth[0]+6; if (mode==MODE_MENU) { str = labels_generalmenu; spacing = spacing_generalmenu; } if (mode==MODE_OPTION) { str = labels_optionmenu; spacing = spacing_optionmenu; } if (mode==MODE_COLOR) { str = labels_colormenu; spacing = spacing_colormenu; } if (mode==MODE_HELP) { str = labels_helpmenu; spacing = spacing_helpmenu; } if (mode==MODE_FILE) { str = labels_filemenu; spacing = spacing_filemenu; } x1 = XTextWidth(xfont[0], str, spacing*(num-1)-1); x2 = XTextWidth(xfont[0], str, spacing*num-1); XClearArea(dpy, cmdwin, 0, y, cmdwin_width, cmdwin_height-y, False); XSetForeground(dpy, gc, scene->color[C_FG_TICKS].pix); a = (x1+x2+4)/2; ++y; for (i=0; i<=7; i++) { d = 3-i/2; XDrawLine(dpy, cmdwin, gc, a-d, y+i, a+d, y+i); } } void draw_win_string(ImageLayout *scene, Window win, char *s, int position) { int i, y0=0, yt=0, tw, width, height; if (win==mainwin) { width = scene->width; height = scene->height; } else { width = cmdwin_width; height = cmdwin_height; } if (positionmax_bounds.descent - 4; yt = yt - fonth[0] - 6; } XSetForeground(dpy, gc, scene->color[C_BG_TEXT].pix); XFillRectangle(dpy, win, gc, 0, yt, width, fonth[0]+6); XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); XDrawImageString(dpy, win, gc, 4, y0, s, strlen(s)); if (text_input_mode() && position==BOTTOM) { tw = XTextWidth(xfont[0], s, caret_pos); XSetForeground(dpy, gc, scene->color[C_FG_CARET].pix); XFillRectangle(dpy, win, gc, tw+4, yt+fonth[0]+3, char_width, 2); } if (win==cmdwin && position==TOP) { XSetForeground(dpy, gc, scene->color[C_BG_ESCAPE].pix); XFillRectangle(dpy, win, gc, width-3*action_width, 0, 3*action_width, fonth[0]+6); for (i=ACTIVATE; i<=QUIT; i++) { draw_separator(scene, width-(3-i)*action_width, TOP); XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); XDrawString(dpy, win, gc, width-(3-i)*action_width+8, fontasc[0]+2, msg[i], strlen(msg[i])); } } XFlush(dpy); text_shown = 1; } void show_title(ImageLayout * scene, Window win) { char title[120]; if (!win) return; if (win==mainwin) sprintf(title, "%s / %s %s", PACKAGE, wintitle_descr[0], projtype[scene->projection]); if (win==datawin) sprintf(title, "%s / %s", PACKAGE, wintitle_descr[1]); if (win==cmdwin) sprintf(title, "%s / %s", PACKAGE, wintitle_descr[2]); if (win==explwin) sprintf(title, "%s / %s", PACKAGE, wintitle_descr[3]); if (win==flagwin) sprintf(title, "%s / %s", PACKAGE, wintitle_descr[4]); XStoreName(dpy, win, title); } void set_font_params(int which) { int i, w; if (which<0 || which>5) return; fontasc[which] = xfont[which]->max_bounds.ascent; fonth[which] = fontasc[which] + xfont[which]->max_bounds.descent; if (which==0) { char_width = XTextWidth(xfont[0], "w", 1); action_width = 0; for (i=ACTIVATE; i<=QUIT; i++) { w = XTextWidth(xfont[0], msg[i], strlen(msg[i])); if (w>action_width) action_width = w; } action_width += 16; } cmdwin_height0 = 3*(fonth[0]+16)+17*(fonth[0]+10); } int set_font(char *s, int which) { XFontStruct * nfont; nfont = XLoadQueryFont(dpy, s); if (nfont == (XFontStruct *)NULL) { fprintf(stderr, msg[CANT_OPEN_FONT], s); fprintf(stderr, "\n"); return 1; } if (xfont[which]) XFreeFont(dpy, xfont[which]); xfont[which] = nfont; if (which==0) XSetFont(dpy, gc, nfont->fid); set_font_params(which); setup_change |= FONT_CHANGE; return 0; } void image_init(ImageLayout *scene) { char str[256], compl[128], lat[40], lon[40]; XFlush(dpy); usleep(10000); if (scene->projection==SPHERICAL) *compl = '\0'; else sprintf(compl, "aspect %.2f, ", scene->aspect); decim2dms(scene->gopt.xrot, lat); decim2dms(scene->gopt.yrot, lon); sprintf(str, "%s %dx%d (%s %s, " "zoom %.2f, %slat %s, lon %s, inc %.2f) ...", msg[BUILDING_MAP], scene->width, scene->height, msg[PROJECTION_TYPE], projtype[scene->projection], scene->gopt.zoom, compl, lat, lon, scene->gopt.zrot); if (!start_menu) draw_win_string(scene, mainwin, str, TOP); if (scene->pixmap) XFreePixmap(dpy, scene->pixmap); scene->pixmap = XCreatePixmap(dpy, mainwin, scene->width, scene->height, color_depth); if (scene->prepixmap) XFreePixmap(dpy, scene->prepixmap); scene->prepixmap = XCreatePixmap(dpy, mainwin, scene->width, scene->height, color_depth); XFlush(dpy); usleep(10000); } void create_GCs(ImageLayout *s) { XGCValues gcv; int mask; mask = GCForeground | GCBackground | GCFont; gcv.background = s->color[C_BG_TEXT].pix; gcv.foreground = s->color[C_FG_TEXT].pix; gcv.font = xfont[0]->fid; gc = XCreateGC(dpy, Root, mask, &gcv); } void print_string(char * s) { if (out_fd) { #ifdef ZLIB if (im_compress) gzprintf((gzFile *)out_fd, "%s", s); else fprintf((FILE *)out_fd, "%s", s); #else fprintf((FILE *)out_fd, "%s", s); #endif } else printf("%s", s); } void draw_pixel(ImageLayout *s, int x, int y, Pixel pix) { XSetForeground(dpy, gc, pix); XDrawPoint(dpy, s->pixmap, gc, x, y); } void draw_pointseg(ImageLayout *s, double x, double y, Pixel pix) { char line[80]; XSetForeground(dpy, gc, pix); XDrawPoint(dpy, s->pixmap, gc, (int)x, (int)y); if (img_output == OUT_EPS) { sprintf(line, "%.2f %.2f D\n", x, s->height-y-1.0); print_string(line); } } void reformat_string(char *dest, char *src, int mode) { int j, k; k = 0; for (j=0; j<=strlen(src); j++) { if (src[j]=='(') { dest[k++] = ' '; if (mode) dest[k++] = '\\'; } if (mode && src[j]==')') dest[k++] = '\\'; dest[k++] = src[j]; } } void PixmapDrawString(ImageLayout *scene, int x, int y, int w, int h, char *str, int length) { int i, j, i1, i2, skip; int mask, mask1, mask2; if (scene->ropt.smartlabels) { text_drawn = 0; if (!textboxes) { tb_width = (scene->width+31)>>5; if (textboxes) free(textboxes); textboxes = (int *) calloc(tb_width * scene->height, sizeof(int)); } if (x>=scene->width) return; if (x+w<=0) return; if (y>=scene->height) return; if (y+h<=0) return; if (x<0) { w = x+w; x = 0; } if (x+w>scene->width) w = scene->width - x; if (y<0) { h = y+h; y = 0; } if (y+h>scene->height) h = scene->height - y; i1 = x>>5; i2 = (x+w-1)>>5; mask1 = (-1)>>(x&31); mask2 = (-1)<<(31-((x+w-1)&31)); if (i1==i2) mask1 &= mask2; for (j=y; jpixmap, gc, x, y, str, length); text_drawn = 1; } void draw_string(ImageLayout *s, ScreenPt *pt, char * text, int nfont, int pos, int space, int ind) { int i, j, l, numl=0; int text_x, text_y, text_w; char *ptr1, *ptr2; char name[256], line[256]; text_drawn = 0; if (!text || !*text) return; XSetFont(dpy, gc, xfont[nfont]->fid); XSetForeground(dpy, gc, (ind==-1)?s->currentpixel:s->color[ind].pix); text_x = (int)pt->coord[X]; text_y = (int)pt->coord[Y]; if (pos) { /* (i, j) mean width, height of text, possibly with sign */ i = 0; if (pos<=3) j = fontasc[nfont]-fonth[nfont]-1; else if (pos>=5) j = fontasc[nfont]+1; else j = 0; ptr1 = text; while (ptr1) { ptr2 = strstr(ptr1, "\\n"); if (ptr2) ++numl; else ptr2 = ptr1+strlen(ptr1); l = XTextWidth(xfont[nfont], ptr1, (int)(ptr2-ptr1)); if (l>i) i = l; if (*ptr2=='\\') { ptr1 = ptr2+2; if (pos<=3) j -= fonth[nfont]; } else ptr1 = NULL; } if (pos==4) i += space; else if (pos==2 || pos==6) { i = i/2; if (j>0) j += space+1; if (j<0) j -= space+1; } else { /* 7/10 is approximately srqt(2)/2 ... */ l = 7*space/10+1; if (pos==1 || pos==7) i = -l-1; else i += l-1; if (j>0) j += l; if (j<0) j -= l; } text_x -= i; text_y += j; } else text_x += space+2; j = 0; /* used as line counter */ redo: ptr1 = NULL; l = strlen(text); for (i=0; iropt.smartlabels) { text_w = XTextWidth(xfont[nfont], text, strlen(text)); PixmapDrawString(s, text_x, text_y + j*fonth[nfont], text_w, fonth[nfont], text, strlen(text)); } else { if (city_already_shown) { XSetForeground(dpy, gc, s->color[C_FG_MARKED].pix); city_shown_box_x = text_x - 1; city_shown_box_y = text_y - fontasc[nfont]; text_w = XTextWidth(xfont[nfont], text, strlen(text)) + 1; if (text_w>city_shown_box_w) city_shown_box_w = text_w; city_shown_box_h = (j+1)*fonth[nfont] + 1; XDrawString(dpy, mainwin, gc, text_x, text_y + j*fonth[nfont], text, strlen(text)); } else XDrawString(dpy, s->pixmap, gc, text_x, text_y + j*fonth[nfont], text, strlen(text)); text_drawn = 1; } /* bail out if some overlapping occurred with the first lines */ if (!text_drawn) return; if (img_output == OUT_EPS) { if (j==0) { if (ind==-1) sprintf(line, "%.4f %.4f %.4f RGB f%d\n", s->red_current/65535.0, s->green_current/65535.0, s->blue_current/65535.0, nfont); else sprintf(line, "c%d f%d\n", ind, nfont); print_string(line); } reformat_string(name, text, 1); sprintf(line, "%.2f %.2f m (%s) %d %d %d %d SS\n", pt->coord[X], s->height - pt->coord[Y] - 1, name, pos, space+1, j, numl); print_string(line); } if (ptr1) { *(ptr1-2) = '\\'; text = ptr1; ++j; goto redo; } } void draw_segment(ImageLayout *s, ScreenPt a, ScreenPt b, Pixel color) { char line[256]; if (abs(b.coord[X]-a.coord[X])>escape_length) { path_start = 1; return; } XSetForeground(dpy, gc, color); XDrawLine(dpy, s->pixmap, gc, (int)a.coord[X], (int)a.coord[Y], (int)b.coord[X], (int)b.coord[Y]); if (img_output == OUT_EPS) { if (path_start) { sprintf(line, "%.2f %.2f m %.2f %.2f l\n", a.coord[X], s->height-a.coord[Y]-1.0, b.coord[X], s->height-b.coord[Y]-1.0); } else { sprintf(line, "%.2f %.2f l\n", b.coord[X], s->height-b.coord[Y]-1.0); } print_string(line); } path_start = 0; } Window make_window (int width, int height) { Window w; black = BlackPixel(dpy, scr); white = WhitePixel(dpy, scr); w = XCreateSimpleWindow(dpy, Root, 10, 10, width, height, 0, white, black); XSetWindowColormap(dpy, w, cmap); XSelectInput(dpy, w, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask | ExposureMask | StructureNotifyMask); wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False); wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(dpy, w, &wm_delete_window, 1); return w; } void close_datawin(ImageLayout * scene) { int i; city_found = -1; city_shown = 0; datawin_on = 0; get_window_placement(datawin, &datawin_x, &datawin_y, &i, &i); XUnmapWindow(dpy, datawin); XClearWindow(dpy, mainwin); } void close_flagwin(ImageLayout * scene) { int i; flagwin_on = 0; get_window_placement(flagwin, &flagwin_x, &flagwin_y, &i, &i); XUnmapWindow(dpy, flagwin); XClearWindow(dpy, mainwin); } void close_cmdwin(ImageLayout * scene) { int i; cmdwin_on = 0; cmd_mode = MODE_RUN; cmd_type = M_RUN_START; get_window_placement(cmdwin, &cmdwin_x, &cmdwin_y, &i, &i); XUnmapWindow(dpy, cmdwin); } Bool evpred(d, e, a) Display * d; XEvent * e; XPointer a; { if (e->type==Expose) { if (e->xexpose.window==mainwin) exposed |= MAIN_WINDOW; if (e->xexpose.window==datawin) exposed |= DATA_WINDOW; if (e->xexpose.window==cmdwin) exposed |= CMD_WINDOW; if (e->xexpose.window==explwin) exposed |= EXPL_WINDOW; if (e->xexpose.window==flagwin) exposed |= FLAG_WINDOW; } if (e->type==ConfigureNotify) { if (e->xexpose.window==mainwin) notified |= MAIN_WINDOW; if (e->xexpose.window==datawin) notified |= DATA_WINDOW; if (e->xexpose.window==cmdwin) notified |= CMD_WINDOW; if (e->xexpose.window==explwin) notified |= EXPL_WINDOW; if (e->xexpose.window==flagwin) notified |= FLAG_WINDOW; } return (True); } void clear_city_shown() { if (city_shown) XClearArea(dpy, mainwin, city_shown_box_x, city_shown_box_y, city_shown_box_w, city_shown_box_h, False); } void clear_strip(ImageLayout * scene, int pos) { if (pos==TOP) XClearArea(dpy, mainwin, 0, 0, scene->width, fonth[0]+6, False); if (pos==BOTTOM) XClearArea(dpy, mainwin, 0, scene->height-fonth[0]-6, scene->width, fonth[0]+6, False); } void do_caret(ImageLayout * scene, int u) { int l; l = strlen(cmd_string); caret_pos = 0; while (caret_poscolor[C_FG_SELRECT].pix); XDrawLine(dpy, mainwin, gc, u-wid, v, u+wid, v); XDrawLine(dpy, mainwin, gc, u, v-wid, u, v+wid); } void show_area_border(ImageLayout * scene, int x, int y) { int i1, j1, i2, j2; if (x>mouse_x2) { i1 = mouse_x2; i2 = x; } else { i1 = x; i2 = mouse_x2; } if (mouse_y2>mouse_y1) { j1 = mouse_y1; j2 = mouse_y2; } else { j1 = mouse_y2; j2 = mouse_y1; } if (i1>0) --i1; if (j1>0) --j1; XCopyArea(dpy, scene->pixmap, mainwin, gc, i1, j1, i2-i1+1, j2-j1+1, i1, j1); if (mouse_x2>mouse_x1) { i1 = mouse_x1; i2 = mouse_x2; } else { i1 = mouse_x2; i2 = mouse_x1; } if (y>mouse_y2) { j1 = mouse_y2; j2 = y; } else { j1 = y; j2 = mouse_y2; } if (i1>0) --i1; if (j1>0) --j1; XCopyArea(dpy, scene->pixmap, mainwin, gc, i1, j1, i2-i1+1, j2-j1+1, i1, j1); i1 = (mouse_x1+mouse_x2)/2; j1 = (mouse_y1+mouse_y2)/2; XCopyArea(dpy, scene->pixmap, mainwin, gc, i1-4, j1-4, 9, 9, i1-4, j1-4); mouse_x2 = x; mouse_y2 = y; if (mouse_x2>mouse_x1) { i1 = mouse_x1; i2 = mouse_x2; } else { i1 = mouse_x2; i2 = mouse_x1; } if (mouse_y2>mouse_y1) { j1 = mouse_y1; j2 = mouse_y2; } else { j1 = mouse_y2; j2 = mouse_y1; } if (i2-i1>maxmove) maxmove = i2-i1; if (j2-j1>maxmove) maxmove = j2-j1; XSetForeground(dpy, gc, scene->color[C_FG_SELRECT].pix); XDrawRectangle(dpy, mainwin, gc, i1, j1, i2-i1, j2-j1); i1 = (mouse_x1+mouse_x2)/2; j1 = (mouse_y1+mouse_y2)/2; show_new_center(scene, i1, j1, 4); } /* * SECTION 2 : PARSING ROUTINES */ void expand_path(char *str) { char *ptr; char buf[512]; if (str[0]=='~' && str[1]=='/' && (ptr=getenv("HOME"))) { strcpy(buf, ptr); strcat(buf, str+1); strncpy(str, buf, 255); str[255] = '\0'; } } void translate_string(char * str) { int i, l; l = strlen(str); for (i=0; i='0' && *ptr0<='9') *num = atoi(ptr0); else { i = 0; if (!strncasecmp(ptr0, "int", 3)) i = 0; else if (!strncasecmp(ptr0, "nat", 3)) i = 3; else if (!strncasecmp(ptr0, "riv", 3)) i = 5; else if (!strncasecmp(ptr0, "cil", 3)) i = 16; else if (!strncasecmp(ptr0, "ear", 3)) i = C_BG_MAP; else if (!strncasecmp(ptr0, "lab", 3)) i = C_CITY_CIRCLE; else if (!strncasecmp(ptr0, "mnu", 3)) i = C_FG_TEXT; else { *ptr = c; return NULL; } ptrp = ptr0+3; while (*ptrp>='A') ++ptrp; *num = i+atoi(ptrp); } *ptr = c; ++ptr; while (*ptr && isspace(*ptr)) ++ptr; return ptr; } void set_opt_color(ImageLayout * scene, char * string, int force) { int i; char *ptr; if (!(ptr=parse_item(string, &i))) return; if (*ptr && i>=0 && icolor[i].bool != INACTIVE || force) { if (i>=C_FG_TEXT) scene->color[i].bool = 1; get_color(ptr, scene, i); if (color_depth<=8) get_all_colors(scene); } } } void get_output_type(ImageLayout *scene) { int l; l = strlen(scene->outfile); if (l==0) { img_output = OUT_NONE; return; } if (!strcmp(scene->outfile+l-3, ".gz")) l-= 3; if (!strncmp(scene->outfile+l-4, ".ppm", 4)) img_output = OUT_PPM; else if (!strncmp(scene->outfile+l-4, ".xpm", 4)) img_output = OUT_XPM; else if (!strncmp(scene->outfile+l-4, ".eps", 4)) img_output = OUT_EPS; else if (!strncmp(scene->outfile+l-3, ".ps", 3)) img_output = OUT_PS; else if (!strncmp(scene->outfile+l-3, ".rc", 3)) img_output = OUT_RC; else /* otherwise set default format = XPM */ img_output = OUT_XPM; } void feature_undefine(ImageLayout *scene, int i) { int j; if (i<0 || i>=scene->numdef) return; if (scene->def[i]) free(scene->def[i]); --scene->numdef; for (j=i; jnumdef; j++) scene->def[j] = scene->def[j+1]; } void parse_define(ImageLayout *scene, char *ptr) { int i; if (!strncmp(ptr, "undef|", 6)) { feature_undefine(scene, atoi(ptr+6)); return; } if (*ptr == '*') { edit_rc_output(scene); return; } if (!strncmp(ptr, "eraseall", 8)) { scene->numpoint = 0; if (scene->mempoint) { free(scene->mempoint); scene->mempoint = NULL; } } if (!strncmp(ptr, "erase", 5)) { char *str; char needle[10]; int i, j, l = strlen(ptr); if (l==5) { str = malloc(8); if (line_clicked>=1) sprintf(str, ",%d,", line_clicked+start_list-1); else *str = '\0'; } else { str = malloc(l-2); *str = ','; for (i=1; inumpoint; i++) { sprintf(needle, ",%d,", i); if (strstr(str, needle)) scene->mempoint[2*i] = 100.0; } j = 0; for (i=0; inumpoint; i++) { scene->mempoint[2*j] = scene->mempoint[2*i]; scene->mempoint[2*j+1] = scene->mempoint[2*i+1]; if (scene->mempoint[2*i]<95.0) ++j; } scene->numpoint = j; free(str); return; } if (!strncmp(ptr, "input|", 6)) { char *str0, *str = NULL; int start = 1; double x, y; str0 = strdup(ptr+6); while (1) { if (start) { str = (char *)strtok(str0, ","); start = 0; } else str = (char *)strtok(NULL, ","); if (!str) break; x = dms2decim(str); str = strtok(NULL, "|"); if (!str) break; y = dms2decim(str); ++scene->numpoint; scene->mempoint = (double *) realloc(scene->mempoint, 2*scene->numpoint*sizeof(double)); scene->mempoint[2*scene->numpoint-2] = x; scene->mempoint[2*scene->numpoint-1] = y; } free(str0); return; } i = scene->numdef; ++scene->numdef; scene->def = (char**)realloc(scene->def, scene->numdef*sizeof(char *)); scene->def[i] = malloc((strlen(ptr)+2)*sizeof(char)); if (scene->def[i]) { strcpy(scene->def[i]+1, ptr); if (!strncmp(ptr, "modif|", 6)) scene->def[i][0] = (char)1; else if (!strncmp(ptr, "exec|", 5)) scene->def[i][0] = (char)2; else scene->def[i][0] = (char)0; } } void parse_rcfile (ImageLayout *s) { FILE *frc = NULL; int i, j, pos=0, parselevel=0, numtype; int ret, length, line_number=0; char buf[512]; char type[256]; char item_color[256]; char active; char *str, *ptr; /* initialize stuff */ length = 512; str = (char *) malloc(length); /* read the color config file and allocate colors */ if (theming) frc = fopen(s->theme, "r"); else frc = fopen(s->rcfile, "r"); /* if relative path && open failed try in SHAREDIR/rc/ directory if just a plain rcfile or in SHAREDIR/themes/ directory if this is a theme */ if (frc == NULL && s->rcfile[0]!= '/' && s->rcfile[0]!= '.') { if (theming) sprintf(str, "%s/themes/%s", SHAREDIR, s->theme); else sprintf(str, "%s/rc/%s", SHAREDIR, s->rcfile); frc = fopen(str, "r"); } if (frc == NULL) { sprintf(str, msg[COULDNT_OPEN_RCFILE], s->rcfile); fprintf(stderr, "%s\n", str); if (runlevel==0) { exit(-2); } else { draw_win_string(s, mainwin, str, BOTTOM); XFlush(dpy); usleep(WARNING_TIME); return; } } j = 0; /* now parse the file */ longline: while ((ret = fread(buf, 1, 510, frc)) != 0) { pos = (int) ftell(frc) - ret; for (i=0; i=length-2) { length += 512; str = realloc(str, length); } if (buf[i] == '\n') { line_number++; str[j] = '\0'; fseek(frc, pos+i+1, SEEK_SET); break; } str[j++] = buf[i]; } if (buf[i] != '\n') { if (ret<510) str[j] = '\0'; else goto longline; } /* remove comments */ for (i=0; i0 && isspace(str[j-1])) str[--j] = '\0'; /* don't consider blank lines */ if (j==0) continue; /* remove initial blank characters */ i = 0; while (str[i] && isspace(str[i])) ++i; if (i>0) { j = i; while (str[j]) { str[j-i] = str[j]; ++j; } str[j-i] = '\0'; } j = 0; if (str[0] == '<') { if (!strncasecmp(str, "", 8)) parselevel = 0; else if (!strncasecmp(str, "", 12)) parselevel = 1; else if (!strncasecmp(str, "", 9)) parselevel = 2; continue; } if (parselevel==0) { ret = sscanf(str, "%s %c%s", type, &active, item_color); strcat(type, " /"); (void)parse_item(type, &numtype); ptr = item_color; if (ptr) while (*ptr && isspace(*ptr)) ++ptr; if (ret != 3 || (active!='+' && active!='-')) { fprintf(stderr, msg[UNABLE_PARSE_STRING], str, line_number, s->rcfile); fprintf(stderr, "\n"); continue; } if (numtype < 0 || numtype >= C_ENDCOLOR) { fprintf(stderr, msg[VALUE_OUT_OF_RANGE], C_ENDCOLOR-1, line_number, s->rcfile); fprintf(stderr, "\n"); } else { if (active == '+') s->color[numtype].bool = ON; else if (active == '-') s->color[numtype].bool = OFF; if (s->color[numtype].bool != INACTIVE) { strncpy(s->color[numtype].name, ptr, 39); s->color[numtype].name[39] = '\0'; } } } if (parselevel==1) { parse_cmd_line(s, str, " "); continue; } if (parselevel==2) { parse_define(s, str); continue; } } fclose(frc); free(str); } void update_auxil_windows(ImageLayout *scene) { int i; if (cmdwin_on) draw_win_cmd(scene, 0); if (datawin_on) { old_city_shown = -2; for (i=0; i<=1; i++) { if (flag_image[i]) XDestroyImage(flag_image[i]); flag_image[i] = NULL; } show_datawin(scene, 0); } if (flagwin_on) { if (big_flag_image) XDestroyImage(big_flag_image); big_flag_image = NULL; show_flagwin(scene, 0); } if (explwin_on) show_explwin(scene, 0, 0); } void set_auxil_win_background(ImageLayout * scene) { if (datapix) XSetWindowBackgroundPixmap(dpy, datawin, datapix); else XSetWindowBackground(dpy, datawin, scene->color[C_BG_TEXT].pix); if (cmdpix) XSetWindowBackgroundPixmap(dpy, cmdwin, cmdpix); else XSetWindowBackground(dpy, cmdwin, scene->color[C_BG_CMDWIN].pix); XSetWindowBackground(dpy, flagwin, scene->color[C_BG_TEXT].pix); if (explpix) XSetWindowBackgroundPixmap(dpy, explwin, explpix); else XSetWindowBackground(dpy, explwin, scene->color[C_BG_CMDWIN].pix); } void parse_theme(ImageLayout *scene) { if (scene->theme[0]) { theming = 1; parse_rcfile(scene); theming = 0; get_all_colors(scene); parse_pixmaps(scene, NULL); set_auxil_win_background(scene); if (color_depth<=8) { if (datawin_on) { XUnmapWindow(dpy, datawin); XMapWindow(dpy, datawin); } if (cmdwin_on) { XUnmapWindow(dpy, cmdwin); XMapWindow(dpy, cmdwin); } if (flagwin_on) { XUnmapWindow(dpy, flagwin); XMapWindow(dpy, flagwin); } if (explwin_on) { XUnmapWindow(dpy, explwin); XMapWindow(dpy, explwin); } generate(scene); show_mark(scene); } update_auxil_windows(scene); } } int strpcmp(char *s, char *t, int n) { int mode; if (n<0) { mode = 0; n = -n; } else mode = 1; if (!s || !t) return -1; if (runlevel==0 && *s!='-' && *s!='+') return -1; if (*t!='+' && *t!='-') { while(*s=='-') ++s; } if (strlen(s)strlen(t)) return -1; n = strlen(s); if (mode) return strncmp(s, t, n); else return strncasecmp(s, t, n); } int color_number(int mode, char * str) { int i, run; char *endptr; if (!str) return -1; run = runlevel; runlevel = 1; if (mode) for (i = 0; i < NUM_CONTINENTS; i++) { if (!strpcmp(str, continent_name[i], -2)) { runlevel = run; return i+1; } } else for (i = 0; i < NUM_ITEMS; i++) { if (!strpcmp(str, item_name[i], -2)) { runlevel = run; return i; } } runlevel = run; i = strtol(str, &endptr, 10); if (!endptr) return -1; return i; } double angle_inc(double z) { double norm[] = { 1.0, 0.75, 0.5, 0.3, 0.2, 0.15 }; double val, valn, fact; int i; if (z<=1.0) return 15.0; val = 15.0/z; valn = 10.0; fact = 10.0; i=0; while (valn>val) { ++i; if (i>5) { fact *= 0.1; i = 0; } valn = norm[i]*fact; } return valn; } void check_spacing(ImageLayout * scene) { if (scene->ropt.spacing_lat< 1.0/scene->gopt.zoom) scene->ropt.spacing_lat = angle_inc(scene->gopt.zoom); if (scene->ropt.spacing_lon< 1.0/scene->gopt.zoom) scene->ropt.spacing_lon = angle_inc(scene->gopt.zoom); } void check_lineorder(ImageLayout * scene) { char str[6]; int busy[5]; int i, j; i=0; j=0; bzero(busy, sizeof(busy)); for (i=0; igopt.lineorder); i++) { if (scene->gopt.lineorder[i]>='0' && scene->gopt.lineorder[i]<='4' && !busy[scene->gopt.lineorder[i]-'0']) { busy[scene->gopt.lineorder[i]-'0'] = 1; str[j] = scene->gopt.lineorder[i]; ++j; } } str[j] = '\0'; strcpy(scene->gopt.lineorder, str); } void set_radius(ImageLayout * scene) { scene->earth_radius = (double)(scene->width/2); if (scene->projection==SPHERICAL && scene->width>scene->height) scene->earth_radius = (double)(scene->height/2); scene->shiftx = 0.5*scene->width; scene->shifty = 0.5*scene->height; } int set_continents(ImageLayout * scene, char *c, int mode) { char * number, *ptr1, *ptr2; char str[256]; int i, tot; if (!strcasecmp(c, "all")) { if (mode) scene->gopt.desired_continents = 0xFFFFFFFF; else scene->gopt.desired_categories = 0xFFFFFFFF; return 0; } number = (char *) malloc(strlen(c)+2); ptr1 = c; tot = 0; while (ptr1 && *ptr1) { ptr2 = index(ptr1, ','); strcpy(number, ptr1); if (ptr2) number[ptr2-ptr1] = '\0'; i = color_number(mode, number); if (i < 1 || i > 4+2*mode) { sprintf(str, msg[PARAMETER_RANGE], itemtype[mode], 4+2*mode, "\n"); if (runlevel) draw_win_string(scene, cmdwin, str, BOTTOM); free(number); return 1; } tot |= (0x00000001 << (i-1)); if (ptr2) ptr1 = ptr2+1; else ptr1 = NULL; } if (mode) scene->gopt.desired_continents = tot; else scene->gopt.desired_categories = tot; free(number); return 0; } void usage() { int i, l; printf("%s\n", msg[BEGIN_USAGE]); for (i=BEGIN_USAGE+1; i=NUMPROJ) projection = SPHERICAL; } runlevel = run; return projection; } void free_countries() { int i; for (i=0; iname); free(countries[i]->flags); free(countries[i]->curr_code); free(countries[i]->currency); free(countries[i]->telephone); free(countries[i]->capital); free(countries[i]); } free(countries); countries = NULL; numcountry = 0; } void free_TZ() { int i; if (timezones) { for (i=0; icode); free(timezones[i]->flags); free(timezones[i]->name); free(timezones[i]->posix); free(timezones[i]); } free(timezones); timezones = NULL; } numtz = 0; } void free_locations() { int i; if (locations) { for (i=0; iname) free(locations[i]->name); if (locations[i]->region) free(locations[i]->region); free(locations[i]); } free(locations); locations = NULL; } numloc = 0; } void free_preselected() { if (presel_pointer) free(presel_pointer); } void free_data_buffers(ImageLayout * scene) { if (segment_index) { free(segment_index); segment_index = NULL; } if (fullmap_buffer) { free(fullmap_buffer); fullmap_buffer = NULL; segment_buffer = NULL; } else { free (segment_buffer); segment_buffer = NULL; } } void error_tz(char * sect, char * str) { fprintf(stderr, "Incorrect timezone label in section <%s> : %s\n", sect, str); } #define BIGNUM 100000000 void reordering(char mode) { long int v, *value; int i, j, k, n, step; int *order, *rank, *minrank; value = malloc(numloc*sizeof(long int)); order = malloc(numloc*sizeof(int)); rank = malloc(numloc*sizeof(int)); minrank = malloc(numcountry*sizeof(int)); for (step=0; step<=2; step++) { bzero(value, numloc*sizeof(long int)); bzero(order, numloc*sizeof(int)); n = 0; for (i=0; iobj==mode) { if (i%500==0) fprintf(stderr, "Step %d, %d \n", step, i); if (mode=='p') v = locations[i]->alt; else v = locations[i]->population; if (step==1) v += BIGNUM*timezones[locations[i]->tz]->continent; else if (step==2) v += BIGNUM*timezones[locations[i]->tz]->country; value[n] = v; order[n] = i; for (j=0; j<=n-1; j++) { if (v>value[j]) { for (k=n; k>j; k--) { value[k] = value[k-1]; order[k] = order[k-1]; } value[j] = v; order[j] = i; break; } } ++n; } } for (i=0; iobj==mode) { locations[i]->worldrank = rank[i]+1; } } if (step==1) { for (i=0; iobj==mode) { j = timezones[locations[i]->tz]->continent; if (rank[i]obj==mode) { j = timezones[locations[i]->tz]->continent; locations[i]->contrank = rank[i]-minrank[j]+1; } } } if (step==2) { for (i=0; iobj==mode) { j = timezones[locations[i]->tz]->country; if (rank[i]obj==mode) { j = timezones[locations[i]->tz]->country; locations[i]->rank = rank[i]-minrank[j]+1; } } } } free(minrank); free(value); free(order); free(rank); } void simplify_string(char * str) { int i, j=0, l; l = strlen(str); for (i=0; iobj=='c') { distp = fabs(locations[i]->lat-x)+fabs(locations[i]->lon-y); if (distplat, locations[numloc]->lon); itz = locations[j]->tz; printf("%s|%s|%s|%s|%s|%s\n", timezones[itz]->code, locations[j]->region, field[1], field[2], field[3], field[4]); */ void parse_locfile(ImageLayout *s) { FILE *f; char buf[512], lat_str[40], lon_str[40]; char field[11][128]; char *sect[] = { "", "countries", "timezones", "cities", "peaks", "locations", "preselected" }; char *str, *ptr, *ptrp; int bool, i, j, itz=0, numfields, datatype; if (!s->locfile || !*s->locfile) return; f = fopen(s->locfile, "r"); if (f == NULL) { sprintf(buf, msg[COULDNT_OPEN_LOCFILE], s->locfile); if (runlevel==0) fprintf(stderr, "%s\n", buf); else { draw_win_string(s, cmdwin, buf, BOTTOM); XFlush(dpy); usleep(WARNING_TIME); } return; } numfields = 0; datatype = T_NONE; while((str=fgets(buf, 510, f))) { while (*str && isspace(*str)) ++str; if (!*str || *str=='%') continue; if (*str=='<') { if (!strncmp(str, "", 17)) { free_countries(); continue; } if (!strncmp(str, "", 10)) { free_TZ(); continue; } if (!strncmp(str, "", 17)) { free_locations(); continue; } if (!strncmp(str, "", 19)) { free_preselected(); continue; } if (!strncmp(str, "", 11)) { datatype = T_COUNTRIES; numfields = 12; continue; } if (!strncmp(str, "", 11)) { datatype = T_TIMEZONES; numfields = 6; continue; } if (!strncmp(str, "", 8)) { datatype = T_CITIES; itz = 0; numfields = 11; continue; } if (!strncmp(str, "", 10)) { datatype = T_AIRPORTS; itz = 0; numfields = 8; continue; } if (!strncmp(str, "", 15)) { datatype = T_OBSERVATORIES; itz = 0; numfields = 6; continue; } if (!strncmp(str, "", 7)) { datatype = T_PEAKS; itz = 0; numfields = 9; continue; } if (!strncmp(str, "", 11)) { datatype = T_LOCATIONS; numfields = 8; continue; } if (!strncmp(str, "", 13)) { datatype = T_PRESELECTED; numfields = 3; continue; } if (datatype==T_COUNTRIES && !strncmp(str, "", 12)) { datatype = T_NONE; numfields = 0; continue; } if (datatype==T_TIMEZONES && !strncmp(str, "", 12)) { datatype = T_NONE; numfields = 0; continue; } if (datatype==T_CITIES && !strncmp(str, "", 9)) { datatype = T_NONE; numfields = 0; continue; } if (datatype==T_AIRPORTS && !strncmp(str, "", 11)) { datatype = T_NONE; numfields = 0; continue; } if (datatype==T_OBSERVATORIES && !strncmp(str, "", 16)) { datatype = T_NONE; numfields = 0; continue; } if (datatype==T_PEAKS && !strncmp(str, "", 8)) { datatype = T_NONE; numfields = 0; continue; } if (datatype==T_LOCATIONS && !strncmp(str, "", 12)) { datatype = T_NONE; numfields = 0; continue; } if (datatype==T_PRESELECTED && !strncmp(str, "", 14)) { datatype = T_NONE; numfields = 0; continue; } } bool = 0; for (i=0; icode2, field[0]); strcpy(countries[numcountry]->code3, field[1]); strcpy(countries[numcountry]->cia, field[4]); strcpy(countries[numcountry]->iana, field[5]); countries[numcountry]->name = strdup(field[2]); countries[numcountry]->flags = strdup(field[3]); countries[numcountry]->curr_code = strdup(field[6]); countries[numcountry]->currency = strdup(field[7]); countries[numcountry]->telephone = strdup(field[8]); countries[numcountry]->capital = strdup(field[9]); countries[numcountry]->area = atoi(field[10]); countries[numcountry]->population = atoi(field[11]); #ifdef DEBUG fprintf(stderr, "%d : %s\n", numcountry, countries[numcountry]->name); #endif ++numcountry; } else if (datatype==T_TIMEZONES) { timezones = (Timezone **) realloc(timezones, (numtz+1)*sizeof(Timezone *)); timezones[numtz] = malloc(sizeof(Timezone)); timezones[numtz]->code = strdup(field[0]); i = (field[1][0]-'A')*26+(field[1][1]-'A'); timezones[numtz]->country = country_table[i]; timezones[numtz]->flags = strdup(field[3]); timezones[numtz]->name = strdup(field[4]); timezones[numtz]->posix = strdup(field[5]); for (i=0; i<=5; i++) { if (!strcasecmp(field[2], continent[i])) { timezones[numtz]->continent = i; break; } } ++numtz; } else if (datatype==T_CITIES) { locations = (Location **) realloc(locations, (numloc+1)*sizeof(Location *)); locations[numloc] = malloc(sizeof(Location)); locations[numloc]->obj = 'c'; locations[numloc]->draw = 0; locations[numloc]->name = strdup(field[1]); locations[numloc]->status = field[2][0]; locations[numloc]->region = strdup(field[3]); locations[numloc]->population = atoi(field[4]); locations[numloc]->rank = atoi(field[5]); locations[numloc]->contrank = atoi(field[6]); locations[numloc]->worldrank = atoi(field[7]); locations[numloc]->lat = dms2decim(field[8]); locations[numloc]->lon = dms2decim(field[9]); if (index(field[10],'?')) locations[numloc]->alt = -30000; else locations[numloc]->alt = round2int(atof(field[10])); locations[numloc]->tz = -1; bool = 1; for (i=0; icode)) { locations[numloc]->tz = j; itz = j; bool = 0; break; } } if (bool) error_tz("locations", field[0]); ++numloc; } else if (datatype==T_AIRPORTS) { locations = (Location **) realloc(locations, (numloc+1)*sizeof(Location *)); locations[numloc] = malloc(sizeof(Location)); locations[numloc]->obj = 'a'; locations[numloc]->draw = 0; locations[numloc]->status = '*'; locations[numloc]->tz = -1; bool = 1; for (i=0; icode)) { locations[numloc]->tz = j; itz = j; bool = 0; break; } } if (bool) error_tz("airports", field[0]); locations[numloc]->name = strdup(field[1]); locations[numloc]->region = strdup(field[2]); locations[numloc]->rank = atoi(field[3]); locations[numloc]->population = atoi(field[4]); locations[numloc]->lat = dms2decim(field[5]); locations[numloc]->lon = dms2decim(field[6]); locations[numloc]->alt = atoi(field[7]); ++numloc; } else if (datatype==T_OBSERVATORIES) { locations = (Location **) realloc(locations, (numloc+1)*sizeof(Location *)); locations[numloc] = malloc(sizeof(Location)); locations[numloc]->obj = 'b'; locations[numloc]->draw = 0; locations[numloc]->status = '*'; locations[numloc]->tz = -1; bool = 1; for (i=0; icode)) { locations[numloc]->tz = j; itz = j; bool = 0; break; } } if (bool) error_tz("observatories", field[0]); locations[numloc]->name = strdup(field[1]); locations[numloc]->region = strdup(field[2]); locations[numloc]->lat = dms2decim(field[3]); locations[numloc]->lon = dms2decim(field[4]); locations[numloc]->alt = atoi(field[5]); ++numloc; } else if (datatype==T_PEAKS) { locations = (Location **) realloc(locations, (numloc+1)*sizeof(Location *)); locations[numloc] = malloc(sizeof(Location)); locations[numloc]->obj = 'p'; locations[numloc]->draw = 0; locations[numloc]->status = '*'; locations[numloc]->tz = -1; bool = 1; for (i=0; icode)) { locations[numloc]->tz = j; itz = j; bool = 0; break; } } if (bool) error_tz("peaks", field[0]); locations[numloc]->name = strdup(field[1]); locations[numloc]->region = strdup(field[2]); locations[numloc]->rank = atoi(field[3]); locations[numloc]->contrank = atoi(field[4]); locations[numloc]->worldrank = atoi(field[5]); locations[numloc]->lat = dms2decim(field[6]); locations[numloc]->lon = dms2decim(field[7]); locations[numloc]->alt = atoi(field[8]); ++numloc; } else if (datatype==T_LOCATIONS) { locations = (Location **) realloc(locations, (numloc+1)*sizeof(Location *)); locations[numloc] = malloc(sizeof(Location)); locations[numloc]->obj = 'l'; locations[numloc]->draw = 0; locations[numloc]->name = strdup(field[0]); locations[numloc]->status = field[3][0]; locations[numloc]->population = atoi(field[4]); locations[numloc]->region = NULL; locations[numloc]->alt = (int)(field[5][1]-'0'); locations[numloc]->lat = dms2decim(field[6]); locations[numloc]->lon = dms2decim(field[7]); locations[numloc]->contrank = 0; locations[numloc]->worldrank = 0; if (strcmp(field[1],"-")) { i = (field[1][0]-'A')*26+(field[1][1]-'A'); locations[numloc]->rank = country_table[i]; } else locations[numloc]->rank = -1; locations[numloc]->tz = -1; for (i=0; i<=5; i++) { if (!strcasecmp(field[2], continent[i])) { locations[numloc]->tz = i; break; } } ++numloc; } else if (datatype==T_PRESELECTED) { char c; double lat, lon; for (i=0; i='A' && c<='Z') c += 32; if (c>=(char)192) c=cvs[c-192]; field[0][i] = c; } lat = dms2decim(field[1]); lon = dms2decim(field[2]); for (i=0; ilat-lat)>0.01) continue; if (fabs(locations[i]->lon-lon)>0.01) continue; strcpy(field[3], locations[i]->name); if (locations[i]->obj!='c') simplify_string(field[3]); if (string_cmp(field[3], field[0])) { presel_pointer = (int *) realloc(presel_pointer, (numpresel+1)*sizeof(int)); presel_pointer[numpresel] = i; ++numpresel; break; } } } } fclose(f); if (ranking) { char alt[20]; reordering((char)ranking); for (i=0; ialt<=-30000) strcpy(alt, "?"); else sprintf(alt, "%d", locations[i]->alt); decim2dms(locations[i]->lat, lat_str); decim2dms(locations[i]->lon, lon_str); if (locations[i]->obj=='c' && ranking==(int)'c') printf("%s|%s|%c|%s|%d|%d|%d|%d|%s|%s|%s\n", timezones[locations[i]->tz]->code, locations[i]->name, locations[i]->status, locations[i]->region, locations[i]->population, locations[i]->rank, locations[i]->contrank, locations[i]->worldrank, lat_str, lon_str, alt); else if (locations[i]->obj=='p' && ranking==(int)'p') printf("%s|%s|%s|%d|%d|%d|%s|%s|%d\n", timezones[locations[i]->tz]->code, locations[i]->name, locations[i]->region, locations[i]->rank, locations[i]->contrank, locations[i]->worldrank, lat_str, lon_str, locations[i]->alt); else if (locations[i]->obj=='l' && ranking==(int)'l') printf("%s|%s|%c|%d|p%d|%s|%s\n", locations[i]->name, continent[locations[i]->tz], locations[i]->status, locations[i]->population, locations[i]->rank, lat_str, lon_str); } } } void read_i18n_file(ImageLayout * scene) { FILE *fd; char *ptr; char buf[512]; char i18n_file[256]; int i, j, l, n; if (!*language) { if (getenv("LANG")) { strncpy(language, getenv("LANG"), 2); language[2] = '\0'; } else strcpy(language, "en"); } sprintf(i18n_file, "%s/xrmap_msg.%s", I18NPATH, language); fd = fopen(i18n_file, "r"); if (!fd) { fprintf(stderr, "Couldn't find %s !!\n", i18n_file); retry: strcpy(language, "en"); sprintf(i18n_file, "%s/xrmap_msg.en", I18NPATH); fprintf(stderr, "Using instead default %s\n", i18n_file); fd = fopen(i18n_file, "r"); } if (!fd) { fprintf(stderr, "Cannot open language file %s !!\n", i18n_file); exit(-1); } if (msg) { for (i=0; i=0 && isspace(ptr[l])) { ptr[l] = '\0'; --l; } if (l<0) continue; msg[num_msg] = strdup(ptr); ++num_msg; } fclose(fd); if (num_msg=0 && lcolor[l].comment = ptr+3; } } void load_city_filter(ImageLayout * scene, char *str) { char ch; int j, k; *scene->ropt.city_filter ='\0'; k = 0; for (j=0;jropt.city_filter, ch)) continue; if (index(city_filter0, ch)) { scene->ropt.city_filter[k] = ch; ++k; scene->ropt.city_filter[k] = '\0'; } } } void load_loc_filter(ImageLayout * scene, char *str) { char ch; int j, k; *scene->ropt.loc_filter ='\0'; k = 0; for (j=0;jropt.loc_filter, ch)) continue; if (index(loc_filter0, ch)) { scene->ropt.loc_filter[k] = ch; ++k; scene->ropt.loc_filter[k] = '\0'; } } } char * list_languages() { int i; char dirname[256]; char *ptr, *str; struct dirent *dirent; DIR *dir; sprintf(dirname, "%s/i18n", SHAREDIR); dir = opendir(dirname); if (dir == NULL) return ""; i = 0; str = (char *)malloc((3+i)*sizeof(char)); str[0] = '\0'; for (dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) { ptr = dirent->d_name; if (!strncmp(ptr, "xrmap_msg.", 10)) { ptr = ptr+10; if (i!=0) { str[i] = ','; str[++i] = '\0'; } i += strlen(ptr); str = realloc(str, (3+i)*sizeof(char)); strcat(str, ptr); } } closedir(dir); return str; } int set_grid_coordinates(char c) { if (toupper(c) == 'T') return 1; if (toupper(c) == 'L') return 1; if (toupper(c) == 'B') return 2; if (toupper(c) == 'R') return 2; if (c == '1') return 1; if (c == '2') return 2; return 0; } char get_grid_coordinates(int i, int mode) { if (i==0) return '0'; if (mode==0) { if (i==1) return 'L'; if (i==2) return 'R'; } if (mode==1) { if (i==1) return 'T'; if (i==2) return 'B'; } return '?'; } void get_button_dimensions() { int x, y; unsigned int b, d; Window root; if (butpix[0]) { XGetGeometry(dpy, butpix[0], &root, &x, &y, &w_buttons, &h_button, &b, &d); w_buttons += 1; h_button += 1; w_button = (w_buttons-4)/NUM_BUTTONS; } else { w_buttons = 172; w_button = 28; h_button = 29; } } int parse_pixmaps(ImageLayout *scene, char *str) { int i, ret = 0, bool; char name[256]; bool = runlevel && !theming; if (!str || !index(str, '|')) { if (str) { if (datapix_name) free(datapix_name); if (cmdpix_name) free(cmdpix_name); if (explpix_name) free(explpix_name); datapix_name = strdup(str); cmdpix_name = strdup(str); explpix_name = strdup(str); } if (bool) { if (datapix) XFreePixmap(dpy, datapix); datapix = xim2pix(readIMG(scene, PIXMAPPATH, datapix_name, 0, &scene->color[C_BG_TEXT])); if (cmdpix) XFreePixmap(dpy, cmdpix); cmdpix = xim2pix(readIMG(scene, PIXMAPPATH, cmdpix_name, 0, &scene->color[C_BG_TEXT])); if (explpix) XFreePixmap(dpy, explpix); explpix = xim2pix(readIMG(scene, PIXMAPPATH, explpix_name, 0, &scene->color[C_BG_TEXT])); ret = 1; } } if (str && !strncmp(str, "data|", 5)) { if (datapix_name) free(datapix_name); ret = 1; datapix_name = strdup(str+5); if (bool) { if (datapix) XFreePixmap(dpy, datapix); datapix = xim2pix(readIMG(scene, PIXMAPPATH, datapix_name, 0, &scene->color[C_BG_TEXT])); } } if (str && !strncmp(str, "cmd|", 4)) { if (cmdpix_name) free(cmdpix_name); ret = 1; cmdpix_name = strdup(str+4); if (bool) { if (cmdpix) XFreePixmap(dpy, cmdpix); cmdpix = xim2pix(readIMG(scene, PIXMAPPATH, cmdpix_name, 0, &scene->color[C_BG_TEXT])); } } if (str && !strncmp(str, "exp|", 4)) { if (explpix_name) free(explpix_name); ret = 1; explpix_name = strdup(str+4); if (bool) { if (explpix) XFreePixmap(dpy, explpix); explpix = xim2pix(readIMG(scene, PIXMAPPATH, explpix_name, 0, &scene->color[C_BG_TEXT])); } } for (i=0; i<=2; i++) { sprintf(name, "button%d|", i); if (!str || !strncmp(str, name, 8)) { ret = 1; if (str) { if (butpix_name[i]) free(butpix_name[i]); butpix_name[i] = strdup(str+8); } if (bool) { if (butpix[i]) XFreePixmap(dpy, butpix[i]); if (butpix_name[i]) strcpy(name, butpix_name[i]); else sprintf(name, DEFAULTBUTTONS, i); butpix[i] = xim2pix(readIMG(scene, PIXMAPPATH, name, 0, &scene->color[C_BG_TEXT])); get_button_dimensions(); } } } if (bool && ret) { set_auxil_win_background(scene); update_auxil_windows(scene); } return ret; } int parse_cmd_line(ImageLayout * scene, char *str, char *sep) { char *string, *ptr, *ptr_err; int w0, h0; if (!str || !*str) return -1; string = strdup(str); w0 = scene->width; h0 = scene->height; while ((ptr = (char*) strtok(string, sep)) != NULL) { ptr_err = ptr; string = NULL; if (!runlevel && !strpcmp(ptr, "help", 1)) { usage(); exit(0); } else if (!runlevel && !strpcmp(ptr, "version", 1)) { printf(msg[VERSION_FORMAT], PACKAGE, VERSION, DATEPKG, "\n", COPYRIGHT); printf("\n"); exit(0); } else if (!runlevel && !strpcmp(ptr, "menu", 4)) { ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; start_menu = (int)*ptr; } else if (!strpcmp(ptr, "language", 4)) { ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if (strcmp(ptr, language)) { strncpy(language, ptr, 2); language[2] = '\0'; read_i18n_file(scene); fix_features_description(scene); } } else if (!strpcmp(ptr, "mapfile", 4)) { ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if (!strcasecmp(ptr, "default")) strncpy(scene->mapfile, MAPFILE, 255); else strncpy(scene->mapfile, ptr, 255); scene->mapfile[255] = '\0'; expand_path(scene->mapfile); free_data_buffers(scene); } else if (!strpcmp(ptr, "rcfile", 3)) { ptr = (char*) strtok(NULL, sep); if (!ptr || (ptr && *ptr == '\0') || (ptr && !strcasecmp(ptr, "null")) || (ptr && !strcasecmp(ptr, "none"))) *scene->rcfile = '\0'; else { if (!strcasecmp(ptr, "default")) strncpy(scene->rcfile, RCFILE, 255); else strncpy(scene->rcfile, ptr, 255); scene->rcfile[255] = '\0'; expand_path(scene->rcfile); if (runlevel) parse_rcfile(scene); } } else if (!strpcmp(ptr, "locfile", 4)) { ptr = (char*) strtok(NULL, sep); if (!ptr || (ptr && *ptr == '\0') || (ptr && !strcasecmp(ptr, "null")) || (ptr && !strcasecmp(ptr, "none"))) *scene->locfile = '\0'; else { if (!strcasecmp(ptr, "default")) strncpy(scene->locfile, LOCFILE, 255); else strncpy(scene->locfile, ptr, 255); scene->locfile[255] = '\0'; expand_path(scene->locfile); parse_locfile(scene); } } else if (!strpcmp(ptr, "outfile", 4)) { ptr = (char*) strtok(NULL, sep); if (!ptr || (ptr && *ptr == '\0') || (ptr && !strcasecmp(ptr, "null")) || (ptr && !strcasecmp(ptr, "none"))) *scene->outfile = '\0'; else { strncpy(scene->outfile, ptr, 255); scene->outfile[255] = '\0'; } } else if (!strpcmp(ptr, "psmacros", 5)) { ptr = (char*) strtok(NULL, sep); if (!ptr || (ptr && *ptr == '\0') || (ptr && !strcasecmp(ptr, "null")) || (ptr && !strcasecmp(ptr, "none"))) *scene->macrofile = '\0'; else { strncpy(scene->macrofile, ptr, 255); scene->macrofile[255] = '\0'; } } else if (!strpcmp(ptr, "theme", 5)) { ptr = (char*) strtok(NULL, sep); if (ptr && *ptr) { strncpy(scene->theme, ptr, 255); scene->theme[255] = '\0'; expand_path(scene->theme); if (runlevel) parse_theme(scene); } } else #ifdef SEG_SELECT if (!strpcmp(ptr, "segment", 3)) { ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if (!strncasecmp(ptr, "mode", 4)) { ptr = index(ptr, '|'); if (!ptr) goto error; ++ptr; seg_mode = atoi(ptr); if (seg_mode<0 || seg_mode>3) seg_mode = 0; } else if (!strncasecmp(ptr, "mark", 4)) { ptr = index(ptr, '|'); if (!ptr) goto error; ++ptr; ++seg_nummarked; seg_specified = realloc(seg_specified, seg_nummarked * sizeof(int)); seg_specified[seg_nummarked-1] = atoi(ptr); } else goto error; } else #endif #ifdef ARCINFO if (!strpcmp(ptr, "arcinfo", 3)) { ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if (!strncasecmp(ptr, "precision", 9)) { int i; ptr = index(ptr, '|'); if (!ptr) goto error; i = atoi(ptr+1); if (i<=2) i = 2; if (i>=12) i = 12; arc_precision = i; } else if (!strncasecmp(ptr, "search", 6)) arc_search = 1; else if (!strncasecmp(ptr, "lambert", 7)) arc_lambert = 1; else if (!strncasecmp(ptr, "lat", 3)) { ptr = index(ptr, '|'); if (!ptr) goto error; ++ptr; arc_lat0 = atof(ptr); } else if (!strncasecmp(ptr, "lon", 3)) { ptr = index(ptr, '|'); if (!ptr) goto error; ++ptr; arc_lon0 = atof(ptr); } else if (!strncasecmp(ptr, "scale", 5)) { ptr = index(ptr, '|'); if (!ptr) goto error; ++ptr; arc_scale = atof(ptr); } else if (!strncasecmp(ptr, "transl", 6)) { ptr = index(ptr, '|'); if (!ptr) goto error; ++ptr; arc_transl = atof(ptr); } else if (!strncasecmp(ptr, "read", 4)) { ptr = index(ptr, '|'); if (!ptr) goto error; ++ptr; arc_file = strdup(ptr); } else goto error; } else if (!strpcmp(ptr, "dump", 4)) { ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if (!strncasecmp(ptr, "split", 5)) { dump_split = 1; } else if (!strncasecmp(ptr, "jpd", 3)) { dump_format = DUMP_JPD; } else if (!strncasecmp(ptr, "ascii", 5)) { dump_format = DUMP_ASCII; } else if (!strncasecmp(ptr, "stat", 4)) { dump_format = DUMP_STAT; } else if (!strncasecmp(ptr, "silent", 6)) { dump_verbose = 0; } else if (!strncasecmp(ptr, "precision", 9)) { int i; ptr = index(ptr, '|'); if (!ptr) goto error; i = atoi(ptr+1); if (i<=2) i = 2; if (i>=12) i = 12; sprintf(dump_precision, "%%.%df %%.%df\n", i, i); } else if (!strncasecmp(ptr, "write", 5)) { ptr = index(ptr, '|'); if (!ptr) goto error; ++ptr; img_output = OUT_DUMP; dump_file = strdup(ptr); } else goto error; } else #endif /* ARCINFO */ if (!strpcmp(ptr, "pixmap", 6)) { ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if (!parse_pixmaps(scene, ptr)) goto error; } else if (!strpcmp(ptr, "+memory", 4)) { use_memory = 1; } else if (!strpcmp(ptr, "-memory", 4)) { use_memory = 0; if (fullmap_buffer) { free(fullmap_buffer); fullmap_buffer = NULL; segment_buffer = NULL; } } else if (!runlevel && !strpcmp(ptr, "ppmout", 6)) { img_output = OUT_PPM; } else if (!runlevel && !strpcmp(ptr, "xpmout", 6)) { img_output = OUT_XPM; } else if (!runlevel && !strpcmp(ptr, "epsout", 6)) { img_output = OUT_EPS; } else if (!runlevel && !strpcmp(ptr, "psout", 5)) { img_output = OUT_PS; } else if (!runlevel && !strpcmp(ptr, "rcout", 5)) { img_output = OUT_RC; } else if (!runlevel && !strpcmp(ptr, "preview", 7)) { ptr = (char*) strtok(NULL, sep); if (ptr) preview = atof(ptr); else goto error; if (preview<0.0) goto error; } else if (!strpcmp(ptr, "psviewer", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) { free(ps_viewer); ps_viewer = strdup(ptr); translate_string(ps_viewer); } else goto error; } else if (!strpcmp(ptr, "imviewer", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) { free(im_viewer); im_viewer = strdup(ptr); translate_string(im_viewer); } else goto error; } else if (!strpcmp(ptr, "svgviewer", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) { free(svg_viewer); svg_viewer = strdup(ptr); translate_string(svg_viewer); } else goto error; } else if (!strpcmp(ptr, "svgconvert", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) { free(svg_convert); svg_convert = strdup(ptr); translate_string(svg_convert); } else goto error; } else if (!strpcmp(ptr, "htmlviewer", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) { free(html_viewer); html_viewer = strdup(ptr); translate_string(html_viewer); } else goto error; } else if (!strpcmp(ptr, "printcmd", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) { free(print_cmd); print_cmd = strdup(ptr); translate_string(print_cmd); } else goto error; } else if (!strpcmp(ptr, "editor", 4)) { ptr = (char*) strtok(NULL, sep); if (ptr) { free(editor_cmd); editor_cmd = strdup(ptr); translate_string(editor_cmd); } else goto error; } else if (!strpcmp(ptr, "musicplayer", 5)) { ptr = (char*) strtok(NULL, sep); if (ptr) { free(midi_cmd); midi_cmd = strdup(ptr); translate_string(editor_cmd); } else goto error; } else if (!strpcmp(ptr, "pswidth", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) ps_width = atof(ptr); else goto error; if (ps_width<=0) goto error; } else if (!strpcmp(ptr, "psleftmargin", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) ps_lm = atof(ptr); else goto error; if (ps_lm<0) goto error; } else if (!strpcmp(ptr, "psbottommargin", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) ps_bm = atof(ptr); else goto error; if (ps_bm<0) goto error; } else if (!strpcmp(ptr, "psrotate", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) ps_rot = atoi(ptr); else goto error; if (ps_rot<0) ps_rot = -90; if (ps_rot>0) ps_rot = 90; } else if (!strpcmp(ptr, "pslinewidth", 4)) { ptr = (char*) strtok(NULL, sep); if (ptr) ps_lw = atof(ptr); else goto error; if (ps_lw<=0) goto error; } else if (!strpcmp(ptr, "psframe", 5)) { ps_frame = 1; } else if (!strpcmp(ptr, "psnoframe", 7)) { ps_frame = 0; } else if (!strpcmp(ptr, "pscolor", 3)) { ps_grayscale = 0; } else if (!strpcmp(ptr, "psgrayscale", 3)) { ps_grayscale = 1; } else if (!strpcmp(ptr, "-dms", 3)) { dms = 0; if (runlevel) update_auxil_windows(scene); } else if (!strpcmp(ptr, "+dms", 3)) { dms = 1; if (runlevel) update_auxil_windows(scene); } else if (!strpcmp(ptr, "longitude", 2)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->gopt.yrot = dms2decim(ptr); else goto error; } else if (!strpcmp(ptr, "latitude", 2)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->gopt.xrot = dms2decim(ptr); else goto error; } else if (!strpcmp(ptr, "inclination", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->gopt.zrot = dms2decim(ptr); else goto error; } else if (!strpcmp(ptr, "search", 4)) { ptr = (char*) strtok(NULL, sep); if (ptr) { if (search_string) free(search_string); search_string = strdup(ptr); if (runlevel) { search_city(scene); search_output(scene, 1); } } } else if (!strpcmp(ptr, "field", 4)) { ptr = (char*) strtok(NULL, sep); if (ptr) { if (!strcasecmp(ptr, "name")) search_by = 1; else if (!strcasecmp(ptr, "country")) search_by = 2; else if (!strcasecmp(ptr, "region")) search_by = 3; else if (!strcasecmp(ptr, "list")) search_by = 4; else { search_by = atoi(ptr); if (search_by<1 || search_by>4) goto error; } } else goto error; } else if (!strpcmp(ptr, "reverse", 1)) { reverse = 1 - reverse; if (runlevel) get_all_colors(scene); } else if (!strpcmp(ptr, "resetcolors", 3)) { if (runlevel && color_depth<=8) get_all_colors(scene); } else if (!strpcmp(ptr, "font", 2)) { int num; char *ptr2; ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if (!(ptr2=index(ptr,','))) goto error; *ptr2 = '\0'; num = atoi(ptr); *ptr2 = ','; if (num<0 || num>5) goto error; if (!runlevel || !set_font(ptr2+1, num)) { strncpy(scene->ropt.font[num], ptr2+1, 255); scene->ropt.font[num][255] = '\0'; } else goto error; } else if (!strpcmp(ptr, "width", 1)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->width = atoi(ptr); else goto error; if (scene->width < 16) goto error; } else if (!strpcmp(ptr, "height", 1)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->height = atoi(ptr); else goto error; if (scene->height < 16) goto error; } else if (!strpcmp(ptr, "color", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) set_opt_color(scene, ptr, 0); else goto error; set_bg_fg(scene); } else if (!strpcmp(ptr, "category", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) { if (set_continents(scene, ptr, 0)) goto error; } else goto error; } else if (!strpcmp(ptr, "continent", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) { if (set_continents(scene, ptr, 1)) goto error; } else goto error; } else if (!strpcmp(ptr, "projection", 1)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->projection = set_proj(ptr); else goto error; if (runlevel) show_title(scene, mainwin); } else if (!strpcmp(ptr, "aspect", 1)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->aspect = atof(ptr); else goto error; if (scene->aspect<0.01) goto error; } else if (!strpcmp(ptr, "accuracy", 5)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->accuracy = atof(ptr); else goto error; if (scene->accuracy<=0.0) goto error; } else if (!strpcmp(ptr, "zoom", 1)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->gopt.zoom = atof(ptr); else goto error; if (scene->gopt.zoomgopt.zoom>MAXZOOM) goto error; } else if (!strpcmp(ptr, "coordinates", 4)) { ptr = (char*) strtok(NULL, sep); if (ptr && strlen(ptr)==2) { scene->ropt.latcoord = set_grid_coordinates(ptr[0]); scene->ropt.loncoord = set_grid_coordinates(ptr[1]); } else goto error; } else if (!strpcmp(ptr, "gslat", 4)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->ropt.spacing_lat = dms2decim(ptr); else goto error; check_spacing(scene); } else if (!strpcmp(ptr,"gslon", 4)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->ropt.spacing_lon = dms2decim(ptr); else goto error; check_spacing(scene); } else if (!strpcmp(ptr, "gspacing", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) scene->ropt.spacing_lat = dms2decim(ptr); else goto error; scene->ropt.spacing_lon = scene->ropt.spacing_lat; check_spacing(scene); } else if (!strpcmp(ptr, "lineorder", 5)) { ptr = (char*) strtok(NULL, sep); if (ptr) { strncpy(scene->gopt.lineorder, ptr, 5); scene->gopt.lineorder[5] = '\0'; check_lineorder(scene); } else goto error; } else if (!strpcmp(ptr, "ranking", 4)) { ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; ranking = (int)*ptr; } else if (!strpcmp(ptr, "marksteps", 3)) { int i, j; ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if ((i=sscanf(ptr, "%d,%d,%d,%d,%d", &scene->ropt.mark_step[0], &scene->ropt.mark_step[1], &scene->ropt.mark_step[2], &scene->ropt.mark_step[3], &scene->ropt.mark_step[4]))<5) for (j=i; j<5; j++) scene->ropt.mark_step[j] = scene->ropt.mark_step[i-1]; } else if (!strpcmp(ptr, "namesteps", 3)) { int i, j; ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if ((i=sscanf(ptr, "%d,%d,%d,%d,%d", &scene->ropt.name_step[0], &scene->ropt.name_step[1], &scene->ropt.name_step[2], &scene->ropt.name_step[3], &scene->ropt.name_step[4]))<5) for (j=i; j<5; j++) scene->ropt.name_step[j] = scene->ropt.name_step[i-1]; } else if (!strpcmp(ptr, "airportmarks", 9)) { int i, j; ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if ((i=sscanf(ptr, "%d,%d,%d,%d,%d", &scene->ropt.airport_mark[0], &scene->ropt.airport_mark[1], &scene->ropt.airport_mark[2], &scene->ropt.airport_mark[3], &scene->ropt.airport_mark[4]))<5) for (j=i; j<5; j++) scene->ropt.airport_mark[j] = scene->ropt.airport_mark[i-1]; } else if (!strpcmp(ptr, "airportsizes", 9)) { int i, j; ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if ((i=sscanf(ptr, "%d,%d,%d,%d,%d", &scene->ropt.airport_size[0], &scene->ropt.airport_size[1], &scene->ropt.airport_size[2], &scene->ropt.airport_size[3], &scene->ropt.airport_size[4]))<5) for (j=i; j<5; j++) scene->ropt.airport_size[j] = scene->ropt.airport_size[i-1]; } else if (!strpcmp(ptr, "peakmarks", 7)) { int i, j; ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if ((i=sscanf(ptr, "%d,%d,%d,%d,%d", &scene->ropt.peak_mark[0], &scene->ropt.peak_mark[1], &scene->ropt.peak_mark[2], &scene->ropt.peak_mark[3], &scene->ropt.peak_mark[4]))<5) for (j=i; j<5; j++) scene->ropt.peak_mark[j] = scene->ropt.peak_mark[i-1]; } else if (!strpcmp(ptr, "peaksizes", 7)) { int i, j; ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if ((i=sscanf(ptr, "%d,%d,%d,%d,%d", &scene->ropt.peak_size[0], &scene->ropt.peak_size[1], &scene->ropt.peak_size[2], &scene->ropt.peak_size[3], &scene->ropt.peak_size[4]))<5) for (j=i; j<5; j++) scene->ropt.peak_size[j] = scene->ropt.peak_size[i-1]; } else if (!strpcmp(ptr, "citymarks", 7)) { int i, j; ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if ((i=sscanf(ptr, "%d,%d,%d,%d,%d", &scene->ropt.city_mark[0], &scene->ropt.city_mark[1], &scene->ropt.city_mark[2], &scene->ropt.city_mark[3], &scene->ropt.city_mark[4]))<5) for (j=i; j<5; j++) scene->ropt.city_mark[j] = scene->ropt.city_mark[i-1]; } else if (!strpcmp(ptr, "citysizes", 7)) { int i, j; ptr = (char*) strtok(NULL, sep); if (!ptr) goto error; if ((i=sscanf(ptr, "%d,%d,%d,%d,%d", &scene->ropt.city_size[0], &scene->ropt.city_size[1], &scene->ropt.city_size[2], &scene->ropt.city_size[3], &scene->ropt.city_size[4]))<5) for (j=i; j<5; j++) scene->ropt.city_size[j] = scene->ropt.city_size[i-1]; } else if (!strpcmp(ptr, "cityfilter", 7)) { ptr = (char*) strtok(NULL, sep); if (ptr) load_city_filter(scene, ptr); else goto error; } else if (!strpcmp(ptr, "locfilter", 6)) { ptr = (char*) strtok(NULL, sep); if (ptr) load_loc_filter(scene, ptr); else goto error; } else if (!strpcmp(ptr, "flagtypes", 7)) { ptr = (char*) strtok(NULL, sep); if (ptr) { free(flag_descr); flag_descr = strdup(ptr); if (set_flag_dirs()) { free_flag_data(); list_flag_dirs(); goto error; } } else goto error; } else if (!strpcmp(ptr, "define", 3)) { ptr = (char*) strtok(NULL, sep); if (ptr) parse_define(scene, ptr); else goto error; } else if (!strpcmp(ptr, "undefine", 5)) { ptr = (char*) strtok(NULL, sep); if (ptr) feature_undefine(scene, atoi(ptr)); else goto error; } else if (!strpcmp(ptr, "+placename", 3)) scene->ropt.placetext = 1; else if (!strpcmp(ptr, "-placename", 3)) scene->ropt.placetext = 0; else if (!strpcmp(ptr, "+smartlabels", 5)) scene->ropt.smartlabels = 1; else if (!strpcmp(ptr, "-smartlabels", 5)) scene->ropt.smartlabels = 0; else if (!strpcmp(ptr, "+compress", 5)) im_compress = 1; else if (!strpcmp(ptr, "-compress", 5)) im_compress = 0; else if (!strpcmp(ptr, "-secure", 4)) secure = 0; else if (!strpcmp(ptr, "+secure", 4)) secure = 1; else if (!strpcmp(ptr, "+cities", 3)) { scene->color[C_CITY_CIRCLE].bool = ON; scene->color[C_CITY_TEXT].bool = OFF; } else if (!strpcmp(ptr, "++cities", 4)) { scene->color[C_CITY_CIRCLE].bool = ON; scene->color[C_CITY_TEXT].bool = ON; } else if (!strpcmp(ptr, "-cities", 2)) { scene->color[C_CITY_CIRCLE].bool = OFF; scene->color[C_CITY_TEXT].bool = OFF; } else if (!strpcmp(ptr, "+airports", 4)) { scene->color[C_AIRPORT_SYMBOL].bool = ON; scene->color[C_AIRPORT_TEXT].bool = OFF; } else if (!strpcmp(ptr, "++airports", 5)) { scene->color[C_AIRPORT_SYMBOL].bool = ON; scene->color[C_AIRPORT_TEXT].bool = ON; } else if (!strpcmp(ptr, "-airports", 4)) { scene->color[C_AIRPORT_SYMBOL].bool = OFF; scene->color[C_AIRPORT_TEXT].bool = OFF; } else if (!strpcmp(ptr, "+observatories", 5)) { scene->color[C_OBSERV_SYMBOL].bool = ON; scene->color[C_OBSERV_TEXT].bool = OFF; } else if (!strpcmp(ptr, "++observatories", 6)) { scene->color[C_OBSERV_SYMBOL].bool = ON; scene->color[C_OBSERV_TEXT].bool = ON; } else if (!strpcmp(ptr, "-observatories", 5)) { scene->color[C_OBSERV_SYMBOL].bool = OFF; scene->color[C_OBSERV_TEXT].bool = OFF; } else if (!strpcmp(ptr, "+peaks", 3)) { scene->color[C_PEAK_TRIANGLE].bool = ON; scene->color[C_PEAK_TEXT].bool = OFF; } else if (!strpcmp(ptr, "++peaks", 4)) { scene->color[C_PEAK_TRIANGLE].bool = ON; scene->color[C_PEAK_TEXT].bool = ON; } else if (!strpcmp(ptr, "-peaks", 3)) { scene->color[C_PEAK_TRIANGLE].bool = OFF; scene->color[C_PEAK_TEXT].bool = OFF; } else if (!strpcmp(ptr, "+locations", 2)) { scene->color[C_LOC_LAND].bool = ON; scene->color[C_LOC_WATER].bool = ON; } else if (!strpcmp(ptr, "-locations", 2)) { scene->color[C_LOC_LAND].bool = OFF; scene->color[C_LOC_WATER].bool = OFF; } else if (!strpcmp(ptr, "+earthcontour", 2)) scene->color[C_EARTH_CONTOUR].bool = ON; else if (!strpcmp(ptr, "-earthcontour", 2)) scene->color[C_EARTH_CONTOUR].bool = OFF; else if (!strpcmp(ptr, "+gridlines", 2)) { scene->color[C_LAT_GRID].bool = ON; scene->color[C_LON_GRID].bool = ON; } else if (!strpcmp(ptr, "-gridlines", 2)) { scene->color[C_LAT_GRID].bool = OFF; scene->color[C_LON_GRID].bool = OFF; } else if (!strpcmp(ptr, "+tropics", 5)) scene->color[C_MAIN_LINES].bool = ON; else if (!strpcmp(ptr, "-tropics", 5)) scene->color[C_MAIN_LINES].bool = OFF; else if (!strpcmp(ptr, "+transparency", 5)) scene->gopt.transparent = ON; else if (!strpcmp(ptr, "-transparency", 5)) scene->gopt.transparent = OFF; else { char *errstr; ptr_err = ptr; free(string); error: errstr = (char *)malloc(strlen(ptr_err)+100); sprintf(errstr, msg[INVALID_OPTION], ptr_err); *cmd_string = '\0'; caret_pos = 0; if (runlevel) { draw_win_string(scene, cmdwin, errstr, BOTTOM); usleep(WARNING_TIME); } else fprintf(stderr, "%s\n", errstr); free(errstr); return 1; } } free(string); if (runlevel) { if (scene->width<=0) scene->width = w0; if (scene->height<=0) scene->height = h0; if (scene->width!=w0 || scene->height!=h0) { set_radius(scene); XResizeWindow(dpy, mainwin, scene->width, scene->height); XFlush(dpy); } } return 0; } void update_positions(ImageLayout *scene, int pos) { int i; for (i=0; inum_positions; i++) { if (!memcmp(&scene->position[i], &scene->gopt, 4*sizeof(double))) return; } ++scene->num_positions; i = scene->ind_position = scene->num_positions-1; scene->position = (XYZPosition *)realloc(scene->position, scene->num_positions*sizeof(XYZPosition)); memcpy(&scene->position[i].xrot, &scene->gopt, 4*sizeof(double)); scene->position[i].loc = pos; } void check_datachanges(ImageLayout * scene) { ImageLayout *backup; backup = (ImageLayout *)scene->backup; if (strcmp(scene->rcfile, backup->rcfile)) parse_rcfile(scene); if (strcmp(scene->locfile, backup->locfile)) parse_locfile(scene); if (strcmp(scene->mapfile, backup->mapfile)) free_data_buffers(scene); } /* * SECTION 3 : I/O & FILE ROUTINES */ void close_outfile() { if (out_fd) { #ifdef ZLIB if (im_compress) gzclose((gzFile *)out_fd); else #endif fclose((FILE *)out_fd); } out_fd = NULL; } void open_outfile(ImageLayout * scene) { int i; struct stat buf; char str[256], strgz[256]; char *ptr; if (out_fd) return; if (!*scene->outfile) { close_outfile(); overwrite = -1; return; } i = strlen(scene->outfile)-3; if (strcmp(scene->outfile+i, ".gz")) { sprintf(str,"%s", scene->outfile); sprintf(strgz,"%s.gz", scene->outfile); } else { strcpy(strgz, scene->outfile); strcpy(str, strgz); str[i-3] = '\0'; } if (overwrite==0) { ptr = strdup(str); buf.st_mode = 0; stat(ptr, &buf); free(ptr); if (S_ISREG(buf.st_mode)) overwrite = 1; ptr = strdup(strgz); buf.st_mode = 0; stat(ptr, &buf); free(ptr); if (S_ISREG(buf.st_mode)) overwrite = 1; if (overwrite==1) return; } #ifdef ZLIB if (im_compress) { out_fd = (void *)gzopen(strgz, "wb6"); strcpy(str, strgz); } else #endif out_fd = (void *)fopen(str, "w"); if (!out_fd) { fprintf(stderr, msg[OPENING_FAILED], str); fprintf(stderr, "\n"); } overwrite = -1; } void print_PS_prolog(ImageLayout *scene) { char str[1024]; /* Real bounding box would be 0 0 width height. Take A4 instead */ sprintf(str, "%%!PS-Adobe-2.0 EPSF-2.0\n" "%%%%Creator: xrmap (version %s)\n" "%%%%Title: %s\n" "%%%%Pages: 1\n" "%%%%BoundingBox: 0 0 "PAGEFORMAT"\n" "%%%%EndComments\n" "%%EndProlog\n" "%%Page: 1 1\n", VERSION, (scene->outfile && *scene->outfile)? scene->outfile: "(stdout)"); print_string(str); } void print_PS_scaling(ImageLayout *scene, int mode) { char str[256]; double fact, dx, dy, fx, fy, shift_x, shift_y; *str = '\0'; fact = ps_width*PTPERMM/((double)scene->width); fx = fact*(double)scene->width; fy = fact*(double)scene->height; if (ps_rot) { dx = ps_bm * PTPERMM; dy = ps_lm * PTPERMM; } else { dx = ps_lm * PTPERMM; dy = ps_bm * PTPERMM; } if (ps_rot) { shift_x = fy + dy; shift_y = fx + dx; } else { shift_x = fx + dx; shift_y = fy + dy; } if (mode == 0) fx = fy = fact; print_string("gsave\n"); if (ps_rot>0) { dy = 0.0; sprintf(str, "%.3f 0 translate 90 rotate\n", shift_x); } if (ps_rot<0) { dx = 0.0; sprintf(str, "0 %.3f translate -90 rotate\n", shift_y); } if (*str) print_string(str); sprintf(str, "%.3f %.3f translate\n%.3f %.3f scale\n", dx, dy, fx, fy); print_string(str); if (mode==0) { sprintf(str, "/linewidth %.2f def\n", ps_lw * fact * 1.5); print_string(str); } if (mode==2) { sprintf(str, "%% frame\n%.4f setlinewidth\n" "0 0 moveto 1 0 lineto 1 1 lineto " "0 1 lineto closepath stroke\n", 4.0/(fabs(fx)+fabs(fy))); print_string(str); } } void print_PS_image(ImageLayout *scene, XImage *ximage) { char str[1024]; int i, j, x, y, numcolors, numindex; Pixel p; XColor xc; unsigned char *u=NULL, *v=NULL, *w=NULL; int *ind = NULL; if (color_depth<=8) { ind = (int *)malloc(256*sizeof(int)); memset(ind, 0, 256*sizeof(int)); } else if (color_depth<=16) { ind = (int *)malloc(65536*sizeof(int)); memset(ind, 0, 65536*sizeof(int)); } numcolors = 0; numindex = 256; u = (unsigned char *) malloc(numindex*sizeof(unsigned char)); v = (unsigned char *) malloc(numindex*sizeof(unsigned char)); w = (unsigned char *) malloc(numindex*sizeof(unsigned char)); sprintf(str, "/line %d string def\n" "%d %d 8 [ %d 0 0 %d 0 %d ]\n" "{currentfile line readhexstring pop}\n" "false 3 colorimage\n", 3*ximage->width, ximage->width, ximage->height, ximage->width, -ximage->height, ximage->height); print_string(str); i = 0; j = 0; for (y=0; yheight; y++) for (x=0; xwidth; x++) { p = XGetPixel(ximage, x, y); if (color_depth>=24) { u[i] = p>>16; v[i] = (p>>8)&255; w[i] = p&255; } else { i = ind[p]; if (i==0) { xc.pixel = p; XQueryColor(dpy, cmap, &xc); i = (++numcolors); if (numindex<=numcolors) { numindex += 256; u = (unsigned char *) realloc(u, numindex*sizeof(unsigned char)); v = (unsigned char *) realloc(v, numindex*sizeof(unsigned char)); w = (unsigned char *) realloc(w, numindex*sizeof(unsigned char)); } ind[p] = i; u[i] = xc.red>>8; v[i] = xc.green>>8; w[i] = xc.blue>>8; } } if (ps_grayscale) { unsigned char c = (unsigned char)((50*u[i]+32*v[i]+18*w[i])/100); i = 0; u[i] = v[i] = w[i] = c; } sprintf(str, "%02x%02x%02x", u[i], v[i], w[i]); print_string(str); j += 6; if (j>70 || x==scene->width-1) { j = 0; if (!out_fd) { fputc('\n', stdout); continue; } #ifdef ZLIB if (im_compress) gzputc((gzFile *)out_fd, '\n'); else fputc('\n', (FILE *)out_fd); #else fputc('\n', (FILE *)out_fd); #endif } } if (ind) free(ind); free(u); free(v); free(w); print_string("\n"); } void print_PPM_image(ImageLayout *scene, XImage *ximage) { char str[1024]; int i, x, y, numcolors, numindex; Pixel p; XColor xc; unsigned char *u=NULL, *v=NULL, *w=NULL; int *ind = NULL; if (color_depth<=8) { ind = (int *)malloc(256*sizeof(int)); memset(ind, 0, 256*sizeof(int)); } else if (color_depth<=16) { ind = (int *)malloc(65536*sizeof(int)); memset(ind, 0, 65536*sizeof(int)); } numcolors = 0; numindex = 256; u = (unsigned char *) malloc(numindex*sizeof(unsigned char)); v = (unsigned char *) malloc(numindex*sizeof(unsigned char)); w = (unsigned char *) malloc(numindex*sizeof(unsigned char)); sprintf(str, "P6\n#Creator: xrmap (version %s)\n%d %d\n%d\n", VERSION, scene->width, scene->height, 255); print_string(str); i = 0; for (y=0; yheight; y++) for (x=0; xwidth; x++) { p = XGetPixel(ximage, x, y); if (color_depth>=24) { u[i] = p>>16; v[i] = (p>>8)&255; w[i] = p&255; } else { i = ind[p]; if (i==0) { xc.pixel = p; XQueryColor(dpy, cmap, &xc); i = (++numcolors); if (numindex<=numcolors) { numindex += 256; u = (unsigned char *) realloc(u, numindex*sizeof(unsigned char)); v = (unsigned char *) realloc(v, numindex*sizeof(unsigned char)); w = (unsigned char *) realloc(w, numindex*sizeof(unsigned char)); } ind[p] = i; u[i] = xc.red>>8; v[i] = xc.green>>8; w[i] = xc.blue>>8; } } if (out_fd) { #ifdef ZLIB if (im_compress) { gzputc((gzFile *)out_fd, u[i]); gzputc((gzFile *)out_fd, v[i]); gzputc((gzFile *)out_fd, w[i]); } else { fputc(u[i], (FILE *)out_fd); fputc(v[i], (FILE *)out_fd); fputc(w[i], (FILE *)out_fd); } #else fputc(u[i], (FILE *)out_fd); fputc(v[i], (FILE *)out_fd); fputc(w[i], (FILE *)out_fd); #endif } else { fputc(u[i], stdout); fputc(v[i], stdout); fputc(w[i], stdout); } } if (ind) free(ind); free(u); free(v); free(w); } void print_image(ImageLayout * scene) { char str[1024], lat[40], lon[40]; XImage *ximage; int i, j; ximage = XGetImage(dpy, scene->pixmap, 0, 0, scene->width, scene->height, AllPlanes, ZPixmap); if (img_output==OUT_PPM) print_PPM_image(scene, ximage); if (img_output==OUT_XPM) XpmWriteFileFromImage(dpy, (*scene->outfile)? scene->outfile : NULL, ximage, NULL, NULL); if (img_output==OUT_PS) { print_PS_prolog(scene); print_PS_scaling(scene, 1+ps_frame); print_PS_image(scene, ximage); print_string("%\ngrestore\nshowpage\n%%Trailer\n"); if (runlevel) { #ifdef ZLIB if (im_compress) gzflush((gzFile *)out_fd, Z_FINISH); else #endif fflush((FILE *)out_fd); } } if (img_output==OUT_RC) { int im_compress_save = im_compress; im_compress = 0; print_string(msg[TYPE_ALT_M_FROM_EMX]); print_string("\n\n\n"); for (i=0; icolor[i].bool)? '+':'-'), scene->color[i].name); print_string(str); } print_string("\n\n"); sprintf(str, "-projection %d -zoom %.6f\n", scene->projection, scene->gopt.zoom); print_string(str); sprintf(str, "-width %d -height %d -aspect %.6f -accuracy %.6f\n", scene->width, scene->height, scene->aspect, scene->accuracy); print_string(str); sprintf(str, "-latitude %.6f -longitude %.6f -inclination %.6f\n", scene->gopt.xrot, scene->gopt.yrot, scene->gopt.zrot); print_string(str); strcpy(str, "-category "); j = 10; for (i=1; i<=4; i++) { if (scene->gopt.desired_categories & (1<<(i-1))) { if (j>10) str[j++] = ','; str[j++] = '0'+i; } } str[j++] = '\n'; str[j++] = '\0'; print_string(str); strcpy(str, "-continent "); j = 11; for (i=1; i<=5; i++) { if (scene->gopt.desired_continents & (1<<(i-1))) { if (j>11) str[j++] = ','; str[j++] = '0'+i; } } str[j++] = '\n'; str[j++] = '\0'; print_string(str); if (scene->projection==SPHERICAL && scene->gopt.transparent) print_string("+transparency\n"); if (scene->ropt.smartlabels==0) print_string("-smartlabels\n"); if (scene->ropt.placetext) print_string("+placename\n"); if (im_compress) print_string("+compress\n"); if (secure) print_string("+secure\n"); for (i=0; i<6; i++) { sprintf(str, "-font %d,%s\n", i, scene->ropt.font[i]); print_string(str); } if (datapix) { sprintf(str, "-pixmap data|%s\n", datapix_name); print_string(str); } if (cmdpix) { sprintf(str, "-pixmap cmd|%s\n", cmdpix_name); print_string(str); } for (i=0; i<=2; i++) if (butpix_name[i]) { sprintf(str, "-pixmap button%d|%s\n", i, butpix_name[i]); print_string(str); } sprintf(str, "-gslat %.6f -gslon %.6f\n", scene->ropt.spacing_lat, scene->ropt.spacing_lon); print_string(str); sprintf(str, "-coordinates %c%c\n", get_grid_coordinates(scene->ropt.latcoord, 0), get_grid_coordinates(scene->ropt.loncoord, 1)); print_string(str); sprintf(str, "%cdms\n", (dms)? '+':'-'); print_string(str); sprintf(str, "-lineorder %s\n", scene->gopt.lineorder); print_string(str); sprintf(str, "-marksteps %d,%d,%d,%d,%d\n", scene->ropt.mark_step[0], scene->ropt.mark_step[1], scene->ropt.mark_step[2], scene->ropt.mark_step[3], scene->ropt.mark_step[4]); print_string(str); sprintf(str, "-namesteps %d,%d,%d,%d,%d\n", scene->ropt.name_step[0], scene->ropt.name_step[1], scene->ropt.name_step[2], scene->ropt.name_step[3], scene->ropt.name_step[4]); print_string(str); sprintf(str, "-citymarks %d,%d,%d,%d,%d\n", scene->ropt.city_mark[0], scene->ropt.city_mark[1], scene->ropt.city_mark[2], scene->ropt.city_mark[3], scene->ropt.city_mark[4]); print_string(str); sprintf(str, "-citysizes %d,%d,%d,%d,%d\n", scene->ropt.city_size[0], scene->ropt.city_size[1], scene->ropt.city_size[2], scene->ropt.city_size[3], scene->ropt.city_size[4]); print_string(str); sprintf(str, "-airportmarks %d,%d,%d,%d,%d\n", scene->ropt.airport_mark[0], scene->ropt.airport_mark[1], scene->ropt.airport_mark[2], scene->ropt.airport_mark[3], scene->ropt.airport_mark[4]); print_string(str); sprintf(str, "-airportsizes %d,%d,%d,%d,%d\n", scene->ropt.airport_size[0], scene->ropt.airport_size[1], scene->ropt.airport_size[2], scene->ropt.airport_size[3], scene->ropt.airport_size[4]); print_string(str); sprintf(str, "-peakmarks %d,%d,%d,%d,%d\n", scene->ropt.peak_mark[0], scene->ropt.peak_mark[1], scene->ropt.peak_mark[2], scene->ropt.peak_mark[3], scene->ropt.peak_mark[4]); print_string(str); sprintf(str, "-peaksizes %d,%d,%d,%d,%d\n", scene->ropt.peak_size[0], scene->ropt.peak_size[1], scene->ropt.peak_size[2], scene->ropt.peak_size[3], scene->ropt.peak_size[4]); print_string(str); sprintf(str, "-flagtypes %s\n", flag_descr); print_string(str); sprintf(str, "-cityfilter %s\n", scene->ropt.city_filter); print_string(str); sprintf(str, "-locfilter %s\n", scene->ropt.loc_filter); print_string(str); if (strcmp(scene->locfile, LOCFILE)) { print_string("-locfile DEFAULT\n"); sprintf(str, "-locfile %s\n", scene->locfile); print_string(str); } if (scene->numdef || scene->numpoint) { print_string("\n\n"); for (i=0; inumdef; i++) { print_string(scene->def[i]+1); print_string("\n"); } if (scene->numpoint) { print_string("input"); j = dms; dms = -1; for (i=0; inumpoint; i++) { decim2dms(scene->mempoint[2*i], lat); decim2dms(scene->mempoint[2*i+1], lon); sprintf(str, "|%s,%s", lat, lon); print_string(str); } dms = j; print_string("\n"); } } if (runlevel) fflush((FILE *)out_fd); im_compress = im_compress_save; } XDestroyImage(ximage); close_outfile(); } /* * SECTION 4 : GEODESIC ROUTINES */ static ScreenPt project(ImageLayout * s, Vector a) { Vector v; static ScreenPt iv; Matrix *b; int i; b = &s->rotation; if (s->projection==SPHERICAL) { v.coord[0] = a.coord[0]*b->comp[0] + a.coord[1]*b->comp[3] + a.coord[2]*b->comp[6]; v.coord[1] = a.coord[0]*b->comp[1] + a.coord[1]*b->comp[4] + a.coord[2]*b->comp[7]; v.coord[2] = a.coord[0]*b->comp[2] + a.coord[1]*b->comp[5] + a.coord[2]*b->comp[8]; if (v.coord[2]>=0) visible = 1; else visible = s->gopt.transparent; } else { v.coord[0] = a.coord[0] - b->comp[0]; if (v.coord[0]>s->earth_radius) { i = (int)(v.coord[0]/s->earth_radius); i = (i+1)&(-2); v.coord[0] -= ((double)i)*s->earth_radius; } else if (v.coord[0]<-s->earth_radius) { i = (int)(-v.coord[0]/s->earth_radius); i = (i+1)&(-2); v.coord[0] += ((double)i)*s->earth_radius; } v.coord[0] *= b->comp[2]; v.coord[1] = (a.coord[1] - b->comp[1]) * b->comp[2]; v.coord[2] = a.coord[2] * b->comp[2]; } iv.coord[0] = v.coord[0]+s->shiftx; iv.coord[1] = v.coord[1]+s->shifty; return iv; } void elliptic(double *x) { int sign=0; double t; if (*x<0) { t = -(*x); sign = 1; } else t = *x; if (t>=1.0) return; if (t==0) return; /* with STRETCHING=4/3, this closely imitates the Mollweide projection, while being much simpler to calculate */ *x = 1.0 - exp(STRETCHING*log(1-t)); if (sign) *x = -(*x); } void mollweide(double *x) { int k, sign=0; double d, t; if (*x<0) { t = -(*x); sign = 1; } else t = *x; if (t>=1.0) return; if (t==0) return; d = PI_OVER_2 * sin(PI_OVER_2 * t); if (t<=0.625) *x = PI_SQUARE_OVER_8 * t * (1.0 - 0.09*t); else *x = 1.0 - exp((PI_SQUARE_OVER_8+MOLLWEIDE_COEFF*t)*log(1-t)); k = 0; iter: ++k; t = *x; *x = 0.5 * (t + (d-asin(t))/sqrt(1-t*t)); if (fabs(*x-t)>1E-9 && k<=10) goto iter; if (sign) *x = - (*x); } void operate(ImageLayout * s, double *y) { if (s->projection==CYLINDRICAL) *y = sin(PI_OVER_2 * (*y)); else if (s->projection==MERCATOR) { if (*y>0.0) { if (*y>0.99) *y = 3.10; else *y = TWO_OVER_PI*log(tan(PI_OVER_4*(*y+1.0))); } else { if (*y<-0.99) *y = -3.10; else *y = -TWO_OVER_PI*log(tan(PI_OVER_4*(-*y+1.0))); } } else if (s->projection==MILLER) *y = FIVE_OVER_2PI*log(tan(PI_OVER_4*(0.8*(*y)+1.0))); else if (s->projection==ELLIPTIC) elliptic(y); else if (s->projection==MOLLWEIDE) mollweide(y); } void inverse_operate(ImageLayout * s, double *y) { double d; int sign; if (s->projection==CYLINDRICAL) { if (fabs(*y)>=1.0) return; *y = TWO_OVER_PI * asin(*y); } else if (s->projection==MERCATOR) *y = atan(exp((*y)*PI_OVER_2))/PI_OVER_4-1.0; else if (s->projection==MILLER) *y = 1.25*(atan(exp(*y/FIVE_OVER_2PI))/PI_OVER_4-1.0); else if (s->projection==ELLIPTIC) { if (*y==0) return; if (*y>0) sign = 0; else { *y = -(*y); sign = 1; } if (*y<1) *y = 1.0 - exp(log(1-(*y))/STRETCHING); if (sign) *y = -(*y); } else if (s->projection==MOLLWEIDE) { if (fabs(*y)>=1.0) return; d = 2.0 * asin(*y); *y = asin((d + sin(d))*ONE_OVER_PI)*TWO_OVER_PI; } } static Vector spher2cart(ImageLayout * scene, SpherePt s) { Vector v; double latrad, lonrad, y; if (scene->projection==SPHERICAL) { latrad = s.sph[LATITUDE] * CONV; lonrad = s.sph[LONGITUDE] * CONV; y = scene->earth_radius * cos(latrad); v.coord[X] = y * sin(lonrad); v.coord[Y] = scene->earth_radius * sin(latrad); v.coord[Z] = y * cos(lonrad); return v; } else { y = -s.sph[LATITUDE] / 90.0; if (scene->projection==SINUSOIDAL) { lonrad = cos(PI_OVER_2*y); if (lonrad>0.1) escape_length = (int)(scene->width * lonrad * 0.5); v.coord[X] = s.sph[LONGITUDE] - scene->gopt.yrot ; while (v.coord[X]<-180.0) v.coord[X] += 360.0; while (v.coord[X]>180.0) v.coord[X] -= 360.0; v.coord[X] = v.coord[X]*lonrad + scene->gopt.yrot; while (v.coord[X]<-180.0) v.coord[X] += 360.0; while (v.coord[X]>180.0) v.coord[X] -= 360.0; v.coord[X] *= scene->earth_radius/180.0; } else if (scene->projection>=ELLIPTIC) { operate(scene, &y); lonrad = 1.0-y*y; if (lonrad<0.0) lonrad = 0.0; else lonrad = sqrt(lonrad); if (lonrad>0.1) escape_length = (int)(scene->width * lonrad * 0.5); v.coord[X] = s.sph[LONGITUDE] - scene->gopt.yrot ; while (v.coord[X]<-180.0) v.coord[X]+= 360.0; while (v.coord[X]>180.0) v.coord[X]-= 360.0; v.coord[X] = v.coord[X]*lonrad + scene->gopt.yrot; while (v.coord[X]<-180.0) v.coord[X]+= 360.0; while (v.coord[X]>180.0) v.coord[X]-= 360.0; v.coord[X] *= scene->earth_radius/180.0; } else { operate(scene, &y); v.coord[X] = scene->earth_radius * s.sph[LONGITUDE] / 180.0; } v.coord[Y] = 0.5 * scene->earth_radius * y * scene->aspect ; return v; } } static int inverse_coord(ImageLayout * s, int i, int j, double *x, double *y) { double fact; Vector a, v; Matrix *b; if (i<0 || j<0 || i>=s->width || j>=s->height) return 0; fact = s->earth_radius*s->gopt.zoom; a.coord[X] = ((double)(i-s->width/2))/fact; if (s->projection==SPHERICAL) { a.coord[Y] = ((double)(j-s->height/2))/fact; a.coord[Z] = 1-(a.coord[X])*(a.coord[X])-(a.coord[Y])*(a.coord[Y]); if (a.coord[Z]<0) return 0; a.coord[Z] = sqrt(a.coord[Z]); b = &s->rotation; v.coord[0] = a.coord[0]*b->comp[0] + a.coord[1]*b->comp[1] + a.coord[2]*b->comp[2]; v.coord[1] = a.coord[0]*b->comp[3] + a.coord[1]*b->comp[4] + a.coord[2]*b->comp[5]; v.coord[2] = a.coord[0]*b->comp[6] + a.coord[1]*b->comp[7] + a.coord[2]*b->comp[8]; v.coord[0] /= s->gopt.zoom; v.coord[1] /= s->gopt.zoom; v.coord[2] /= s->gopt.zoom; *x = atan2(v.coord[1], sqrt(v.coord[0]*v.coord[0]+v.coord[2]*v.coord[2])) / CONV; *y = atan2(v.coord[0] , v.coord[2]) / CONV; return 1; } else { a.coord[Y] = 2.0 * (((double)(j-s->height/2))/(fact*s->aspect) + s->rotation.comp[1]/(s->earth_radius * s->aspect) ); if (s->projection==SINUSOIDAL) { fact = cos(PI_OVER_2*a.coord[Y]); if (fabs(a.coord[X])>fact) return 0; *y = a.coord[X]/fact; } else if (s->projection>=ELLIPTIC) { fact = sqrt(1-a.coord[Y]*a.coord[Y]); if (fabs(a.coord[X])>fact) return 0; *y = a.coord[X]/fact; } else { *y = a.coord[X]; if (fabs(*y)>1.0) return 0; } inverse_operate(s, &a.coord[Y]); if (fabs(a.coord[Y])>1.0) return 0; *x = -a.coord[Y] * 90.0; *y = (*y)*180.0 + s->gopt.yrot; while (*y>180.0) *y -= 360.0; while (*y<=-180.0) *y += 360.0; return 1; } } /* static int str2toint(unsigned char *str) { if (str[1]<=127) return (int) (str[1]<<8)|str[0]; else return (int) (0xffff<<16)|(str[1]<<8)|str[0]; } */ static int str3toint(unsigned char *str) { if (str[2]<=127) return (int) (str[2]<<16)|(str[1]<<8)|str[0]; else return (int) (0xff<<24)|(str[2]<<16)|(str[1]<<8)|str[0]; } static int str4toint(unsigned char *str) { return (int) (str[3]<<24)|(str[2]<<16)|(str[1]<<8)|str[0]; } /* This function will generate the proper transformation * matrix (rotation and scaling) and copy the values * to the ImageLayout struct */ void compute_matrix(ImageLayout *s) { double y, cosx, cosy, cosz, sinx, siny, sinz; if (s->projection==SPHERICAL) { /* generate the proper rotation & scale matrix */ cosx = cos(s->gopt.xrot * CONV); cosy = cos(s->gopt.yrot * CONV); cosz = cos(s->gopt.zrot * CONV); sinx = sin(s->gopt.xrot * CONV); siny = sin(s->gopt.yrot * CONV); sinz = sin(s->gopt.zrot * CONV); s->rotation.comp[0] = s->gopt.zoom*(cosy*cosz + sinx*siny*sinz); s->rotation.comp[1] = s->gopt.zoom*(-cosy*sinz + sinx*siny*cosz); s->rotation.comp[2] = s->gopt.zoom*(cosx*siny); s->rotation.comp[3] = s->gopt.zoom*(-cosx*sinz); s->rotation.comp[4] = s->gopt.zoom*(-cosx*cosz); s->rotation.comp[5] = s->gopt.zoom*(sinx); s->rotation.comp[6] = s->gopt.zoom*(-siny*cosz + sinx*cosy*sinz); s->rotation.comp[7] = s->gopt.zoom*(siny*sinz + sinx*cosy*cosz); s->rotation.comp[8] = s->gopt.zoom*(cosx*cosy); } else { s->rotation.comp[0] = s->gopt.yrot * s->earth_radius / 180.0; y = s->gopt.xrot / 90.0; operate(s, &y); s->rotation.comp[1] = - 0.5 * s->earth_radius * y * s->aspect; s->rotation.comp[2] = s->gopt.zoom; } update_positions(s, city_found); } static int segment_in_scene(ImageLayout *s, Segment_index *ind){ SpherePt min, max, mid; ScreenPt pt1, pt2, pt3; min.sph[LONGITUDE] = str3toint(ind->minlong)/3600.0; min.sph[LATITUDE] = str3toint(ind->minlat)/3600.0; max.sph[LONGITUDE] = str3toint(ind->maxlong)/3600.0; max.sph[LATITUDE] = str3toint(ind->maxlat)/3600.0; mid.sph[LONGITUDE] = 0.5 * (min.sph[LONGITUDE] + max.sph[LONGITUDE]); mid.sph[LATITUDE] = 0.5 * (min.sph[LATITUDE] + max.sph[LATITUDE]); pt1 = project(s, spher2cart(s, max)); if (!visible) return NO; pt2 = project(s, spher2cart(s, min)); if (!visible) return NO; pt3 = project(s, spher2cart(s, mid)); if (!visible) return NO; /* Yeah, this is ugly, but my head hurts right now. I've got the flu I'll try to figure it out later */ if ( (pt1.coord[X] >= s->width && pt2.coord[X] >= s->width && pt3.coord[X] >= s->width) || (pt1.coord[Y] >= s->height && pt2.coord[Y] >= s->height && pt3.coord[Y] >= s->height) || (pt1.coord[X] < 0 && pt2.coord[X] < 0 && pt3.coord[X] < 0) || (pt1.coord[Y] < 0 && pt2.coord[Y] < 0 && pt3.coord[Y] < 0) ) { return NO; } /* See if the whole segment can fit into one point, if so, then just draw the point! */ if ( (int)pt1.coord[X] == (int)pt2.coord[X] && (int)pt1.coord[Y] == (int)pt2.coord[Y] ) { return POINT_ONLY; } return YES; } void draw_circles(ImageLayout *s) { int i, j, b; double x, y; SpherePt spt1, spt2; ScreenPt pt1, pt2; char line[80]; double step; /* small step */ double main_circles_lat[5] = { 0.0, 23.435, 66.565 }; int prev_visible; step = sqrt(4.0/(1.0+s->gopt.zoom)); b = (s->projection==SPHERICAL); if (s->color[C_LON_GRID].bool == ON) for (i=0; i<=1; i++) for (x=i*s->ropt.spacing_lon; x<180.001-i*b*(s->ropt.spacing_lon/5); x+=s->ropt.spacing_lon) { j = 0; if (img_output == OUT_EPS) { sprintf(line, "s%d\n", C_LON_GRID); print_string(line); } spt1.sph[LONGITUDE] = (i==0)? x : -x; spt2.sph[LONGITUDE] = spt1.sph[LONGITUDE]; y = -89.999999; while (y<90.0) { if (j==0) { spt1.sph[LATITUDE] = y; pt1 = project(s, spher2cart(s, spt1)); if (visible && abs(pt1.coord[X])<=15000 && abs(pt1.coord[Y])<=15000) ++j; else { y += step; continue; } path_start = 1; } else pt1 = pt2; y += step; if (y>=90.0) spt2.sph[LATITUDE] = 89.999999; else spt2.sph[LATITUDE] = y; prev_visible = visible; pt2 = project(s, spher2cart(s, spt2)); if (visible && abs(pt2.coord[X])<=15000 && abs(pt2.coord[Y])<=15000) { escape_length = LARGE_INTEGER; if (!prev_visible) path_start = 1; draw_segment(s, pt1, pt2, s->color[C_LON_GRID].pix); } } if (img_output == OUT_EPS) print_string("k\n"); } for (i=0; i<=6; i++) for (x=i*s->ropt.spacing_lat; x<90.0-s->ropt.spacing_lat/5 || i>=2; x+=s->ropt.spacing_lat) { Pixel pix; if (i<=1 && s->color[C_LAT_GRID].bool != ON) break; if (i>1 && s->color[C_MAIN_LINES].bool != ON) break; if (i>=2) { x = main_circles_lat[(i-1)>>1]; pix = s->color[C_MAIN_LINES].pix; if (img_output == OUT_EPS) { sprintf(line, "s%d\n", C_MAIN_LINES); print_string(line); } } else { pix = s->color[C_LAT_GRID].pix; if (img_output == OUT_EPS) { sprintf(line, "s%d\n", C_LAT_GRID); print_string(line); } } j = 0; spt1.sph[LATITUDE] = (i&1)? x : -x; spt2.sph[LATITUDE] = spt1.sph[LATITUDE]; y = -180; while (y<180.0) { if (j==0) { spt1.sph[LONGITUDE] = y; pt1 = project(s, spher2cart(s, spt1)); if (visible && abs(pt1.coord[X])<=15000 && abs(pt1.coord[Y])<=15000) ++j; else { y += step; continue; } path_start = 1; } else pt1 = pt2; y += step; if (y>=180.0) spt2.sph[LONGITUDE] = 180.0; else spt2.sph[LONGITUDE] = y; prev_visible = visible; pt2 = project(s, spher2cart(s, spt2)); if (visible && abs(pt2.coord[X])<=15000 && abs(pt2.coord[Y])<=15000) { escape_length = LARGE_INTEGER; if (!prev_visible) path_start = 1; draw_segment(s, pt1, pt2, pix); } } if (img_output == OUT_EPS) print_string("k\n"); if (i>=2) break; } if (s->color[C_EARTH_CONTOUR].bool == ON && s->projection==SPHERICAL) { y = s->earth_radius * s->gopt.zoom; pt2.coord[X] = (int)(y+s->shiftx); pt2.coord[Y] = (int)(s->shifty); path_start = 1; if (img_output == OUT_EPS) { sprintf(line, "s%d\n", C_EARTH_CONTOUR); print_string(line); } for (x=step; x<360.1-step; x+=step) { pt1 = pt2; pt2.coord[X] = (int) (y * cos(x*CONV)+s->shiftx); pt2.coord[Y] = (int) (y * sin(x*CONV)+s->shifty); draw_segment(s, pt1, pt2, s->color[C_EARTH_CONTOUR].pix); } if (img_output == OUT_EPS) print_string("k\n"); } } void draw_circle_coordinates(ImageLayout *scene) { int i, ip, j, k, kold, l, vshift, hshift, step, fontnum, text_w; double x, y; char number[30], text[256], format[20]; if (scene->color[C_LAT_GRID].bool == OFF && scene->color[C_LON_GRID].bool == OFF) return; if (scene->ropt.latcoord == 0 && scene->ropt.loncoord == 0) return; fontnum = 5; XSetForeground(dpy, gc, scene->color[C_LAT_GRID].pix); XSetFont(dpy, gc, xfont[fontnum]->fid); vshift = xfont[fontnum]->max_bounds.descent + 3; hshift = 4; step = 0; k = 0; if (scene->ropt.latcoord == 1) i = ip = 3; else i = ip = scene->width - 3; if (scene->ropt.spacing_lat>=1.0) strcpy(format, "%.0f°"); else if (scene->ropt.spacing_lat>=0.1) strcpy(format, "%.1f°"); else strcpy(format, "%.2f°"); if (scene->color[C_LAT_GRID].bool == ON && scene->ropt.latcoord) for (j=0; jheight - vshift; j++) { if (inverse_coord(scene, i, j+vshift, &x, &y)) { kold = k; if (x>=0) k = (int) (x/scene->ropt.spacing_lat); else k = -(int) (-x/scene->ropt.spacing_lat)-1; ++step; if (step==1) { if (img_output == OUT_EPS) { sprintf(text, "f%d c%d\n", fontnum, C_LAT_GRID); print_string(text); } continue; } if (k==kold) continue; if (k>kold) l = k; else l = kold; sprintf(number, format, l*scene->ropt.spacing_lat); text_w = XTextWidth(xfont[fontnum], number, strlen(number)); if (i>3) { ip = scene->width - text_w - 3; } if (scene->ropt.smartlabels) PixmapDrawString(scene, ip, j, text_w, fonth[fontnum], number, strlen(number)); else { XDrawString(dpy, scene->pixmap, gc, ip, j, number, strlen(number)); text_drawn = 1; } if (img_output == OUT_EPS && text_drawn) { sprintf(text, "%d %d m (%s) %d %d %d %d SS\n", ip, scene->height - j - 1, number, 0, 0, 0, 0); print_string(text); } } } k = 0; step = 0; if (scene->ropt.loncoord == 1) j = fontasc[fontnum]+1; else j = scene->height - xfont[fontnum]->max_bounds.descent - 3; if (scene->ropt.spacing_lon>=1.0) strcpy(format, "%.0f°"); else if (scene->ropt.spacing_lon>=0.1) strcpy(format, "%.1f°"); else strcpy(format, "%.2f°"); if (scene->color[C_LON_GRID].bool == ON && scene->ropt.loncoord) for (i=0; iwidth - hshift; i++) { if (inverse_coord(scene, i-hshift, j, &x, &y)) { kold = k; if (y>=0) k = (int) (y/scene->ropt.spacing_lon); else k = -(int) (-y/scene->ropt.spacing_lon)-1; ++step; if (step==1) { if (img_output == OUT_EPS) { sprintf(text, "f%d c%d\n", fontnum, C_LON_GRID); print_string(text); } continue; } if (k==kold) continue; if (k>kold) l = k; else l = kold; sprintf(number, format, l*scene->ropt.spacing_lon); if (scene->ropt.smartlabels) { text_w = XTextWidth(xfont[fontnum], number, strlen(number)); PixmapDrawString(scene, i, j, text_w, fonth[fontnum], number, strlen(number)); } else { XDrawString(dpy, scene->pixmap, gc, i, j, number, strlen(number)); text_drawn = 1; } if (img_output == OUT_EPS && text_drawn) { sprintf(text, "%d %d m (%s) %d %d %d %d SS\n", i, scene->height - j - 1, number, 1, 0, 0, 0); print_string(text); } } } } int size_of_object(ImageLayout *s, int *sizes, int n) { int i; for (i=0; i<5; i++) if (n>=sizes[i]) return i; return -1; } void draw_location(ImageLayout *s, Location * loc) { ScreenPt pt; SpherePt spt; int i, j, space=0, u, x, y, pos=0, ind=0, size=0, colmark=0, coltext=0; int boolmark=0, booltext=0; Pixel pix = black; unsigned short * bits; char name[128], line[256]; char *ptr = NULL, *seatype = NULL; if (loc->draw & OBJ_HIDE) return; i = loc->tz; if (i<0) return; if (loc->obj=='l') { i = 0x00000001<<(i-1); if (!(s->gopt.desired_continents & i)) return; seatype = index("BKOSTV", loc->status); if (s->color[C_LOC_LAND].bool!=ON && !seatype) return; if (s->color[C_LOC_WATER].bool!=ON && seatype) return; booltext = 1; goto projpoint; } else { i = 0x00000001<continent; if (!(s->gopt.desired_continents & i)) return; } if (loc->obj=='c') { if (!index(s->ropt.city_filter, loc->status)) return; size = size_of_object(s, s->ropt.city_size, loc->population); ind = s->ropt.city_mark[size]-1; if (ind<0) return; if (!(loc->draw & OBJ_SHOW) && s->ropt.mark_step[size] > (int)(2*s->gopt.zoom*s->earth_radius)) return; boolmark = s->color[C_CITY_CIRCLE].bool; booltext = s->color[C_CITY_TEXT].bool; colmark = C_CITY_CIRCLE; coltext = C_CITY_TEXT; } else if (loc->obj=='a') { size = size_of_object(s, s->ropt.airport_size, loc->population); ind = s->ropt.airport_mark[size]+4; if (ind<=4) return; if (!(loc->draw & OBJ_SHOW) && s->ropt.mark_step[size] > (int)(2*s->gopt.zoom*s->earth_radius)) return; boolmark = s->color[C_AIRPORT_SYMBOL].bool; booltext = s->color[C_AIRPORT_TEXT].bool; colmark = C_AIRPORT_SYMBOL; coltext = C_AIRPORT_TEXT; } else if (loc->obj=='p') { size = size_of_object(s, s->ropt.peak_size, loc->alt); ind = s->ropt.peak_mark[size]+9; if (ind<=9) return; if (!(loc->draw & OBJ_SHOW) && s->ropt.mark_step[size] > (int)(2*s->gopt.zoom*s->earth_radius)) return; boolmark = s->color[C_PEAK_TRIANGLE].bool; booltext = s->color[C_PEAK_TEXT].bool; colmark = C_PEAK_TRIANGLE; coltext = C_PEAK_TEXT; } else if (loc->obj=='b') { boolmark = s->color[C_OBSERV_SYMBOL].bool; booltext = s->color[C_OBSERV_TEXT].bool; colmark = C_OBSERV_SYMBOL; coltext = C_OBSERV_TEXT; ind = 15; } if (!boolmark && !booltext) return; /* calculate the point projection and check visibility */ projpoint: spt.sph[LONGITUDE] = loc->lon; spt.sph[LATITUDE] = loc->lat; pt = project(s, spher2cart(s, spt)); if (!visible) return; /* verify that the point is on the map, return if not */ if (pt.coord[X] > s->width || pt.coord[X] < 0 || pt.coord[Y] > s->height || pt.coord[Y] < 0) return; /* draw a mark around the point in question if it's not just a location name and boolmark is set */ if (boolmark) { bits = spot_bits[ind]; space = bits[0]/2; pix = s->color[colmark].pix; x = (int)pt.coord[X]; y = (int)pt.coord[Y]; if (img_output == OUT_EPS) { sprintf(line, "c%d %.2f %.2f m o%c%d\n", colmark, pt.coord[X], s->height-1-pt.coord[Y], loc->obj, size); print_string(line); } for (j=0; j= s->height) break; u = bits[j+1]; for (i=0; i>1; } } loc->draw |= SPOT_DRAWN; } if (!booltext) return; /* determine the text position depending whether it's a location name or a label near a mark */ if (loc->obj=='l') { ind = loc->population; pos = loc->alt; strcpy(name, loc->name); if (!ind) return; if (!index(s->ropt.loc_filter, loc->status)) return; if (!(loc->draw & OBJ_SHOW) && s->ropt.name_step[ind-1] > (int)(2*s->gopt.zoom*s->earth_radius)) return; if (seatype) coltext = C_LOC_WATER; else coltext = C_LOC_LAND; } else { ind = size; /* write also names of smaller capital cities... */ if (loc->status!= 'C' && !(loc->draw & OBJ_SHOW) && s->ropt.name_step[size] > (int)(2*s->gopt.zoom*s->earth_radius)) return; if ((ptr=index(loc->name,'('))) { strcpy(name, ptr+1); ptr = index(name,')'); if (ptr) *ptr = '\0'; } else strcpy(name, loc->name); ptr = name; if (s->ropt.placetext) { if (pt.coord[X] > s->width/2) pos = 4; else pos = 0; if (pt.coord[Y] < s->height/16) { if (pos==0) pos = 7; else pos = 5; } if (pt.coord[Y] > 15*s->height/16) { if (pos==0) pos = 1; else pos = 3; } } } /* add text, taking possibly into account user defined modification */ if ((i=(loc->draw & 0x0fffffff))) { i = 2*(i-1); pt.coord[X] += (double) s->modpos[i]; pt.coord[Y] += (double) s->modpos[i+1]; } draw_string(s, &pt, name, ind, pos, space, coltext); if (text_drawn) loc->draw |= TEXT_DRAWN; } void draw_feature(ImageLayout *scene, char * cmd) { int i, j, n, h; SpherePt spt; ScreenPt pt; char name[256]; char line[256]; char lat[256]; char lon[256]; char height[256]; char *str = NULL, *ptr; /* first char of cmd string is feature type; skip it */ ++cmd; if (!strncmp(cmd, "image|", 6)) { XImage *image = NULL; str = strdup(cmd+6); if ((ptr=index(str, ','))) { *ptr = ' '; ++ptr; if ((ptr=index(ptr, '|'))) *ptr = ' '; ++ptr; if ((ptr=index(ptr, '|'))) *ptr = ' '; } n = sscanf(str, "%s %s %s %s", lat, lon, name, height); spt.sph[LATITUDE] = dms2decim(lat); spt.sph[LONGITUDE] = dms2decim(lon); if (n>=3) { if (n==4) h=atoi(height); else h = 32; /* why not ? */ j = -1; for (i=0; icolor[C_BG_MAP]); if (image != NULL) { pt = project(scene, spher2cart(scene, spt)); XPutImage(dpy, scene->pixmap, gc, image, 0, 0, pt.coord[X]-image->width/2, pt.coord[Y]-image->height/2, image->width, image->height); if (img_output == OUT_EPS) { print_string("gsave\n"); sprintf(line, "%.2f %.2f translate\n%d %d scale", pt.coord[X]-image->width/2, scene->height-1-pt.coord[Y]-image->height/2, image->width, image->height); print_string(line); print_PS_image(scene, image); print_string("grestore\n"); } XDestroyImage(image); } } free(str); } if (!strncmp(cmd, "color|", 6)) { XColor color, exact; if (XAllocNamedColor(dpy, cmap, cmd+6, &color, &exact)==(Status)1) { scene->currentpixel = color.pixel; scene->red_current = color.red; scene->green_current = color.green; scene->blue_current = color.blue; } else { scene->currentpixel = (reverse)?white:black; scene->red_current = (reverse)?65535:0; scene->green_current = scene->red_current; scene->blue_current = scene->red_current; } if (img_output == OUT_EPS) { sprintf(line, "%.4f %.4f %.4f RGB\n", scene->red_current/65535.0, scene->green_current/65535.0, scene->blue_current/65535.0); print_string(line); } } if (!strncmp(cmd, "font|", 5)) { i = atoi(cmd+5); if (i<0) i=0; if (i>=5) i=5; scene->currentfont = i; if (img_output == OUT_EPS) { sprintf(line, "f%d\n", scene->currentfont); print_string(line); } } if (!strncmp(cmd, "label|", 6)) { int pos; str = strdup(cmd+6); if ((ptr=index(str, '|'))) { *ptr = ' '; ++ptr; if ((ptr=index(ptr, ','))) { *ptr = ' '; ++ptr; if ((ptr=index(ptr, '|'))) *ptr = ' '; } } n = sscanf(str, "%d %s %s %s", &pos, lat, lon, name); if (n==4) { spt.sph[LATITUDE] = dms2decim(lat); spt.sph[LONGITUDE] = dms2decim(lon); for (i=0; icurrentfont, pos, 0, -1); } } if (!strncmp(cmd, "ellipse|", 8)) { int rx, ry; str = strdup(cmd+8); if ((ptr=index(str, ','))) { *ptr = ' '; ++ptr; if ((ptr=index(ptr, '|'))) { *ptr = ' '; ++ptr; if ((ptr=index(ptr, ','))) *ptr = ' '; } } n = sscanf(str, "%d %d %s %s", &rx, &ry, lat, lon); spt.sph[LATITUDE] = dms2decim(lat); spt.sph[LONGITUDE] = dms2decim(lon); if (str) free(str); if (n==4) { pt = project(scene, spher2cart(scene, spt)); XSetForeground(dpy, gc, scene->currentpixel); XFillArc(dpy, scene->pixmap, gc, pt.coord[X]-rx/2, pt.coord[Y]-ry/2, (unsigned) rx, (unsigned) ry, 0, 360*64); if (img_output == OUT_EPS) { sprintf(line, "%.2f %.2f %d %d ellipse fill\n", pt.coord[X]-rx/2, pt.coord[Y]-ry/2, (unsigned) rx, (unsigned) ry); print_string(line); } } } if (!strncmp(cmd, "polyline|", 9) || !strncmp(cmd, "polygon|", 8) || !strncmp(cmd, "region|", 7)) { char *strp; int done, fill, npoints=0; XPoint *points = NULL; if (*cmd=='r') { str = strdup(cmd+7); fill = 2; } else if (cmd[4]=='g') { str = strdup(cmd+8); fill = 1; } else { str = strdup(cmd+9); fill = 0; } XSetForeground(dpy, gc, scene->currentpixel); strp = (char *)strtok(str, ","); done = 0; if (strp) { spt.sph[LATITUDE] = dms2decim(strp); strp = strtok(NULL, "|"); if (strp) { spt.sph[LONGITUDE] = dms2decim(strp); pt = project(scene, spher2cart(scene, spt)); done = 1; points = (XPoint*) malloc(sizeof(XPoint)); points[0].x = double2short(pt.coord[X]); points[0].y = double2short(pt.coord[Y]); npoints = 1; } } while (done) { done = 0; strp = strtok(NULL, ","); if (strp) { spt.sph[LATITUDE] = dms2decim(strp); strp = strtok(NULL, "|"); if (strp) { spt.sph[LONGITUDE] = dms2decim(strp); pt = project(scene, spher2cart(scene, spt)); done = 1; points = (XPoint*) realloc(points, (npoints+2)*sizeof(XPoint)); points[npoints].x = double2short(pt.coord[X]); points[npoints].y = double2short(pt.coord[Y]); ++npoints; } } } if (fill==1) { points[npoints] = points[0]; ++npoints; } if (fill==2) XFillPolygon(dpy, scene->pixmap, gc, points, npoints, Complex, CoordModeOrigin); else XDrawLines(dpy, scene->pixmap, gc, points, npoints, CoordModeOrigin); if (img_output == OUT_EPS) { sprintf(line, "%d %d m\n", points[0].x, scene->height-1-points[0].y); print_string(line); for (i=1; iheight-1-points[i].y); print_string(line); } if (fill==2) print_string("fill\n"); else print_string("stroke\n"); } if (str) free(str); if (points) free(points); } if (!strncmp(cmd, "modif|", 6)) { int mode, dx, dy; str = strdup(cmd+6); if (search_string) free(search_string); mode = -1; if (!strncmp(str, "hide", 4)) { mode = 0; search_string = strdup(str+5); } else if (!strncmp(str, "show", 4)) { mode = 1; search_string = strdup(str+5); } else if (!strncmp(str, "position", 8)) { mode = 2; search_string = strdup(str+9); if (sscanf(str+9, "%d|%s", &dx, search_string)<2) mode = -1; } else if (!strncmp(str, "move", 4)) { mode = 3; search_string = strdup(str+5); if (sscanf(str+5, "%d,%d|%s", &dx, &dy, search_string)<3) mode = -1; } if (str) free(str); for (i=0; i=0) search_city(scene); else num_found = 0; if (num_found==1) { i = loc_pointer[0]; if (mode==0) { locations[i]->draw |= OBJ_HIDE; locations[i]->draw &= ~OBJ_SHOW; } if (mode>=1) { locations[i]->draw &= ~OBJ_HIDE; locations[i]->draw |= OBJ_SHOW; } if (mode==2) { locations[i]->alt = (char)dx; } else if (mode==3) { int j = 2*scene->nummod; ++scene->nummod; locations[i]->draw &= 0xf0000000; locations[i]->draw |= scene->nummod; scene->modpos = (int*) realloc(scene->modpos, 2*scene->nummod*sizeof(int)); scene->modpos[j] = dx; scene->modpos[j+1] = -dy; } } } } void set_sky(ImageLayout *scene, int c) { int i, j, i1_0=0, i2_0=0, i1, i2, j1=0, j2=0, k, l, pixelset = 0; Pixel bg, sky, star; /* pixels for bigger stars */ int dx[5] = { 0, 0, 0, 1, -1}; int dy[5] = { 0, 1, -1, 0, 0}; double R, R2=0, val, y; char line[256]; bg = scene->color[C_BG_MAP].pix; if (scene->color[C_BG_SKY].bool) { sky = scene->color[C_BG_SKY].pix; if (scene->color[C_FG_STARS].bool) star = scene->color[C_FG_STARS].pix; else star = sky; } else star = sky = bg; R = scene->earth_radius*scene->gopt.zoom; i = round2int(R); if (scene->projection==SPHERICAL) { j = i; j1 = scene->height/2 - j; j2 = scene->height/2 + j; R2 = R*R; } else { i1_0 = scene->width/2 - i; i2_0 = scene->width/2 + i; if (scene->projection==RECTANGULAR || scene->projection==SINUSOIDAL || scene->projection>=ELLIPTIC) { y = scene->gopt.xrot/90.0; operate(scene, &y); y *= 0.5; j1 = scene->height/2-(int)(R*scene->aspect*(0.5-y)); j2 = scene->height/2+(int)(R*scene->aspect*(0.5+y)); } else if (scene->projection==CYLINDRICAL) { y = 0.5*sin(scene->gopt.xrot * CONV); j1 = scene->height/2-(int)(R*scene->aspect*(0.5-y)); j2 = scene->height/2+(int)(R*scene->aspect*(0.5+y)); } else if (scene->projection==MERCATOR) { j1 = 0; j2 = scene->height-1; } else if (scene->projection==MILLER) { y = scene->gopt.xrot/90.0; operate(scene, &y); y *= 0.5; j1 = scene->height/2 - (int)(R*scene->aspect*(MAX_MILLER-y)); j2 = scene->height/2 + (int)(R*scene->aspect*(MAX_MILLER+y)); } } for (j=0; jheight; j++) { if (jj2) i1 = i2 = scene->width; else { if (scene->projection==SPHERICAL) { i = j - scene->height/2; val = R2 - ((double)i*(double)i); if (val<=0) val = 0.0; else val = sqrt(val); i = round2int(val); i1 = scene->width/2 - i; i2 = scene->width/2 + i; } else if (scene->projection==SINUSOIDAL) { k = j-scene->height/2-(int)(R*scene->aspect*y); k = (int)(R*cos((M_PI*k)/(R*scene->aspect))); i1 = scene->width/2 - k; i2 = scene->width/2 + k; } else if (scene->projection>=ELLIPTIC) { k = j-scene->height/2-(int)(R*scene->aspect*y); val = (2.0*(double)k)/(R*scene->aspect); val = 1-val*val; if (val<=0) val = 0; else val = sqrt(val); k = round2int(R*val); i1 = scene->width/2 - k; i2 = scene->width/2 + k; } else { i1 = i1_0; i2 = i2_0; } } for (i=0; iwidth; i++) { if (i>=i1 && ii2+2) && (i*i+j)%971 == (j*j*j+i)%593 + c) { pixelset = 1; if (((9*i+j*j)%7) == 0) l=4; else l=0; for (k=0; k<=l; k++) draw_pixel(scene, i+dx[k], j+dy[k], star); } else draw_pixel(scene, i, j, sky); } } } if (img_output == OUT_EPS) { /* initialize */ if (!pixelset) print_string("/draw_sky false def\n"); sprintf(line, "draw_sky { c%d 0 0 m %d 0 l %d %d l 0 %d l 0 0 l fill\n" " c%d %d %d %d stars } if\n", C_BG_SKY, scene->width, scene->width, scene->height, scene->height, C_FG_STARS, c, scene->width, scene->height); print_string(line); /* fill according to projection */ if (scene->projection==SPHERICAL) sprintf(line, "draw_sky { c%d %.2f %.2f %.2f 0 360 arc fill } if\n", C_BG_MAP, 0.5*scene->width, 0.5*scene->height, R); else if (scene->projection>=RECTANGULAR && scene->projection<=MILLER) sprintf(line, "draw_sky { c%d %d %d m %d %d l %d %d l %d %d l clp fill } if\n", C_BG_MAP, i1_0, scene->height-1-j1, i2_0, scene->height-1-j1, i2_0, scene->height-1-j2, i1_0, scene->height-1-j2); else if (scene->projection>=SINUSOIDAL) sprintf(line, "draw_sky { gsave c%d %.2f %.2f translate\n" " 1 %.4f scale 0 0 %.2f %s fill\n" " grestore } if\n", C_BG_MAP, 0.5*(i1_0+i2_0), scene->height-1-0.5*(j1+j2), 0.5*scene->aspect, R, (scene->projection==SINUSOIDAL)? "sinusoidal" : "0 360 arc fill"); print_string(line); /* set PS rectangle clip */ sprintf(line, "0 0 m %d 0 l %d %d l 0 %d l 0 0 l clip newpath\n" "2 slj\n\n", scene->width, scene->width, scene->height, scene->height); print_string(line); } } void initialize_EPS(ImageLayout * scene, int c) { FILE *fini; char line[256]; int i; double lw; open_outfile(scene); print_PS_prolog(scene); print_string("gsave\n"); fini = fopen(SHAREDIR"/postscript/macros.ps", "r"); if (fini) { while (fgets(line, 254, fini)) print_string(line); fclose(fini); } print_string("\n"); print_PS_scaling(scene, 0); print_string("% Set frame linewidth and color here\n"); sprintf(line, "/frame_style { 0 slj 1 lw c%d } def\n", C_BG_SKY); print_string(line); sprintf(line, "%s %s %s\n", "/draw_frame", (ps_frame)?"true":"false", "def"); print_string(line); print_string("/draw_sky true def\n"); print_string("\n%% font sizes and types\n"); for (i=0; i<=5; i++) { sprintf(line, "/fs%d %d def /f%d {fs%d /Times-Roman-ISO fontdef} def\n", i, 12-i, i, i); print_string(line); } print_string("\n%% colors\n"); for (i=0; icolor[i].r/65535.0, scene->color[i].g/65535.0, scene->color[i].b/65535.0); print_string(line); } print_string( "\n%% line styles (color, linewidth, dash style)\n"); for (i=0; i=3 && i<=5) lw = 0.6; if (i==16) lw = 1.0; sprintf(line, "/s%d {c%d %.2f clw [] 0 ds} def\n", i, i, lw); print_string(line); } print_string("\n"); if (*scene->macrofile) { fini = fopen(scene->macrofile, "r"); if (fini) { while (fgets(line, 254, fini)) print_string(line); fclose(fini); } } } int essential_change(ImageLayout *scene1, ImageLayout *scene2) { return memcmp(scene1, scene2, 3*sizeof(int)+5*sizeof(double)+sizeof(Matrix) +sizeof(GeomOptions)) || memcmp(scene1->color, scene2->color, C_MAIN_LINES*sizeof(Colordata)); } #ifdef ARCINFO void fpr3(FILE * f, int n) { fprintf(f, "%c%c%c", n&255, (n>>8)&255, (n>>16)&255); } void fpr4(FILE * f, int n) { fprintf(f, "%c%c%c%c", n&255, (n>>8)&255, (n>>16)&255, n>>24); } void spr3(char * st, int n) { st[0] = n&255; st[1] = (n>>8)&255; st[2] = (n>>16)&255; } void spr4(char * st, int n) { st[0] = n&255; st[1] = (n>>8)&255; st[2] = (n>>16)&255; st[3] = n>>24; } int check_cat_and_cont(ImageLayout *scene, int u) { int i, k; i = u/28; /* number of continent */ if ( !((1<gopt.desired_continents) ) return 0; /* type of item, INT=0, NAT=1, RIV=2 or CIL=3 */ i = u%28; if (!scene->color[i].bool) return 0; if (i <= 2) k = 0; else if (i <= 4) k = 1; else if (i <= 15) k = 2; else k = 3; if ( !((1<gopt.desired_categories) ) return 0; return 1; } void arcinfo_lines(ImageLayout *scene) { void *fd; char buf[512]; char sep; char *ptr; char **seg; double a, b, c, d; int i, j, k, u, n, p, i0; int new_arc=0, ind, indpr, num_mod = -1, nstrokes, xi, yi; SpherePt sp; ScreenPt pt1, pt2; Pixel pix; double cotan_lat0, conv_lat0; void next_segment(double x, double y) { double u, v, w, t; int i, j, dx, dy, dxp, dyp, epsx, epsy; if (arc_lambert) { /* Inverse Lambert projection */ u = x * arc_scale; v = y * arc_scale - arc_transl; w = atan(u/(-v)); t = v/cos(w); x = arc_lon0 + conv_lat0 * w; y = atan(cotan_lat0 + t)/CONV + arc_lat0; } sp.sph[LONGITUDE] = x; sp.sph[LATITUDE] = y; if (arc_start==1 && fabs(x-arc_x)+fabs(y-arc_y)<0.05) arc_start = 2; if (arc_start==3) printf("%.6f %.6f\n", x, y); pt2 = project(scene, spher2cart(scene, sp)); split_arc: if (new_arc) { if (num_mod!= -1) { i = (++arc_numseg[num_mod]); arc_index[num_mod] = (char **) realloc(arc_index[num_mod], i * sizeof(char *)); nstrokes = 0; seg = (char **)&arc_index[num_mod][i-1]; *seg = (char *) malloc(10); spr4(*seg, nstrokes); xi = round2int(3600.0 * x); yi = round2int(3600.0 * y); spr3(*seg+4, xi); spr3(*seg+7, yi); } else seg = NULL; path_start = 1; pt1 = pt2; new_arc = 0; } else { if (visible && abs(pt2.coord[X])<=15000 && abs(pt2.coord[Y])<=15000) { escape_length = LARGE_INTEGER; if (arc_start==3) draw_segment(scene, pt1, pt2, scene->color[C_FG_TICKS].pix); else draw_segment(scene, pt1, pt2, scene->color[C_LON_GRID].pix); } if (path_start) { new_arc = 1; goto split_arc; } pt1 = pt2; if (seg) { dx = xi; dy = yi; xi = round2int(3600.0 * x); yi = round2int(3600.0 * y); dx = xi - dx; dy = yi - dy; if (dx || dy) { if (dx<0) { epsx = -1; dx = -dx; } else epsx = 1; if (dy<0) { epsy = -1; dy = -dy; } else epsy = 1; dxp = (dx+126)/127; dyp = (dy+126)/127; if (dxp>dyp) n = dxp; else n = dyp; nstrokes += n; *seg = (char *)realloc(*seg, 10+2*nstrokes); spr4(*seg, nstrokes); for (j=0; jcolor[u%28].pix; redraw: ptr = arc_index[u][i]; nstrokes = str4toint(ptr); xi = str3toint(ptr+4); yi = str3toint(ptr+7); sp.sph[LONGITUDE] = ((double)xi)/3600.00; sp.sph[LATITUDE] = ((double)yi)/3600.00; pt2 = project(scene, spher2cart(scene, sp)); for (j=0; jcolor[C_FG_TICKS].pix; fprintf(stderr, "section %d, arc # %d\n", u, i); i0 = i; goto redraw; } } pt2 = project(scene, spher2cart(scene, sp)); draw_segment(scene, pt1, pt2, pix); } } } } return; } pix = scene->color[C_FG_TICKS].pix; #ifdef ZLIB fd = (void *) gzopen(arc_file, "r"); #else fd = (void *) fopen(arc_file, "r"); #endif if (!fd) return; arc_numseg = (int *)malloc(140*sizeof(int)); bzero(arc_numseg, 140*sizeof(int)); arc_index = (char ***)malloc(140*sizeof(char **)); bzero(arc_index, 140*sizeof(char **)); if (arc_lambert) { cotan_lat0 = tan((90.0-arc_lat0) * PI / 180.0); conv_lat0 = 180.0/(PI * sin(arc_lat0 * PI / 180.0)); } ind = 0; #ifdef ZLIB while ((ptr=gzgets((gzFile *)fd, buf, 510))) { #else while ((ptr=fgets(buf, 510, (FILE *)fd))) { #endif ind = ind + strlen(ptr); if (!strncasecmp(ptr, "arc", 3)) break; } indpr = ind; #ifdef ZLIB while ((ptr=gzgets((gzFile *)fd, buf, 510))) { #else while ((ptr=fgets(buf, 510, (FILE *)fd))) { #endif ind = ind+strlen(ptr); if (*ptr == '%') continue; if (!strncasecmp(ptr, "typ =", 5)) { num_mod = atoi(ptr+5); if (num_mod<0 || num_mod>=140) num_mod = -1; if (num_mod == -1) pix = scene->color[C_FG_TICKS].pix; else pix = scene->color[num_mod%28].pix; continue; } if (arc_start == 2) { #ifdef ZLIB gzseek((gzFile *)fd, indpr, SEEK_SET); #else fseek((FILE *)fd, indpr, SEEK_SET); #endif ind = indpr; printf("new = %d\n", ind); #ifdef ZLIB ptr = gzgets((gzFile *)fd, buf, 510); #else ptr = fgets(buf, 510, (FILE *)fd); #endif ind = ind + strlen(ptr); arc_start = 3; new_arc = 1; } if (!strncmp(ptr, " ", 5) || !strncasecmp(ptr, "new =", 5)) { new_arc = 1; if (num_mod == -1) pix = scene->color[C_FG_TICKS].pix; else pix = scene->color[num_mod%28].pix; indpr = ind; if (arc_start) fprintf(stderr, " ind = %d\n", ind); if (arc_start >= 2) arc_start = 1; continue; } if (ptr[0]>='A' && ptr[0]<='Z') break; if (!strncasecmp(ptr, "end", 3)) break; if (arc_precision<=6 && strlen(ptr)>28) { sep = ptr[28]; ptr[28] = '\0'; n = sscanf(ptr, "%lg %lg", &a, &b); if (n<2) continue; next_segment(a, b); ptr[28] = sep; p = sscanf(ptr+28, "%lg %lg", &c, &d); if (p>=2) next_segment(c, d); } else { n = sscanf(ptr, "%lg %lg", &a, &b); if (n<2) continue; next_segment(a, b); } } #ifdef ZLIB gzclose((gzFile *)fd); #else fclose((FILE *)fd); #endif } void warning_output(char *name) { fprintf(stderr, msg[COULDNT_OPEN_OUTPUT_FILE_FOR_ASCII_DUMP], name); fprintf(stderr, "\n"); exit(0); } #ifdef SEG_SELECT int seg_select(int i) { int answer; if (seg_mode<=1 || !seg_marked) return 1; answer = seg_mode-2; if (seg_marked[i]) return answer; else return !answer; } void mark_segments(int numseg) { int i, j; if (!seg_marked && numseg>0) { seg_marked = malloc(numseg*sizeof(char)); bzero(seg_marked, numseg); if (seg_nummarked) { for (i=0; i=0 && jindex[556]); else numseg = 0; #ifdef SEG_SELECT mark_segments(numseg); #endif address0 = sizeof(Header) + numseg*sizeof(Segment_index); maxlength = 0; total_numseg = 0; for (u=0; u<140; u++) { mem_numseg[u] = 0; if (check_cat_and_cont(scene, u)) { if (use_memory) { if (u==0) index1 = 0; else index1 = str4toint(&header->index[4*(u-1)]); index2 = str4toint(&header->index[4*u]); j = index2 - index1; if (index1>0) address2 = str4toint(segment_index[index1-1].address); else address2 = address0; for (i=index1; imaxlength) maxlength = nstrokes; } mem_numseg[u] = j; } if (arc_numseg) { for (i=0; imaxlength) maxlength = nstrokes; } } } total_numseg += mem_numseg[u] + ((arc_numseg)? arc_numseg[u] : 0); } total_address0 = sizeof(Header) + total_numseg*sizeof(Segment_index); if (dump_format == DUMP_ASCII) { k = 0; index2 = 0; for (u=0; u<140; u++) { if (use_memory) { index1 = index2; index2 = str4toint(&header->index[4*u]); } if (!check_cat_and_cont(scene, u)) continue; if (dump_split) { if (fd) fclose(fd); sprintf(filename, "%s.%03d", dump_file, u); if (dump_verbose) { fprintf(stderr, msg[OPENING_FILE], filename); fprintf(stderr, "\n"); } fd = fopen(filename, "w"); if (!fd) warning_output(filename); } if (u==0 || dump_split) { fprintf(fd, "%s", "%% Coordinate output (lon,lat) " "of arc strokes in vector map data\n"); fprintf(fd, "\narcinfo\n"); } if (dump_verbose && (mem_numseg[u] || ((arc_numseg)? arc_numseg[u] : 0)) ) { fprintf(stderr, msg[WRITING_ARCS_OF_TYPE], u, continent_name[u/28], u%28); fprintf(stderr, "\n"); } bool_write = 0; if (use_memory) { if (mem_numseg[u]) { bool_write = 1; fprintf(fd, "\n%%%% %s/%d\n", continent_name[u/28], u%28); fprintf(fd, "typ = %d\n", u); } if (index1) address2 = str4toint(segment_index[index1-1].address); else address2 = address0; for (i=index1; i0 && !bool_write) { fprintf(fd, "\n%%%% %s/%d\n", continent_name[u/28], u%28); fprintf(fd, "typ = %d\n", u); } for (i=0; iindex[4*u]); if (!check_cat_and_cont(scene, u)) continue; if (index1>0) address2 = str4toint(segment_index[index1-1].address); else address2 = address0; for (i=index1; imaxlong) maxlong = xi; if (yimaxlat) maxlat = yi; } total_address2 += 6+2*nstrokes; fpr3(fd, minlong); fpr3(fd, maxlong); fpr3(fd, minlat); fpr3(fd, maxlat); fpr4(fd, total_address2); } } } if (dump_verbose) { fprintf(stderr, msg[WROTE_JPD_SEGMENT_HEADERS], total_numseg); fprintf(stderr, "\n"); } index2 = 0; for (u=0; u<140; u++) { if (use_memory) { index1 = index2; index2 = str4toint(&header->index[4*u]); if (!check_cat_and_cont(scene, u)) continue; if (index1>0) address2 = str4toint(segment_index[index1-1].address); else address2 = address0; for (i=index1; iindex[556]); marked = malloc(numseg * sizeof(int)); bzero(marked, numseg * sizeof(int)); address0 = sizeof(Header) + numseg*sizeof(Segment_index); for (u=0; u<140; u++) { if (u==0) index1 = 0; else index1 = str4toint(&header->index[4*(u-1)]); index2 = str4toint(&header->index[4*u]); i = u%28; if (i<16 || i>21) continue; if (index1>0) address2 = str4toint(segment_index[index1-1].address); else address2 = address0; for (i=index1; i=0 && e[i]>=0) continue; if (abs(x1[i]-x0[i])+abs(y1[i]-y0[i])<=n) { b[i] = i; e[i] = i; num[i] = n; continue; } for (j=i+1; j=0 && e[j]>=0) continue; if (e[i]<0 && b[j]<0 && abs(x0[j]-x1[i])+abs(y0[j]-y1[i])<=n) { e[i] = j; b[j] = i; num[i] = n; if (b[i]>=0) j=NUM; } else if (b[i]<0 && e[j]<0 && abs(x1[j]-x0[i])+abs(y1[j]-y0[i])<=n) { b[i] = j; e[j] = i; num[j] = n; if (e[i]>=0) j=NUM; } else if (b[i]<0 && b[j]<0 && abs(x0[j]-x0[i])+abs(y0[j]-y0[i])<=n) { b[i] = j; b[j] = i; if (e[i]>=0) j=NUM; } else if (e[i]<0 && e[j]<0 && abs(x1[j]-x1[i])+abs(y1[j]-y1[i])<=n) { e[i] = j; e[j] = i; num[i] = n; num[j] = n; if (b[i]>=0) j=NUM; } } } ++n; } fprintf(stderr, "\n"); for (i=0; i=10) { l=0; printf("\n"); } k = length[g]; length[g] = k+1; group[g] = (int *) realloc(group[g], length[g]*sizeof(int)); group[g][k] = i; marked[ind[i]] = 0; if (e[i] == i0) { max = 0; for (k=0; kmax) max = num[j]; } if (max<=count) closed[g] = 1; printf(" closed [%d]\n\n", max); ++g; goto iter1; } goto iter2; finished: for (i=0; i0 && closed[g]>0) { for (i=0; i0 && closed[g]==0) { for (i=0; iprepixmap && scene->gopt.lineorder[0]=='0' && !essential_change(scene, scene->backup) && img_output!= OUT_EPS) { l = 0; XCopyArea(dpy, scene->prepixmap, scene->pixmap, gc, 0, 0, scene->width, scene->height, 0, 0); goto direct2; } /* initialize the image stuff */ image_init(scene); /* compute the rotation matrix */ compute_matrix(scene); /* Random seed for position of stars */ u = random() % 191; /* Initialize PostScript right now if OUT_EPS */ if (img_output == OUT_EPS) initialize_EPS(scene, u); /* set the background color or starry sky */ set_sky(scene, u); #ifdef DEBUG fprintf(stderr,"-- GENERATE --\n"); fprintf(stderr,"o Options\n"); fprintf(stderr," - slatitude [%g]\n", scene->ropt.spacing_lat); fprintf(stderr," - slongitude [%g]\n", scene->ropt.spacing_lon); fprintf(stderr," - zoom [%g]\n", scene->gopt.zoom); fprintf(stderr," - aspect [%g]\n", scene->aspect); fprintf(stderr," - latitude [%g]\n", scene->gopt.xrot); fprintf(stderr," - longitude [%g]\n", scene->gopt.yrot); fprintf(stderr," - inclination [%g]\n", scene->gopt.zrot); fprintf(stderr," - projection [%d]\n", scene->projection); fprintf(stderr," - mapfile [%s]\n", scene->mapfile); fprintf(stderr," - rcfile [%s]\n", scene->rcfile); fprintf(stderr," - locfile [%s]\n", scene->locfile); fprintf(stderr," - des_cat [%X]\n", scene->gopt.desired_categories); fprintf(stderr," - des_cont [%X]\n", scene->gopt.desired_continents); fprintf(stderr,"o ImageLayout (Scene)\n"); fprintf(stderr," - height [%d]\n", scene->height); fprintf(stderr," - width [%d]\n", scene->width); fprintf(stderr," - transp. [%d]\n", scene->gopt.transparent); fprintf(stderr,"o Colormap\n"); for (i=0; icolor[i].bool != INACTIVE) fprintf(stderr," - (%2d) [%s] %s\n",i , (scene->color[i].bool)? "on":"off", scene->color[i].name); fprintf(stderr, "o Rotation Matrix\n"); for (i=0; i<3; i++) fprintf(stderr," [%10.5f] [%10.5f] [%10.5f]\n", scene->rotation.comp[3*i], scene->rotation.comp[3*i+1], scene->rotation.comp[3*i+2]); fprintf(stderr,"-- -------- --\n"); #endif /* DEBUG */ if (scene->mapfile[0] == '\0' || !strcasecmp(scene->mapfile, "none") || !strcasecmp(scene->mapfile, "null")) { free_data_buffers(scene); use_memory = -1; } /* Open the mapfile and find graph of the appropriate sectors */ if (!fullmap_buffer) { if (use_memory >= 0) { #ifdef ZLIB fh = (void *)gzopen(scene->mapfile, "r"); if (fh == NULL) { char *name; name = scene->mapfile+strlen(scene->mapfile)-3; if (strcmp(name, ".gz")) { name = (char *)malloc(512); strcpy(name, scene->mapfile); strcat(name, ".gz"); fh = gzopen(name, "r"); free(name); } } #else fh = (FILE *)fopen(scene->mapfile, "r"); #endif if (use_memory>=0 && fh == NULL) { char *err_msg = malloc(512); sprintf(err_msg, msg[COULDNT_OPEN_VECTOR_MAP], scene->mapfile); fprintf(stderr, "%s\n", err_msg); if (runlevel) { XSetWindowBackgroundPixmap(dpy, mainwin, scene->pixmap); XClearWindow(dpy, mainwin); draw_win_string(scene, mainwin, err_msg, BOTTOM); XFlush(dpy); usleep(WARNING_TIME); } free(err_msg); } } else use_memory = 0; cannotuse: if (fh == NULL) { if (index(scene->gopt.lineorder, '0')) strcpy(scene->gopt.lineorder, "0"); else *scene->gopt.lineorder = '\0'; #ifdef ARCINFO if (dump_format == DUMP_STAT) writeout_stat(scene, 0); #endif goto direct1; } } /* read the header */ if (!header) { header = (Header *) malloc(sizeof(Header)); #ifdef ZLIB gzread((gzFile *)fh, header, sizeof(Header)); #else fread(header, 1, sizeof(Header), (FILE *)fh); #endif if (strcmp(header->magic, HEADER_MAGIC)) { fprintf(stderr, msg[MAGIC_INFORMATION1], scene->mapfile, header->magic); fprintf(stderr, "\n\n"); fprintf(stderr, msg[MAGIC_INFORMATION2], HEADER_MAGIC); fprintf(stderr, "\n%s\n", msg[MAGIC_INFORMATION3]); if (fh) #ifdef ZLIB gzclose((gzFile *)fh); #else fclose((FILE *)fh); #endif fh = NULL; free(header); header = NULL; goto cannotuse; } } numseg = str4toint(&header->index[556]); #ifdef SEG_SELECT mark_segments(numseg); #endif #ifdef ARCINFO if (dump_format == DUMP_STAT) writeout_stat(scene, numseg); #endif if (!segment_index) { #ifdef TRACE fprintf(stderr, "Allocating index buffer of size %d (%d headers)\n", numseg * sizeof(Segment_index), numseg); #endif segment_index = (Segment_index *) malloc(numseg * sizeof(Segment_index)); #ifdef ZLIB gzseek((gzFile *)fh, sizeof(Header), SEEK_SET); gzread((gzFile *)fh, segment_index, numseg * sizeof(Segment_index)); #else fseek((FILE *)fh, sizeof(Header), SEEK_SET); fread(segment_index, 1, numseg * sizeof(Segment_index), (FILE *)fh); #endif } address0 = sizeof(Header) + numseg*sizeof(Segment_index); if (use_memory && !fullmap_buffer) { i = str4toint(segment_index[numseg-1].address) - address0; #ifdef TRACE fprintf (stderr, "Addresses %d + %d = %d\n", address0, i, address0+i); fprintf(stderr, "Allocating index fullmap buffer of size %d (%d segments)\n", i * sizeof(Segment_index), numseg); #endif fullmap_buffer = (signed char *) malloc(i); #ifdef ZLIB gzseek((gzFile *)fh, address0, SEEK_SET); gzread((gzFile *)fh, fullmap_buffer, i); gzclose((gzFile *)fh); #else fseek((FILE *)fh, address0, SEEK_SET); fread(fullmap_buffer, 1, i, (FILE *)fh); fclose((FILE *)fh); #endif fh = NULL; segment_buffer = fullmap_buffer; } if (!segment_buffer) { maxlength = str4toint(header->maxlength); #ifdef TRACE fprintf(stderr, "Allocating segment buffer of size %d (max %d strokes)\n", 6+2*maxlength, maxlength); #endif segment_buffer = (char *) malloc(6+2*maxlength); } jump = (int)(scene->earth_radius*scene->accuracy/ (20.0*scene->gopt.zoom)); if (jump==0) jump=1; direct1: /* open output file if needed */ if (img_output!=OUT_NONE && img_output!=OUT_DUMP) open_outfile(scene); /* draw gridlines and segments with appropriate lineorder ordering */ for (l=strlen(scene->gopt.lineorder)-1; l>=0; l--) if (scene->gopt.lineorder[l]=='0') { if (l==0) XCopyArea(dpy, scene->pixmap, scene->prepixmap, gc, 0, 0, scene->width, scene->height, 0, 0); direct2: /* draw grid and contour */ draw_circles(scene); draw_circle_coordinates(scene); /* iterate through locations and show spot/texts */ scene->currentpixel = (reverse)?white:black; scene->red_current = (reverse)?65535:0; scene->green_current = scene->red_current; scene->blue_current = scene->red_current; scene->currentfont = 0; for (i=0; inumdef; i++) if (scene->def[i][0]==(char)1) { draw_feature(scene, scene->def[i]); scene->def[i][0] = (char)255; } if (img_output == OUT_EPS) print_string("%% locations\n[] 0 ds\n"); /* draw first large cities and high peaks, and then smaller ones */ /* this is just a very ugly hack to do this ... */ if (scene->ropt.smartlabels) { ret = 30; index1 = 3000000; address1 = 8000; } else { ret = 1; index1 = 0; address1 = 0; } index2 = 1000000000; address2 = 100000; for (u=0; uobj == 'c') { m = locations[i]->population; if (m>=index1 && mdraw &= 0x3fffffff; draw_location(scene, locations[i]); } } else if (locations[i]->obj == 'p') { m = locations[i]->alt; if (m>=address1 && mdraw &= 0x3fffffff; draw_location(scene, locations[i]); } } else { if (u>0) { locations[i]->draw &= 0x3fffffff; draw_location(scene, locations[i]); } } } index2 = index1; index1 = (5*index1)/6; if (index1<16000) index1 = 0; address2 = address1; address1 = (11*address1)/12; if (address1<650) address1 = 0; } if (img_output == OUT_EPS && scene->numdef>0) print_string("0 0 0 RGB 1.0 clw\n"); for (i=0; inumdef; i++) if (!scene->def[i][0]) draw_feature(scene, scene->def[i]); } else for (u=0; u<140; u++) { i = u/28; /* number of continent */ if ( !((1<gopt.desired_continents) ) continue; /* number of item */ j = u%28; /* type of item, INT=0, NAT=1, RIV=2 or CIL=3 */ if (j <= 2) k = 0; else if (j <= 4) k = 1; else if (j <= 15) k = 2; else k = 3; if (k!=scene->gopt.lineorder[l]-'1') continue; if ( !((1<gopt.desired_categories) ) continue; if (scene->color[j].bool!=ON) { #ifdef TRACE fprintf(stderr, "Skipping u = %d (type = %d)\n", u, j); #endif continue; } /* initialize escape length */ escape_length = scene->width/2; #ifndef SEG_SELECT pix = scene->color[j].pix; #endif if (img_output == OUT_EPS) { sprintf(line, "%%%% continent: %s\ns%d\n", continent_name[i], j); print_string(line); } #ifdef TRACE fprintf(stderr, "Section u = %d (type = %d)\n", u, j); #endif if (u==0) index1 = 0; else index1 = str4toint(&header->index[4*(u-1)]); index2 = str4toint(&header->index[4*u]); #ifdef TRACE fprintf(stderr, "ind1 = %d, ind2 = %d\n", index1, index2); #endif for (i=index1; icolor[C_FG_TICKS].pix; else pix = scene->color[j].pix; #endif for (n=0; n0) continue; sp.sph[LONGITUDE] = ((double)lon)/3600.0; sp.sph[LATITUDE] = ((double)lat)/3600.0; #ifdef SEG_SELECT if (seg_mode>=1 && !seg_marked[i]) { if (fabs(sp.sph[LONGITUDE]-arc_x)+ fabs(sp.sph[LATITUDE]-arc_y)<0.05) { printf("index %d\n", i); seg_marked[i] = 1; goto seg_repeat; } } #endif pt2 = project(scene, spher2cart(scene, sp)); draw_segment(scene, pt1, pt2, pix); } if (img_output == OUT_EPS) { sprintf(line, "k\n"); print_string(line); } } else if (ret == POINT_ONLY) { /* the whole segment amounts to a point based on the perspective of the scene, so just draw a point */ sp.sph[LONGITUDE] = str3toint(segment_index[i].maxlong)/3600.0; sp.sph[LATITUDE] = str3toint(segment_index[i].maxlat)/3600.0; pt1 = project(scene, spher2cart(scene, sp)); draw_pointseg(scene, pt1.coord[X], pt1.coord[Y], pix); } } } if (fh) #ifdef ZLIB gzclose((gzFile *)fh); #else fclose((FILE *)fh); #endif #ifdef ARCINFO if (arc_file) arcinfo_lines(scene); if (dump_file) dump_arcs(scene); #endif XSetWindowBackgroundPixmap(dpy, mainwin, scene->pixmap); XClearWindow(dpy, mainwin); if (cmdwin_on) { if (memcmp(scene, scene->backup, sizeof(ImageLayout))) draw_win_cmd(scene, 0); } memcpy(scene->backup, scene, sizeof(ImageLayout)); if (img_output != OUT_NONE) { if (img_output == OUT_EPS) { sprintf(line, "frame_style\n" "draw_frame { 0 0 m %d 0 l %d %d l 0 %d l 0 0 l k } if\n" "2 slj\n\n", scene->width, scene->width, scene->height, scene->height); print_string(line); print_string("%\ngrestore\nshowpage\n%%Trailer\n"); close_outfile(); } else print_image(scene); } if (textboxes) { free(textboxes); textboxes = NULL; } } /* * SECTION 5 : USER INTERFACE ROUTINES */ void search_city(ImageLayout * scene) { int i, l; char *needle; char *ptr = NULL; char fieldname[256]; unsigned char c; double lat = 0.0, lon=0.0, delta, deltax, deltay, deltamin = 1E20; char lat_str[80], lon_str[80]; if (search_by==6) { num_found = scene->num_positions; return; } l = strlen(search_string); needle = (char *)malloc(sizeof(char)*(l+2)); for (i=0; i<=l; i++) { c = search_string[i]; if (ptr) { if (c == ',' || c == '|') needle[i] = ' '; else needle[i] = c; } else if (c<='Z') { if (c=='-') c=' '; if (c>='A' && c<='Z') c += 32; needle[i] = c; } else if (c>=192) needle[i] = cvs[c-192]; else { if (c=='|') { needle[i] = '\0'; ptr = needle+i+1; } else needle[i] = c; } } if (search_by>4) ptr = NULL; if (ptr) { if (sscanf(ptr, "%s %s", lat_str, lon_str)<2) ptr = NULL; else { lat = dms2decim(lat_str); lon = dms2decim(lon_str); } } num_found = 0; start_list = 0; for (i=0; iname); if (locations[i]->obj!='c') simplify_string(fieldname); } else if (search_by==2) { if (locations[i]->obj!='c') continue; strcpy(fieldname, countries[timezones[locations[i]->tz]->country]->name); } else if (search_by==3) { if (locations[i]->obj!='c') continue; strcpy(fieldname, locations[i]->region); } else if (search_by==4) { if (locations[i]->obj!='l' || locations[i]->rank==-1) continue; strcpy(fieldname, locations[i]->name); if (l==0) { strcpy(needle, "*"); l = 1; } simplify_string(fieldname); } else if (search_by==5) { if (l==0) { strcpy(needle, "*"); l = 1; } if (i>=numpresel) break; } if (!string_cmp(fieldname, needle)) { if (ptr) { if (!num_found) { loc_pointer = (int *)realloc(loc_pointer, sizeof(int)); ++num_found; } deltax = fabs(lat-locations[i]->lat); deltay = fabs(lon-locations[i]->lon); delta = deltax*deltax + deltay*deltay; if (deltacolor[i].bool == OFF) strcpy(str, "-"); else if (scene->color[i].bool == ON && scene->color[i+1].bool == OFF) strcpy(str, "+"); else if (scene->color[i].bool == ON && scene->color[i+1].bool == ON) strcpy(str, "++"); } void value2str(ImageLayout * scene, int i, char * str, int mode) { int j; char c; *str = '\0'; if (cmd_mode==MODE_FILE) { if (cmd_type==M_FILE_DATA) { switch(i) { case 1: strcpy(str, scene->rcfile); break; case 2: strcpy(str, scene->mapfile); break; case 3: strcpy(str, (dump_file)? dump_file : ""); break; case 4: strcpy(str, scene->locfile); break; case 5: strcpy(str, scene->theme); break; case 6: if (datapix_name) strcpy(str, datapix_name); else *str = '\0'; break; default: break; } } if (cmd_type==M_FILE_EXTERNAL) { switch(i) { case 1: strcpy(str, ps_viewer); break; case 2: strcpy(str, im_viewer); break; case 3: strcpy(str, html_viewer); break; case 4: strcpy(str, svg_viewer); break; case 5: strcpy(str, svg_convert); break; case 6: strcpy(str, editor_cmd); break; case 7: strcpy(str, midi_cmd); break; default: break; } } if (cmd_type==M_FILE_PRINTCFG) { switch(i) { case 1: sprintf(str, "%.1f", ps_width); break; case 2: sprintf(str, "%.1f", ps_lm); break; case 3: sprintf(str, "%.1f", ps_bm); break; case 4: sprintf(str, "%d", ps_rot); break; case 5: sprintf(str, "%.2f", ps_lw); break; case 6: str[0] = (ps_frame)? '+':'-'; str[1] = '\0'; break; case 7: str[0] = (ps_grayscale)? '+':'-'; str[1] = '\0'; break; case 8: str[0] = (im_compress)? '+':'-'; str[1] = '\0'; break; case 9: strcpy(str, scene->macrofile); break; case 10: strcpy(str, print_cmd); break; default: break; } } if (cmd_type==M_FILE_SAVE && i==1) strcpy(str, scene->outfile); } if (cmd_mode==MODE_OPTION) { if (cmd_type==M_OPTION_PARAM) { switch(i) { case 1: if (mode) sprintf(str, "%d = %s", scene->projection, projtype[scene->projection]); else sprintf(str, "%d", scene->projection); break; case 2: sprintf(str, "%.3f", scene->accuracy); break; case 3: sprintf(str, "%d", scene->width); break; case 4: sprintf(str, "%d", scene->height); break; case 5: sprintf(str, "%.3f", scene->gopt.zoom); break; case 6: sprintf(str, "%.3f", scene->aspect); break; case 7: sprintf(str, "%.3f", scene->gopt.xrot); break; case 8: sprintf(str, "%.3f", scene->gopt.yrot); break; case 9: sprintf(str, "%.3f", scene->gopt.zrot); break; case 10: sprintf(str, "%.3f", scene->ropt.spacing_lat); break; case 11: sprintf(str, "%.3f", scene->ropt.spacing_lon); break; case 12: sprintf(str, "%c%c", get_grid_coordinates(scene->ropt.latcoord, 0), get_grid_coordinates(scene->ropt.loncoord, 1)); break; case 13: sprintf(str, "%c", (dms)? '+' : '-'); break; case 14: if (scene->gopt.transparent) strcpy(str, "+"); else strcpy(str, "-"); break; case 15: if (secure) strcpy(str, "+"); else strcpy(str, "-"); break; default: break; } } if (cmd_type==M_OPTION_HIERARCHY) { switch(i) { case 1: sprintf(str, "%s (mrk=0, int=1, nat=2, riv=3, cil=4)", scene->gopt.lineorder); break; case 2: sprintf(str, "%d,%d,%d,%d,%d", scene->ropt.mark_step[0], scene->ropt.mark_step[1], scene->ropt.mark_step[2], scene->ropt.mark_step[3], scene->ropt.mark_step[4]); break; case 3: sprintf(str, "%d,%d,%d,%d,%d", scene->ropt.name_step[0], scene->ropt.name_step[1], scene->ropt.name_step[2], scene->ropt.name_step[3], scene->ropt.name_step[4]); break; case 4: sprintf(str, "%d,%d,%d,%d,%d", scene->ropt.airport_mark[0], scene->ropt.airport_mark[1], scene->ropt.airport_mark[2], scene->ropt.airport_mark[3], scene->ropt.airport_mark[4]); break; case 5: sprintf(str, "%d,%d,%d,%d,%d", scene->ropt.airport_size[0], scene->ropt.airport_size[1], scene->ropt.airport_size[2], scene->ropt.airport_size[3], scene->ropt.airport_size[4]); break; case 6: sprintf(str, "%d,%d,%d,%d,%d", scene->ropt.peak_mark[0], scene->ropt.peak_mark[1], scene->ropt.peak_mark[2], scene->ropt.peak_mark[3], scene->ropt.peak_mark[4]); break; case 7: sprintf(str, "%d,%d,%d,%d,%d", scene->ropt.peak_size[0], scene->ropt.peak_size[1], scene->ropt.peak_size[2], scene->ropt.peak_size[3], scene->ropt.peak_size[4]); break; case 8: sprintf(str, "%d,%d,%d,%d,%d", scene->ropt.city_mark[0], scene->ropt.city_mark[1], scene->ropt.city_mark[2], scene->ropt.city_mark[3], scene->ropt.city_mark[4]); break; case 9: sprintf(str, "%d,%d,%d,%d,%d", scene->ropt.city_size[0], scene->ropt.city_size[1], scene->ropt.city_size[2], scene->ropt.city_size[3], scene->ropt.city_size[4]); break; case 10: strcpy(str, scene->ropt.city_filter); break; case 11: strcpy(str, scene->ropt.loc_filter); break; case 12: if (scene->ropt.smartlabels) strcpy(str, "+"); else strcpy(str, "-"); break; case 13: if (scene->ropt.placetext) strcpy(str, "+"); else strcpy(str, "-"); break; case 14: sprintf(str, "%s", flag_descr); break; case 15: sprintf(str, "%s (%s)", language, list_lang); break; default: break; } } if (cmd_type==M_OPTION_FONT) { if (i>=1 && i<=6) strcpy(str, scene->ropt.font[i-1]); } if (cmd_type==M_OPTION_MARKS) { switch(i) { case 1: twist_string(scene, C_CITY_CIRCLE, str); break; case 2: twist_string(scene, C_AIRPORT_SYMBOL, str); break; case 3: twist_string(scene, C_OBSERV_SYMBOL, str); break; case 4: twist_string(scene, C_PEAK_TRIANGLE, str); break; case 5: j = scene->color[C_LOC_LAND].bool; strcpy(str, (j)? "+":"-"); break; case 6: j = scene->color[C_LOC_WATER].bool; strcpy(str, (j)? "+":"-"); break; case 7: j = scene->color[C_LON_GRID].bool; strcpy(str, (j)? "+":"-"); break; case 8: j = scene->color[C_LAT_GRID].bool; strcpy(str, (j)? "+":"-"); break; case 9: j = scene->color[C_MAIN_LINES].bool; strcpy(str, (j)? "+":"-"); break; case 10: j = scene->color[C_EARTH_CONTOUR].bool; strcpy(str, (j)? "+":"-"); break; case 11: j = scene->color[C_BG_SKY].bool; strcpy(str, (j)? "+":"-"); break; case 12: j = scene->color[C_FG_STARS].bool; strcpy(str, (j)? "+":"-"); break; default: break; } } if (cmd_type==M_OPTION_CONTIN) { if ((1<<(i-1)) & scene->gopt.desired_continents) strcpy(str, "+"); else strcpy(str, "-"); } if (cmd_type==M_OPTION_CAT) { if ((1<<(i-1)) & scene->gopt.desired_categories) strcpy(str, "+"); else strcpy(str, "-"); } } if (cmd_mode==MODE_COLOR) { j = feature_index[cmd_type-1]+i-1; c = (scene->color[j].bool)? '+' : '-'; sprintf(str, "%c%s", c, scene->color[j].name); } } void twist_value(ImageLayout *scene, int i, char *str) { if (!strcmp(str, "-")) scene->color[i].bool = OFF; else if (!strcmp(str, "+")) { scene->color[i].bool = ON; scene->color[i+1].bool = OFF; } else if (!strcmp(str, "++")) { scene->color[i].bool = ON; scene->color[i+1].bool = ON; } } void str2value(ImageLayout * scene, int i, char * str) { int j; double f; if (cmd_mode==MODE_FILE) { if (cmd_type==M_FILE_DATA) { switch(i) { case 1: strcpy(scene->rcfile, str); expand_path(scene->mapfile); break; case 2: strcpy(scene->mapfile, str); expand_path(scene->mapfile); break; case 3: dump_file = realloc(dump_file, 256); strncpy(dump_file, str, 255); dump_file[255]= '\0'; expand_path(dump_file); if (*dump_file) { img_output = OUT_DUMP; dump_arcs(scene); img_output = OUT_NONE; } break; case 4: strcpy(scene->locfile, str); expand_path(scene->locfile); break; case 5: strcpy(scene->theme, str); expand_path(scene->theme); parse_theme(scene); break; case 6: parse_pixmaps(scene, str); break; default: break; } } if (cmd_type==M_FILE_EXTERNAL) { switch(i) { case 1: if (*str) { free(ps_viewer); ps_viewer = strdup(str); } break; case 2: if (*str) { free(im_viewer); im_viewer = strdup(str); } break; case 3: if (*str) { free(html_viewer); html_viewer = strdup(str); } break; case 4: if (*str) { free(svg_viewer); svg_viewer = strdup(str); } break; case 5: if (*str) { free(svg_convert); svg_convert = strdup(str); } break; case 6: if (*str) { free(editor_cmd); editor_cmd = strdup(str); } break; case 7: if (*str) { free(midi_cmd); midi_cmd = strdup(str); } break; default: break; } } if (cmd_type==M_FILE_PRINTCFG) { switch(i) { case 1: if (atof(str)>0) ps_width = atof(str); break; case 2: if (atof(str)>0) ps_lm = atof(str); break; case 3: if (atof(str)>0) ps_bm = atof(str); break; case 4: ps_rot = (int)atof(str); if (ps_rot>0) ps_rot = 90; if (ps_rot<0) ps_rot = -90; break; case 5: if (atof(str)>0) ps_lw = atof(str); break; case 6: ps_frame = (*str=='+'); break; case 7: ps_grayscale = (*str=='+'); break; case 8: im_compress = (*str=='+'); break; case 9: strncpy(scene->macrofile, str, 255); scene->macrofile[255] = '\0'; break; case 10: if (*str) { free(print_cmd); print_cmd = strdup(str); } break; default: break; } return; } if (cmd_type==M_FILE_SAVE && i==1) strcpy(scene->outfile, str); } if (cmd_mode==MODE_OPTION) { if (cmd_type==M_OPTION_PARAM) { switch(i) { case 1: scene->projection = set_proj(str); show_title(scene, mainwin); break; case 2: f = atof(str); if (f<=0.0) break; scene->accuracy = f; break; case 3: j = atoi(str); if (j<16) break; scene->width = j; XResizeWindow(dpy, mainwin, scene->width, scene->height); XFlush(dpy); break; case 4: j = atoi(str); if (j<16) break; scene->height = j; XResizeWindow(dpy, mainwin, scene->width, scene->height); XFlush(dpy); break; case 5: f = atof(str); if (fMAXZOOM) break; scene->gopt.zoom = f; break; case 6: f = atof(str); if (f<0.01) break; scene->aspect = f; break; case 7: scene->gopt.xrot = atof(str); break; case 8: scene->gopt.yrot = atof(str); break; case 9: scene->gopt.zrot = atof(str); break; case 10: scene->ropt.spacing_lat = atof(str); break; case 11: scene->ropt.spacing_lon = atof(str); break; case 12: if (strlen(str) != 2) break; scene->ropt.latcoord = set_grid_coordinates(str[0]); scene->ropt.loncoord = set_grid_coordinates(str[1]); break; case 13: dms = (*str=='+'); update_auxil_windows(scene); break; case 14: scene->gopt.transparent = (*str == '+'); break; case 15: secure= (*str == '+') ; break; default: break; } } if (cmd_type==M_OPTION_HIERARCHY) { switch(i) { case 1: strncpy(scene->gopt.lineorder, str, 5); scene->gopt.lineorder[5] = '\0'; check_lineorder(scene); break; case 2: if ((j=sscanf(str, "%d,%d,%d,%d,%d", &scene->ropt.mark_step[0], &scene->ropt.mark_step[1], &scene->ropt.mark_step[2], &scene->ropt.mark_step[3], &scene->ropt.mark_step[4]))<5) while(j<5) { scene->ropt.mark_step[j]=scene->ropt.mark_step[j-1]; ++j; } break; case 3: if ((j=sscanf(str, "%d,%d,%d,%d,%d", &scene->ropt.name_step[0], &scene->ropt.name_step[1], &scene->ropt.name_step[2], &scene->ropt.name_step[3], &scene->ropt.name_step[4]))<5) while(j<5) { scene->ropt.name_step[j]=scene->ropt.name_step[j-1]; ++j; } break; case 4: if ((j=sscanf(str, "%d,%d,%d,%d,%d", &scene->ropt.airport_mark[0], &scene->ropt.airport_mark[1], &scene->ropt.airport_mark[2], &scene->ropt.airport_mark[3], &scene->ropt.airport_mark[4]))<5) while(j<5) { scene->ropt.airport_mark[j] = scene->ropt.airport_mark[j-1]; ++j; } break; case 5: if ((j=sscanf(str, "%d,%d,%d,%d,%d", &scene->ropt.airport_size[0], &scene->ropt.airport_size[1], &scene->ropt.airport_size[2], &scene->ropt.airport_size[3], &scene->ropt.airport_size[4]))<5) while(j<5) { scene->ropt.airport_size[j]=scene->ropt.airport_size[j-1]; ++j; } break; case 6: if ((j=sscanf(str, "%d,%d,%d,%d,%d", &scene->ropt.peak_mark[0], &scene->ropt.peak_mark[1], &scene->ropt.peak_mark[2], &scene->ropt.peak_mark[3], &scene->ropt.peak_mark[4]))<5) while(j<5) { scene->ropt.peak_mark[j] = scene->ropt.peak_mark[j-1]; ++j; } break; case 7: if ((j=sscanf(str, "%d,%d,%d,%d,%d", &scene->ropt.peak_size[0], &scene->ropt.peak_size[1], &scene->ropt.peak_size[2], &scene->ropt.peak_size[3], &scene->ropt.peak_size[4]))<5) while(j<5) { scene->ropt.peak_size[j]=scene->ropt.peak_size[j-1]; ++j; } break; case 8: if ((j=sscanf(str, "%d,%d,%d,%d,%d", &scene->ropt.city_mark[0], &scene->ropt.city_mark[1], &scene->ropt.city_mark[2], &scene->ropt.city_mark[3], &scene->ropt.city_mark[4]))<5) while(j<5) { scene->ropt.city_mark[j] = scene->ropt.city_mark[j-1]; ++j; } break; case 9: if ((j=sscanf(str, "%d,%d,%d,%d,%d", &scene->ropt.city_size[0], &scene->ropt.city_size[1], &scene->ropt.city_size[2], &scene->ropt.city_size[3], &scene->ropt.city_size[4]))<5) while(j<5) { scene->ropt.city_size[j]=scene->ropt.city_size[j-1]; ++j; } break; case 10: load_city_filter(scene, str); break; case 11: load_loc_filter(scene, str); break; case 12: scene->ropt.smartlabels = (*str == '+'); break; case 13: scene->ropt.placetext = (*str == '+'); break; case 14: free(flag_descr); flag_descr = strdup(str); if (set_flag_dirs()) { free_flag_data(); list_flag_dirs(); } break; case 15: strncpy(language, str, 2); language[2] = '\0'; read_i18n_file(scene); fix_features_description(scene); break; default: break; } } if (cmd_type==M_OPTION_FONT) { if (i>=1 && i<=6) { i -= 1; str[255] = '\0'; if (!set_font(str, i)) strcpy(scene->ropt.font[i], str); } } if (cmd_type==M_OPTION_MARKS) { switch(i) { case 1: twist_value(scene, C_CITY_CIRCLE, str); break; case 2: twist_value(scene, C_AIRPORT_SYMBOL, str); break; case 3: twist_value(scene, C_OBSERV_SYMBOL, str); break; case 4: twist_value(scene, C_PEAK_TRIANGLE, str); break; case 5: scene->color[C_LOC_LAND].bool = !strcmp(str, "+"); break; case 6: scene->color[C_LOC_WATER].bool = !strcmp(str, "+"); break; case 7: scene->color[C_LON_GRID].bool = !strcmp(str, "+"); break; case 8: scene->color[C_LAT_GRID].bool = !strcmp(str, "+"); break; case 9: scene->color[C_MAIN_LINES].bool = !strcmp(str, "+"); break; case 10: scene->color[C_EARTH_CONTOUR].bool = !strcmp(str, "+"); break; case 11: scene->color[C_BG_SKY].bool = !strcmp(str, "+"); break; case 12: scene->color[C_FG_STARS].bool = !strcmp(str, "+"); break; default: break; } } if (cmd_type==M_OPTION_CONTIN) { j = 1<<(i-1); if (!strcmp(str, "+")) scene->gopt.desired_continents |= j; if (!strcmp(str, "-")) scene->gopt.desired_continents &= ~j; } if (cmd_type==M_OPTION_CAT) { j = 1<<(i-1); if (!strcmp(str, "+")) scene->gopt.desired_categories |= j; if (!strcmp(str, "-")) scene->gopt.desired_categories &= ~j; } } if (cmd_mode==MODE_COLOR) { j = feature_index[cmd_type-1]+i-1; if (cmd_type==M_COLOR_WIDGETS || j==C_BG_MAP) { scene->color[j].bool = 1; if (*str=='-') *str = '+'; } get_color(str, scene, j); if (color_depth<=8) get_all_colors(scene); if (j==C_BG_TEXT || j==C_FG_TEXT) set_bg_fg(scene); setup_change |= COLOR_CHANGE; } } void show_brief_menu(ImageLayout * scene) { int i, m = 0; static int old_brief_menu = -1; char *str; if (brief_menu != old_brief_menu) XClearWindow(dpy, mainwin); if (!brief_menu) return; XSetForeground(dpy, gc, scene->color[C_BG_TEXT].pix); if (brief_menu == 1) m = BEGIN_MAP_FEATURES - BEGIN_LIST_SHORTCUTS + 1; if (brief_menu == 2) m = END_MAP_FEATURES - BEGIN_MAP_FEATURES + 1; if (brief_menu == 3) m = 1; if (brief_menu == 4) { draw_win_string(scene, mainwin, error_msg, BOTTOM); return; } XFillRectangle(dpy, mainwin, gc, 14, 0, scene->width-28, (m+1)*(fonth[0]+12) + 26); XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); for (i=0; i<=m; i++) { if (i == 0) { str = msg[BRIEF_MENU_SHORTCUTS+brief_menu]; } else { if ((brief_menu==1 || brief_menu==2) && i==m) { str = "<<<<>>>>"; } else { XDrawRectangle(dpy, mainwin, gc, 29, i * (fonth[0]+12) + 19, 62, fonth[0]+7); XDrawRectangle(dpy, mainwin, gc, 30, i * (fonth[0]+12) + 20, 60, fonth[0]+5); if (brief_menu==2) str = msg[BEGIN_MAP_FEATURES+i-1]; else str = msg[BEGIN_LIST_SHORTCUTS+i-1]; } } XDrawString(dpy, mainwin, gc, 38, i * (fonth[0]+12) + fontasc[0] + ((i==0)? 13:23), str, strlen(str)); } } void draw_rect_cmd(ImageLayout * scene, char **paramstr, int n, int position, int level) { int i, l, m, y; char str[256]; char *ptr; box_width = 0; box_height = fonth[0]+6; box_spacing = fonth[0]+((level<0)?5:10); box_numitems = n; box_x = 6; box_y = (position-TOP+1)*(fonth[0]+16)-box_spacing/2+1; y = box_y+box_spacing/2-1; if (level<=1 && n>0) { XSetForeground(dpy, gc, scene->color[C_BG_TEXT].pix); XFillRectangle(dpy, cmdwin, gc, 0, y, cmdwin_width, (n+1)*box_spacing); } if (n>0) y += (n+1)*box_spacing; if (cmdwin_height-y-fonth[0]-6>0) XClearArea(dpy, cmdwin, 0, y, cmdwin_width, cmdwin_height-y-fonth[0]-6, False); for (i=1; i<=n; i++) { ptr = paramstr[i-1]; if (!ptr) ptr = "(null)"; l = strlen(ptr); XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); XDrawImageString(dpy, cmdwin, gc, box_x+6, box_y+i*box_spacing+fontasc[0]+3, ptr, l); m = XTextWidth(xfont[0], ptr, l) + 12; if (m>box_width) box_width = m; } for (i=1; i<=n; i++) { if (level>=0) { XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); XDrawRectangle(dpy, cmdwin, gc, box_x, box_y+i*box_spacing, box_width, box_height); } if (line_clicked==i) { XSetForeground(dpy, gc, scene->color[C_BG_TEXT].pix); XFillRectangle(dpy, cmdwin, gc, box_x+box_width+1, box_y+i*box_spacing, cmdwin_width-box_x-box_width-1, box_height); XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); XDrawRectangle(dpy, cmdwin, gc, box_x+1, box_y+i*box_spacing+1, box_width-2, box_height-2); } else { XSetForeground(dpy, gc, scene->color[C_BG_TEXT].pix); XDrawRectangle(dpy, cmdwin, gc, box_x+1, box_y+i*box_spacing+1, box_width-2, box_height-2); } value2str(scene, i, str, 1); if (*str) { XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); XDrawImageString(dpy, cmdwin, gc, box_x+box_width+5*char_width, box_y+i*box_spacing+fontasc[0]+3, str, strlen(str)); } } XFlush(dpy); } void show_manual() { int i=0, j, k, l, c, cp; char cmd[256]; char tmpname[80]; struct stat buf; char *ptr, *text; FILE *man; secure_tmpnam(tmpname); strcat(tmpname, "_xrmap.man"); sprintf(cmd, "man xrmap > %s", tmpname); system(cmd); man = fopen(tmpname, "r"); if (!man) { unlink(tmpname); return; } ptr = strdup(tmpname); buf.st_mode = 0; stat(ptr, &buf); free(ptr); text = malloc(buf.st_size+2); if (!text) { fclose(man); return; } while ((c=fgetc(man))!=EOF) { iter: if (c=='_') { cp = fgetc(man); if (cp==EOF) break; if (cp==8) continue; text[i++] = (char)c; c = cp; goto iter; } else if (c==8) { c = fgetc(man); if (c==EOF) break; } else text[i++] = (char)c; } text[i] = '\0'; fclose(man); man = fopen(tmpname, "w"); if (!man) { free(text); return; } for (j=0; jMODE_RUN) { XSizeHints xsh; cmdwin_on = 1; if (cmdwin_x>-100000) { xsh.flags = USPosition | PSize; xsh.x = cmdwin_x; xsh.y = cmdwin_y; xsh.width = cmdwin_width; xsh.height = cmdwin_height; XSetNormalHints(dpy, cmdwin, &xsh); } XMapWindow(dpy, cmdwin); XFlush(dpy); usleep(10000); } if (cmd_mode>MODE_RUN && level==0) { strcpy(str, labels_generalmenu); draw_win_string(scene, cmdwin, str, TOP); for (i=1;ioutfile); draw_win_string(scene, cmdwin, str, BOTTOM); } } } if (cmd_mode==MODE_MENU) { if (level<=1) draw_tick(scene, MODE_MENU, cmd_type, TOP); if (cmd_type==M_MENU_SEARCH) { line_clicked = search_by; draw_win_string(scene, cmdwin, msg[SPECIFY_STRING_TO_SEARCH], TOP+1); draw_rect_cmd(scene, searchby_descr, END_SEARCHBY_DESCRIPTION-BEGIN_SEARCHBY_DESCRIPTION, TOP+1, level); } else if (cmd_type==M_MENU_LIST) { char ** cityname_descr; if (search_by<=5) { strcpy(str, msg[LIST_OF_MATCHING_LOCATIONS]); line_clicked = -1; } else { strcpy(str, msg[LIST_OF_PREVIOUS_POSITIONS]); num_found = scene->num_positions; loc_pointer = (int *)realloc(loc_pointer, num_found*sizeof(int)); for (i=0; iposition[i].loc; } draw_win_string(scene, cmdwin, str, TOP+1); num_listed = cmdwin_height/(fonth[0]+10)-4; if (num_listed>num_found) num_listed = num_found; cityname_descr = (char **)malloc((num_listed+1)*sizeof(char *)); for (i=0; i0) strcpy(str, GO_UP); else if (i==num_listed-1 && start_list+num_listed=0) sprintf(name, " %s", locations[j]->name); else *name = '\0'; j = i+start_list; if (j==search_index) line_clicked = i+1; decim2dms(scene->position[j].xrot, lat); decim2dms(scene->position[j].yrot, lon); sprintf(str, "lat = %s, lon = %s, zoom = %.3f%s", lat, lon, scene->position[j].zoom, name); } else if (locations[j]->obj=='c') { decim2dms(locations[j]->lat, lat); decim2dms(locations[j]->lon, lon); sprintf(str, "%s, %s, %s (lat = %s lon = %s)", locations[j]->name, countries[timezones[locations[j]->tz]->country]->name, locations[j]->region, lat, lon); } else if (locations[j]->obj=='a' || locations[j]->obj=='b' || locations[j]->obj=='p') { decim2dms(locations[j]->lat, lat); decim2dms(locations[j]->lon, lon); sprintf(str, "%s, %s (lat = %s lon = %s)", locations[j]->name, countries[timezones[locations[j]->tz]->country]->name, lat, lon); } else if (locations[j]->obj=='l') { strcpy(name, locations[j]->name); simplify_string(name); decim2dms(locations[j]->lat, lat); decim2dms(locations[j]->lon, lon); sprintf(str, "%s, %s (lat = %s lon = %s)", name, msg[BEGIN_CONTINENT_DESCRIPTION+locations[j]->tz], lat, lon); } } cityname_descr[i] = strdup(str); } draw_rect_cmd(scene, cityname_descr, num_listed, TOP+1, level); j = box_y+box_spacing/2-1+(num_listed+1)*box_spacing; XClearArea(dpy, cmdwin, 0, j, cmdwin_width, cmdwin_height-j, False); for (i=0; iM_COLOR_START) draw_rect_cmd(scene, feature_descr[cmd_type-1], feature_length[cmd_type-1], TOP+1, level); } if (cmd_mode==MODE_HELP) { if (level<=1) draw_tick(scene, MODE_MENU, M_MENU_HELP, TOP); strcpy(str, labels_helpmenu); draw_win_string(scene, cmdwin, str, TOP+1); for (i=1; iEND_LIST_SHORTCUTS-BEGIN_LIST_SHORTCUTS) n = END_LIST_SHORTCUTS-BEGIN_LIST_SHORTCUTS; if (BEGIN_LIST_SHORTCUTS+start_shortcut+n>=END_LIST_SHORTCUTS) start_shortcut = END_LIST_SHORTCUTS-BEGIN_LIST_SHORTCUTS-n; ptr1 = msg[BEGIN_LIST_SHORTCUTS+start_shortcut]; ptr2 = msg[BEGIN_LIST_SHORTCUTS+start_shortcut+n-1]; if (start_shortcut) msg[BEGIN_LIST_SHORTCUTS+start_shortcut] = GO_UP; if (BEGIN_LIST_SHORTCUTS+start_shortcut+n< END_LIST_SHORTCUTS) msg[BEGIN_LIST_SHORTCUTS+start_shortcut+n-1] = GO_DOWN; draw_rect_cmd(scene, msg+BEGIN_LIST_SHORTCUTS+start_shortcut, n, TOP+1, -1); msg[BEGIN_LIST_SHORTCUTS+start_shortcut] = ptr1; msg[BEGIN_LIST_SHORTCUTS+start_shortcut+n-1] = ptr2; } if (cmd_type==M_HELP_ABOUT) show_version(scene, cmdwin); if (cmd_type==M_HELP_DOC || cmd_type==M_HELP_EXTRA) { DIR *dir = NULL; struct dirent *dirent = NULL; num_doc = 0; if (cmd_type==M_HELP_DOC) dir = opendir(DOCPATH); else if (cmd_type==M_HELP_EXTRA) dir = opendir(CIAEXTRAPATH); if (dir) { if (doc_descr) { for (i=0; id_name, ".") && strcmp(dirent->d_name, "..")) { doc_descr = (char **)realloc(doc_descr, (num_doc+2)*sizeof(char *)); doc_descr[num_doc] = strdup(dirent->d_name); ++num_doc; } closedir(dir); if (cmd_type==M_HELP_DOC) { doc_descr[num_doc] = strdup(msg[MANUAL_PAGE]); ++num_doc; } } num_listed = cmdwin_height/(fonth[0]+10)-4; if (num_listed>num_doc) { num_listed = num_doc; start_list = 0; } if (start_list + num_listed < num_doc) doc_descr[start_list+num_listed-1] = strdup(GO_DOWN); else start_list = num_doc - num_listed; if (start_list) doc_descr[start_list] = strdup(GO_UP); if (doc_descr) draw_rect_cmd(scene, doc_descr + start_list, num_listed, TOP+1,level); } if (cmd_type==M_HELP_EDIT) { char **data_descr = NULL; num_listed = cmdwin_height/(fonth[0]+10)-4; if (num_listed>scene->numpoint) num_listed = scene->numpoint; data_descr = (char**) malloc((num_listed+1)*sizeof(char*)); for (i=0; i0) strcpy(str, GO_UP); else if (i==num_listed-1 && start_list+num_listednumpoint) strcpy(str, GO_DOWN); else { sprintf(str, "%s = %.6f %s = %.6f", msg[LATITUDE_ABBREVIATED], scene->mempoint[2*(i+start_list)], msg[LONGITUDE_ABBREVIATED], scene->mempoint[2*(i+start_list)+1]); } data_descr[i] = strdup(str); } draw_rect_cmd(scene, data_descr, num_listed, TOP+1,level); for (i=0; icolor[j].bool != INACTIVE) { feature_descr[i][n] = scene->color[j].comment; } } } show_title(scene, mainwin); show_title(scene, datawin); show_title(scene, cmdwin); if (cmdwin_on) draw_win_cmd(scene, 0); } void explain_tz(char *out, char *data) { char *ptr, *ptrp; char explan[256], compl[80]; int month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int i, j, k, l; ptr = data; while (*ptr>='A' && *ptr<='Z') ++ptr; strncpy(explan, data, ptr-data); explan[ptr-data] = '\0'; strcat(out, explan); ptrp = ptr; while (*ptrp && *ptrp<'A') ++ptrp; if (*ptr=='-') { strncpy(explan, ptr, ptrp-ptr); explan[0] = '+'; explan[ptrp-ptr] = '\0'; } else if (*ptr=='+') { strncpy(explan, ptr, ptrp-ptr); explan[0] = '-'; explan[ptrp-ptr] = '\0'; } else { if (atoi(ptr)) { strncpy(explan+1, ptr, ptrp-ptr); explan[0] = '-'; explan[ptrp-ptr+1] = '\0'; } else { strcpy(explan, "0"); } } i = atoi(explan); j = -1; if ((ptrp=index(explan, ':'))) j = atoi(ptrp+1); strcat(out, explan); if (!index(ptr,',')) return; strcat(out, "/"); while (*ptr && *ptr<'A') ++ptr; ptrp = ptr; while (*ptrp && *ptrp!=',') ++ptrp; strncpy(explan, ptr, ptrp-ptr); explan[ptrp-ptr] = '\0'; strcat(out, explan); if (j==-1) { if (i+1>0) sprintf(explan, "+%d", i+1); else sprintf(explan, "%d", i+1); } else { if (i+1>=0) sprintf(explan, "+%d:%d ", i+1, j); else if (i+1<0) sprintf(explan, "%d:%d", i+1, j); } strcat(out, explan); if (!*ptrp) return; strcat(out, ", "); if (*ptrp==',') ++ptrp; repscan: if (*ptrp=='M') { sscanf(ptrp+1, "%d.%d.%d/%s", &i, &j, &k, compl); if (j<=0 || j>5) j=1; strcpy(explan, msg[ORDINALS+j-1]); strcat(explan, " "); if (k<0 || k>=7) k=0; l = msg[LENGTH_DAY_ABBREVIATION][k]-'0'; strncat(explan, msg[NAME_OF_DAYS+k], l); strcat(explan, " "); if (i<0 || i>11) i=0; l = msg[LENGTH_MONTH_ABBREVIATION][i]-'0'; strncat(explan, msg[NAME_OF_MONTHS+i], l); strcat(out, explan); if (!*compl) return; if ((ptrp=index(compl,','))) *ptrp = '\0'; strcat(out, " @"); strcat(out, compl); if (!ptrp) return; ++ptrp; } else if (*ptrp=='J') { sscanf(ptrp+1, "%d/%s", &j, compl); if (j>365) j=365; i = 0; while (j>month[i]) { j -= month[i]; ++i; } sprintf(explan, "%d", j); strcat(explan, " "); l = msg[LENGTH_MONTH_ABBREVIATION][i]-'0'; strncat(explan, msg[NAME_OF_MONTHS+i], l); strcat(out, explan); if (!*compl) return; if ((ptrp=index(compl,','))) *ptrp = '\0'; strcat(out, " @"); strcat(out, compl); if (!ptrp) return; ++ptrp; } else return; if (*ptrp) { strcat(out, "/"); goto repscan; } } void show_coord(ImageLayout * scene, double x, double y) { char str[256], compl1[40], compl2[40], lat[40], lon[40]; if (but_main_pressed == 3) { strcpy(compl1, msg[RECENTER_MAP]); strcpy(compl2, msg[CANCEL_MOVE]); } else *compl1 = *compl2 = '\0'; decim2dms(x, lat); decim2dms(y, lon); sprintf(str, "%slat = %s lon = %s%s", compl1, lat, lon, compl2); draw_win_string(scene, mainwin, str, line_pos); point_shown = 1; #ifdef SEG_SELECT if (seg_mode>=1 && but_main_pressed == 1) { arc_x = y; arc_y = x; if (scene->prepixmap) { XFreePixmap(dpy, scene->prepixmap); scene->prepixmap = None; } generate(scene); return; } #endif #ifdef ARCINFO if (arc_search && but_main_pressed == 1) { arc_start = 1; arc_x = y; arc_y = x; if (scene->prepixmap) { XFreePixmap(dpy, scene->prepixmap); scene->prepixmap = None; } generate(scene); return; } #endif } void set_time(int num, char *str) { struct tm ltp; time_t gtime; #ifdef __linux__ time(>ime); setenv("TZ", timezones[num]->posix, 1); #else char buf[256]; time(>ime); sprintf(buf, "TZ=%s", timezones[num]->posix); #ifdef __solaris__ putenv(buf); #endif #ifdef __hpux__ putenv(stdup(buf)); #endif #endif ltp = *localtime(>ime); sprintf(str, "%s %02d:%02d:%02d %s, %s %d %s %d", msg[DATE_TIME], ltp.tm_hour, ltp.tm_min, ltp.tm_sec, #ifdef NEW_CTIME ltp.tm_zone, #else tzname[ltp.tm_isdst], #endif msg[NAME_OF_DAYS+ltp.tm_wday], ltp.tm_mday, msg[NAME_OF_MONTHS+ltp.tm_mon], ltp.tm_year+1900); } void update_time(ImageLayout * scene, char *str) { int j, y, l1, l2, x1, x2, w1, w2; x1 = 4; x2 = 4; y = h_button+pixmap_height_max+11*(fonth[0]+4)+28; l1 = strlen(str); l2 = strlen(time_string); j = 0; XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); while(jmempoint[2*i], scene->mempoint[2*i+1]); write_primary(str); } void show_mark(ImageLayout * scene) { ScreenPt pt; SpherePt spt; int u, v, du = 0, dv = 0, l; char name[256]; if (brief_menu) return; if (cmd_mode==MODE_HELP && cmd_type==M_HELP_EDIT && scene->numpoint>0) { for (l=0; lnumpoint; l++) { spt.sph[LATITUDE] = scene->mempoint[2*l]; spt.sph[LONGITUDE] = scene->mempoint[2*l+1]; pt = project(scene, spher2cart(scene, spt)); if (!visible) continue; u = pt.coord[X]; v = pt.coord[Y]; if (l==line_clicked+start_list-1) XSetForeground(dpy, gc, scene->color[C_FG_SELPOINT].pix); else XSetForeground(dpy, gc, scene->color[C_FG_SELRECT].pix); XDrawLine(dpy, mainwin, gc, u-6, v, u+6, v); XDrawLine(dpy, mainwin, gc, u, v-6, u, v+6); } } if (city_found<0) return; clear_city_shown(); city_shown = 1; exposed |= DONE_MARK; spt.sph[LONGITUDE] = locations[city_found]->lon; spt.sph[LATITUDE] = locations[city_found]->lat; pt = project(scene, spher2cart(scene, spt)); if (!visible) return; u = pt.coord[X]; v = pt.coord[Y]; XSetForeground(dpy, gc, scene->color[C_FG_MARKED].pix); XSetFont(dpy, gc, xfont[1]->fid); reformat_string(name, locations[city_found]->name, 0); simplify_string(name); l = strlen(name); if (locations[city_found]->obj!='l') { XDrawLine(dpy, mainwin, gc, u-6, v, u+6, v); XDrawLine(dpy, mainwin, gc, u, v-6, u, v+6); du = -4-XTextWidth(xfont[1], locations[city_found]->name, l); dv = -3; } if (locations[city_found]->draw & TEXT_DRAWN) { city_already_shown = 1; l = scene->ropt.smartlabels; city_shown_box_w = 0; scene->ropt.smartlabels = 0; draw_location(scene, locations[city_found]); scene->ropt.smartlabels = l; city_already_shown = 0; if (city_shown_box_x > u - 7) { city_shown_box_w = city_shown_box_w + (city_shown_box_x - u + 7); city_shown_box_x = u - 7; } if (city_shown_box_y > v - 7) { city_shown_box_h = city_shown_box_h + (city_shown_box_y - v + 7); city_shown_box_y = v - 7; } if (city_shown_box_y + city_shown_box_h < v + 7) city_shown_box_h = v + 7 - city_shown_box_y; return; } city_shown_box_w = 13-du; city_shown_box_h = fonth[1]+13; if (u>scene->width/2) { city_shown_box_x = u+du-2; } else { city_shown_box_x = u-6; du = 6; } city_shown_box_y = v-6-fontasc[1]; XDrawString(dpy, mainwin, gc, u+du,v+dv, name, l); } void free_flag_data() { int i; if (flag_dir) { for (i=0; i9) j = flag_ordering[i] - 'a' + 9; if (j<0 || j>=num_flag_dirs) return 1; } return 0; } void list_flag_dirs() { char dirname[256], name[80], ftype[80]; struct dirent *dirent; DIR *dir; char *ptr; int i, j, k, n; int *weight, *order; sprintf(dirname, "%s/flags", SHAREDIR); dir = opendir(dirname); if (dir == NULL) return; flag_descr = NULL; flag_dir = NULL; num_flag_types = sizeof(flag_formats)/sizeof(char *); n = 1; for (dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) { ptr = dirent->d_name; if (!strcmp(ptr, ".") || !strcmp(ptr, "..")) continue; ++num_flag_dirs; strncpy(name, ptr, 78); name[78] = '\0'; strcpy(ftype, name); ptr = index(ftype, '_'); if (ptr) *ptr = '\0'; j = -1; for (i=0; i=200) weight[i] += 1000; } if (k==0) { for (i=0; i=weight[i]) ++order[j]; } if (k==1) { for (i=0; iobj == 'l') { strcpy(name, locations[city_found]->name); simplify_string(name); decim2dms(locations[city_found]->lat, lat); decim2dms(locations[city_found]->lon, lon); sprintf(str[0], "%s, %s (%c, %d)", name, msg[BEGIN_CONTINENT_DESCRIPTION+locations[city_found]->tz], locations[city_found]->status, locations[city_found]->population); sprintf(str[1], "%s = %s %s = %s", msg[LATITUDE_ABBREVIATED], lat, msg[LONGITUDE_ABBREVIATED], lon); if (locations[city_found]->rank==-1) { datawin_height = h_button+2*(fonth[0]+4)+12; if (raise) XMapRaised(dpy, datawin); else XMapWindow(dpy, datawin); (void) get_window_placement(datawin, &x, &y, &w, &h); if (w!=datawin_width || h!=datawin_height) XResizeWindow(dpy, datawin, datawin_width, datawin_height); XFlush(dpy); if (!datawin_on) usleep(80000); usleep(20000); datawin_on = 1; XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); for (i=0; i<=1; i++) { j = strlen(str[i]); XDrawString(dpy, datawin, gc, 4, h_button+(fonth[0]+4)*(i+1)+2, str[i], j); } XDrawLine(dpy, datawin, gc, 0, h_button, datawin_width, h_button); if (butpix[0]!=None) { XCopyArea(dpy, butpix[0], datawin, gc, 0,0, w_buttons-1, h_button-1, 0, 0); } return; } j = locations[city_found]->rank; sprintf(str[2], "%s", countries[j]->name); sprintf(str[3], msg[DATA_CURRENCY], countries[j]->currency, countries[j]->curr_code); sprintf(str[4], msg[DATA_TELEPHONE], countries[j]->telephone); sprintf(str[5], msg[DATA_AREA], countries[j]->area); sprintf(str[6], msg[DATA_POPULATION], countries[j]->capital, countries[j]->population); lstep = 2; lmax = 6; if (show_flags) { ptr = countries[j]->flags; goto doflags; } else goto skipflags; } if (locations[city_found]->obj != 'c' && locations[city_found]->obj != 'a' && locations[city_found]->obj != 'b' && locations[city_found]->obj != 'p') return; if (locations[city_found]->status=='C') sprintf(adm_status, " (%s)", msg[CAPITAL_OF_STATE]); else if (locations[city_found]->status=='R') sprintf(adm_status, " (%s)", msg[CAPITAL_OF_REGION]); else *adm_status = '\0'; reformat_string(name, locations[city_found]->name, 0); if (locations[city_found]->alt==-30000) strcpy(alt, "?"); else sprintf(alt, "%dm", locations[city_found]->alt); decim2dms(locations[city_found]->lat, lat); decim2dms(locations[city_found]->lon, lon); sprintf(str[1], "%s = %s %s = %s %s = %s", msg[LATITUDE_ABBREVIATED], lat, msg[LONGITUDE_ABBREVIATED], lon, msg[ALTITUDE_ABBREVIATED], alt); if (locations[city_found]->obj == 'b') { sprintf(str[0], name); sprintf(str[2], msg[ADMINISTRATIVE_REGION], (locations[city_found]->region[0])? locations[city_found]->region : "-"); str[3][0] = '\0'; goto fix_tz; } if (locations[city_found]->obj == 'a') { sprintf(str[0], name); sprintf(str[2], msg[AIRPORT_CODE_COUNTRY], locations[city_found]->region, locations[city_found]->rank); sprintf(str[3], msg[AIRPORT_RUNWAY_LENGTH], locations[city_found]->population); } if (locations[city_found]->rank) sprintf(rank1, "%d", locations[city_found]->rank); else strcpy(rank1, "-"); if (locations[city_found]->contrank) sprintf(rank2, "%d", locations[city_found]->contrank); else strcpy(rank2, "-"); if (locations[city_found]->worldrank) sprintf(rank3, "%d", locations[city_found]->worldrank); else strcpy(rank3, "-"); if (locations[city_found]->obj=='c') { sprintf(country, countries[timezones[locations[city_found]->tz]->country]->name); if ((ptr=index(country,','))) *ptr='\0'; sprintf(str[0], "%s, %s%s", name, country, adm_status); sprintf(str[2], msg[ADMINISTRATIVE_REGION], (locations[city_found]->region[0])? locations[city_found]->region : "-"); if (locations[city_found]->population) { sprintf(pop, "%d", locations[city_found]->population); sprintf(str[4], msg[POPULATION_NUMBER], pop); sprintf(str[5], msg[CONTINENT_AND_WORLD_RANKS], rank1, rank2, rank3); sprintf(str[3], "%s %s", str[4], str[5]); } else sprintf(str[3], msg[POPULATION_NUMBER], "?"); } else if (locations[city_found]->obj=='p') { sprintf(str[0], name); sprintf(str[2], locations[city_found]->region); sprintf(str[3], msg[CONTINENT_AND_WORLD_RANKS], rank1, rank2, rank3); } fix_tz: j = locations[city_found]->tz; k = timezones[j]->country; sprintf(str[4], "%s", countries[k]->name); sprintf(str[5], msg[DATA_CURRENCY], countries[k]->currency, countries[k]->curr_code); sprintf(str[6], msg[DATA_TELEPHONE], countries[k]->telephone); if (countries[k]->capital[0]=='@') { k = (countries[k]->capital[1]-'A')*26+(countries[k]->capital[2]-'A'); k = country_table[k]; sprintf(str[7], msg[DATA_TERRITORY], countries[k]->name); } else sprintf(str[7], msg[DATA_AREA], countries[k]->area); sprintf(str[8], msg[DATA_POPULATION], countries[k]->capital, countries[k]->population); sprintf(str[9], "%s %s; ", msg[AREA_AND_TIMEZONE], timezones[j]->name); explain_tz(str[9], timezones[j]->posix); set_time(j, str[10]); strcpy(time_string, str[10]); lstep = 4; lmax = 10; time_count = 1; if (!show_flags) goto skipflags; ptr = timezones[j]->flags; doflags: for (i=0; i<=1; i++) { if (prev_flag[i]) free(prev_flag[i]); prev_flag[i] = flag[i]; flag[i] = NULL; pixmap_width[i] = pixmap_height[i] = 0; } pixmap_height_max = 0; flag[0] = strdup(ptr); if ((ptr = index(flag[0], ','))) { *ptr = '\0'; flag[1] = strdup(ptr+1); } for (i=0; i<=1; i++) { if (!flag[i] || (prev_flag[i] && strcmp(flag[i], prev_flag[i]))) { if (flag_image[i]) XDestroyImage(flag_image[i]); flag_image[i] = NULL; } if (flag[i] && !flag_image[i]) flag_image[i] = readIMG(scene, FLAGPATH, flag[i], 150, &scene->color[C_BG_TEXT]); if (!flag_image[i]) { if (flag[i]) { pixmap_width[i] = 270; pixmap_height[i] = 150; } } else { pixmap_width[i] = flag_image[i]->width; pixmap_height[i] = flag_image[i]->height; } if (pixmap_height[i] > pixmap_height_max) pixmap_height_max = pixmap_height[i]; } skipflags: if (pixmap_height_max>0) datawin_height = h_button + pixmap_height_max + 26; else { pixmap_height_max = -8; datawin_height = h_button + 20; } datawin_height += (lmax+1)*(fonth[0]+4)+10*(lmax==10); if (datawin_x>-100000) { XSizeHints xsh; xsh.flags = USPosition | PSize; xsh.x = datawin_x; xsh.y = datawin_y; xsh.width = datawin_width; xsh.height = datawin_height; XSetNormalHints(dpy, datawin, &xsh); } if (raise) XMapRaised(dpy, datawin); else XMapWindow(dpy, datawin); (void) get_window_placement(datawin, &x, &y, &w, &h); if (w!=datawin_width || h!=datawin_height) XResizeWindow(dpy, datawin, datawin_width, datawin_height); if (datawin_x>-100000) { XMoveWindow(dpy, datawin, datawin_x, datawin_y); datawin_x = -1000000; } XFlush(dpy); if (!datawin_on) usleep(80000); usleep(20000); datawin_on = 1; show_mark(scene); XClearArea(dpy, datawin, 0, h_button + 1, datawin_width, 4, False); XClearArea(dpy, datawin, 0, h_button+5, 4, pixmap_height_max, False); for (i=0; i<=1; i++) if (flag[i]) { j = (i)? pixmap_width[0]+12 : 4; if (flag_image[i]) { XPutImage(dpy, datawin, gc, flag_image[i], 0, 0, j, h_button + 5, pixmap_width[i], pixmap_height[i]); } else { sprintf(path, "%s/???/%s.???", FLAGPATH, flag[i]); XSetForeground(dpy, gc, scene->color[C_BG_TEXT].pix); XFillRectangle(dpy, datawin, gc, j, h_button + 5, pixmap_width[i], pixmap_height[i]); XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); XDrawRectangle(dpy, datawin, gc, j, h_button + 5, pixmap_width[i]-1, pixmap_height[i]-1); XDrawString(dpy, datawin, gc, (i)? pixmap_width[0]+20:12, h_button+8+2*fonth[0], path, strlen(path)); } } if (flag[1]) { XClearArea(dpy, datawin, pixmap_width[0]+4, h_button+5, 8, pixmap_height_max, False); XClearArea(dpy, datawin, pixmap_width[0]+pixmap_width[1]+12, h_button + 5, datawin_width, pixmap_height_max, False); } else XClearArea(dpy, datawin, pixmap_width[0]+4, h_button+5, datawin_width, pixmap_height_max, False); k = 90; if (erase_text) XClearArea(dpy, datawin, 0, h_button+pixmap_height_max+5, datawin_width, datawin_height, False); XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); for (i=0; i<=lmax; i++) { j = strlen(str[i]); XDrawString(dpy, datawin, gc, 4, h_button + pixmap_height_max+(fonth[0]+4)*(i+1)+8+ ((i>=lstep)?10:0)+((i>=9)?10:0), str[i], j); k += j+2; data_text = realloc(data_text, (k+2)*sizeof(char)); if (i==lstep) strcat(data_text, "\n"); if (i==lmax) { for (j=1; j<=78; j++) strcat(data_text, "-"); strcat(data_text, "\n"); } else strcat(data_text, str[i]); strcat(data_text, "\n"); } line_y = h_button+pixmap_height_max + (lstep+1)*(fonth[0]+4)+14-fontasc[0]; XDrawLine(dpy, datawin, gc, 0, h_button, datawin_width, h_button); XDrawLine(dpy, datawin, gc, 0, line_y, datawin_width, line_y); if (butpix[0]!=None) { XCopyArea(dpy, butpix[0], datawin, gc, 0, 0, w_buttons-1, h_button-1, 0, 0); XClearArea(dpy, datawin, w_buttons-1, 0, datawin_width, h_button-1, False); } else for (i=0; icolor[C_FG_TEXT].pix); XDrawRectangle(dpy, datawin, gc, i * w_button + 4, 3, w_button - 4, h_button - 8); s[0] = s[2] = '?'; s[1] = '1'+i; s[3] = '\0'; XDrawString(dpy, datawin, gc, i * w_button + 8, 7+fontasc[0], s, 3); } if (lmax==10) { j = h_button + pixmap_height_max + 11*(fonth[0]+4)+4-fontasc[0]; XDrawLine(dpy, datawin, gc, 0, j, datawin_width, j); } XFlush(dpy); } void flag_viewer(int j) { struct stat buf; char *viewer; char name[256], cmd[512]; if (j<0 || j>num_flag_dirs) return; if (!flag_name || !flag_name) return; sprintf(name, "%s/%s/%s.%s", FLAGPATH, flag_dir[j], flag_name, flag_type[j]); if (stat(name, &buf) || !S_ISREG(buf.st_mode)) strcat(name, ".gz"); if (stat(name, &buf) || !S_ISREG(buf.st_mode)) return; if (!strcmp(flag_type[j], "eps")) viewer = ps_viewer; else if (!strcmp(flag_type[j], "svg")) viewer = svg_viewer; else viewer = im_viewer; sprintf(cmd, "%s %s &", viewer, name); system(cmd); } void show_flagwin(ImageLayout * scene, int raise) { XEvent ev, *pev; int x, y, w, h, n; if (!flag_name) return; if (raise) XMapRaised(dpy, flagwin); else XMapWindow(dpy, flagwin); XFlush(dpy); if (!flagwin_on || raise) usleep(20000); flagwin_on = 1; if (!big_flag_image) { flag_size = 1; big_flag_image = readIMG(scene, FLAGPATH, flag_name, flagwin_height, &scene->color[C_BG_TEXT]); flag_size = 0; } if (raise && big_flag_image && (flagwin_width != big_flag_image->width || flagwin_height != big_flag_image->height)) { flagwin_width = big_flag_image->width; flagwin_height = big_flag_image->height; (void) get_window_placement(flagwin, &x, &y, &w, &h); if (w!=flagwin_width || h!=flagwin_height) { XResizeWindow(dpy, flagwin, flagwin_width, flagwin_height); XFlush(dpy); usleep(40000); pev = NULL; n = 0; while (XCheckIfEvent(dpy, &ev, evpred, (XPointer)0)) { if (ev.xexpose.window != flagwin) { ++n; pev = (XEvent *)realloc(pev, n*sizeof(XEvent)); pev[n-1] = ev; } } if (pev) while (n>=1) { --n; XPutBackEvent(dpy, &pev[n]); } if (pev) free(pev); } } if (big_flag_image && (big_flag_image->width > flagwin_width)) { h = (flagwin_width*big_flag_image->height) / big_flag_image->width; XDestroyImage(big_flag_image); flag_size = 1; big_flag_image = readIMG(scene, FLAGPATH, flag_name, h, &scene->color[C_BG_TEXT]); flag_size = 0; } XSetWindowBackground(dpy, flagwin, scene->color[C_BG_TEXT].pix); if (big_flag_image) { XPutImage(dpy, flagwin, gc, big_flag_image, 0, 0, 0, 0, big_flag_image->width, big_flag_image->height); XClearArea(dpy, flagwin, big_flag_image->width, 0, flagwin_width, flagwin_height, False); XClearArea(dpy, flagwin, 0, big_flag_image->height, flagwin_width, flagwin_height, False); } else XClearWindow(dpy, flagwin); } void view_outfile(ImageLayout * scene) { struct stat buf; char compl[50], str[512]; if (!*scene->outfile) return; *compl = '\0'; #ifdef ZLIB if (im_compress && strcmp(scene->outfile+strlen(scene->outfile)-3,".gz")) strcpy(compl, ".gz"); #endif sprintf(str, "%s%s", scene->outfile, compl); buf.st_mode = 0; stat(str, &buf); if (!S_ISREG(buf.st_mode)) return; get_output_type(scene); if (img_output==OUT_RC && *editor_cmd) { sprintf(str, "(%s %s%s ; rm -f %s%s ) &", editor_cmd, scene->outfile, compl, scene->outfile, compl); system(str); } else if ((img_output==OUT_EPS || img_output==OUT_PS) && *ps_viewer) { sprintf(str, "%s %s%s &", ps_viewer, scene->outfile, compl); system(str); } else if (img_output!=OUT_EPS && img_output!=OUT_PS && *im_viewer) { sprintf(str, "%s %s%s &", im_viewer, scene->outfile, compl); system(str); } img_output = OUT_NONE; } void edit_rc_output(ImageLayout * scene) { char ptr[256]; strcpy(ptr, scene->outfile); secure_tmpnam(scene->outfile); strcat(scene->outfile, "_xrmap_data.rc"); img_output = OUT_RC; overwrite = 1; open_outfile(scene); print_image(scene); view_outfile(scene); strcpy(scene->outfile, ptr); } void clear_mainwin_strips(ImageLayout * scene) { if (point_shown) { clear_strip(scene, TOP); clear_strip(scene, BOTTOM); show_mark(scene); point_shown = 0; } } void show_point(ImageLayout * scene, int u, int v, int active) { double x, y, eps; int i=0, j, k, found, popul, max; int up, vp, uf=0, vf=0; char lat[256], lon[256]; char cmd[1024]; if (brief_menu) return; found = -1; if (inverse_coord(scene, u, v, &x, &y)) { eps = 1.5/scene->gopt.zoom; if (but_main_pressed==1) { popul = -30000; max = 10; if (active) for (i=0; inumdef; i++) if (scene->def[i][0]==(char)2) { double fact = 0.3334*(scene->def[i][6]-'0'+1); double xp, yp; char *rep; int m, n; rep = strdup(scene->def[i]+8); n=0; for (m=0; mdraw & SPOT_DRAWN) && fabs(x-locations[i]->lat)+fabs(y-locations[i]->lon)lon; spt.sph[LATITUDE] = locations[i]->lat; pt = project(scene, spher2cart(scene, spt)); up = pt.coord[X]; vp = pt.coord[Y]; j = abs(u-up); k = abs(v-vp); if (j<3 && k<3 && j+k<=max) { if (j+kpopulation>popul) { found = i; uf = up; vf = vp; popul = locations[i]->population; } } } } } if (v>scene->height/2) j = TOP; else j = BOTTOM; if (j!=line_pos) { clear_strip(scene, line_pos); line_pos = j; } if (found>=0) { if (found==city_found) return; city_found = found; show_datawin(scene, 1); } show_coord(scene, x, y); } else clear_mainwin_strips(scene); } void open_cmdwin(ImageLayout * scene) { cmd_mode = MODE_CMD; cmd_type = M_CMD_START; draw_win_cmd(scene, 0); XMapRaised(dpy, cmdwin); } void open_explwin(ImageLayout * scene) { if (explpix) XSetWindowBackgroundPixmap(dpy, explwin, explpix); else XSetWindowBackground(dpy, explwin, scene->color[C_BG_CMDWIN].pix); XMapRaised(dpy, explwin); explwin_on = 1; expl_shift = 0; } /* * SECTION 6 : X EVENTS ROUTINES */ void do_escape(ImageLayout * scene) { int i; line_clicked = -1; *cmd_string = '\0'; caret_pos = 0; cmd_mode = MODE_RUN; cmd_type = M_RUN_START; memcpy(scene, scene->backup, sizeof(ImageLayout)); if (setup_change & FONT_CHANGE) { for (i=0; i<=5; i++) set_font(scene->ropt.font[i], i); setup_change &= ~FONT_CHANGE; } if (setup_change & COLOR_CHANGE) { get_all_colors(scene); setup_change &= ~COLOR_CHANGE; if (color_depth<=8) { generate(scene); return; } } if (cmdwin_on) close_cmdwin(scene); } void do_activate(ImageLayout * scene, KeySym keysym) { char str[512], outfilename[256], compl[6]; struct stat buf; if (cmd_mode==MODE_MENU && cmd_type==M_MENU_SEARCH) { if (!*cmd_string) { draw_win_cmd(scene, 2); if (keysym==XK_Return && line_clicked<=3) return; } if (search_string) free(search_string); search_string = strdup(cmd_string); search_city(scene); search_output(scene, (keysym==XK_exclam)); return; } if (cmd_mode==MODE_HELP && cmd_type==M_HELP_EDIT) { int i, j; char str[40]; i = strlen(cmd_string); if (scene->numpoint && i>=2 && cmd_string[i-2]=='|' && cmd_string[i-1]=='*') { cmd_string = realloc(cmd_string, i+40*scene->numpoint); cmd_string[i-2] = '\0'; for (j=0; jnumpoint; j++) { sprintf(str, "|%.6f,%.6f", scene->mempoint[2*j], scene->mempoint[2*j+1]); strcat(cmd_string, str); } } parse_define(scene, cmd_string); generate(scene); show_mark(scene); *cmd_string = '\0'; draw_win_cmd(scene, 2); return; } if (cmd_mode==MODE_FILE && (cmd_type==M_FILE_DATA || cmd_type==M_FILE_PRINTCFG)) { str2value(scene, line_clicked, cmd_string); if (keysym==XK_Return) { draw_win_cmd(scene, 2); return; } } if (cmd_mode==MODE_FILE && cmd_type==M_FILE_SAVE) { if (line_clicked<=1) { strncpy(scene->outfile, cmd_string, 255); scene->outfile[255] = '\0'; draw_win_cmd(scene, 2); return; } #ifdef ZLIB if (im_compress && *scene->outfile && strcmp(scene->outfile+strlen(scene->outfile)-3,".gz")) strcpy(compl, ".gz"); else #endif *compl = '\0'; sprintf(outfilename, "%s%s", scene->outfile, compl); if (runlevel && line_clicked==2 && !*scene->outfile) { noname: draw_win_string(scene, cmdwin, msg[NO_FILENAME_SPECIFIED], BOTTOM); return; } if (line_clicked==3) { if (!*scene->outfile) goto noname; buf.st_mode = 0; stat(outfilename, &buf); if (!S_ISREG(buf.st_mode)) { notsaved: draw_win_string(scene, cmdwin, msg[FILE_NOT_SAVED], BOTTOM); return; } sprintf(str, msg[VIEWING_IMAGE], outfilename); draw_win_string(scene, cmdwin, str, BOTTOM); view_outfile(scene); return; } if (line_clicked==4) { if (!*scene->outfile) goto noname; buf.st_mode = 0; stat(outfilename, &buf); if (!S_ISREG(buf.st_mode)) goto notsaved; if (strcmp(outfilename+strlen(outfilename)-3,".ps") && strcmp(outfilename+strlen(outfilename)-4,".eps") && strcmp(outfilename+strlen(outfilename)-6,".ps.gz") && strcmp(outfilename+strlen(outfilename)-7,".eps.gz")) goto notsaved; sprintf(str, msg[PRINTING_IMAGE], outfilename); draw_win_string(scene, cmdwin, str, BOTTOM); if (strcmp(outfilename+strlen(outfilename)-3,".gz")) sprintf(str, "%s %s &", print_cmd, outfilename); else sprintf(str, "gzip -cd %s | %s - &", outfilename, print_cmd); system(str); return; } if (overwrite==1) overwrite=-1; open_outfile(scene); if (overwrite==-1) { get_output_type(scene); sprintf(str, msg[WRITING_IMAGE_TO_FILE], outfilename); draw_win_string(scene, cmdwin, str, BOTTOM); if (img_output == OUT_EPS) generate(scene); else { print_image(scene); strcpy(((ImageLayout *)scene->backup)->outfile, scene->outfile); ((ImageLayout *)scene->backup)->prepixmap = scene->prepixmap; } img_output = OUT_NONE; overwrite = 0; } } if (cmd_mode==MODE_CMD) { if (*cmd_string && parse_cmd_line(scene, cmd_string, " ")) return; } if (keysym==XK_exclam || ((cmd_mode==MODE_CMD) && expert)) { if (cmd_mode == MODE_MENU && cmd_type==M_MENU_LIST && search_index>=0) { if (num_found==1 && search_by<=5) { search_output(scene, 1); return; } if (search_index!=-1) { if (search_by==6) city_found = loc_pointer[search_index]; else city_found = search_index; } } if (!memcmp((char *)scene, (char *)scene->backup, sizeof(ImageLayout))) { draw_win_string(scene, cmdwin, msg[NO_CHANGE_MADE], BOTTOM); return; } /* look whether some options have changed that force to regenerate image */ if (memcmp((char *)scene, (char *)scene->backup, sizeof(ImageLayout)-256- (C_ENDCOLOR-C_FG_TEXT)*sizeof(Colordata))) { check_datachanges(scene); generate(scene); if (datawin_on) show_mark(scene); } if (search_index==city_found && search_index>=0) show_datawin(scene, 1); return; } /* Remaining text_input cases with XK_Return */ if (text_input_mode()) { if (line_clicked>=1 && line_clicked<=box_numitems) { str2value(scene, line_clicked, cmd_string); if (setup_change) draw_win_cmd(scene, 0); else draw_win_cmd(scene, 2); } } else draw_win_cmd(scene, 0); } void filemenu(ImageLayout * scene) { overwrite = 0; cmd_mode = MODE_FILE; cmd_type = M_FILE_START; cmd_string = (char *)realloc(cmd_string, 1); *cmd_string = '\0'; cmd_killed_char = '\0'; caret_pos = 0; } int click_truncated_list(int l, int total, int *level) { if (l==1 && start_list>0) { start_list -= (num_listed-3); if (start_list<0) start_list = 0; *level = 1; return 0; } else if (l==num_listed && start_list+num_listedtotal) start_list = total-num_listed; *level = 1; return 0; } else { if (line_clicked==-10) *level = 1; else *level = 2; return 1; } } void adjust_list(int total, int *l) { if (*l==1 && start_list>0) { line_clicked = -10; start_list -= (num_listed-3); if (start_list<0) start_list = 0; *l = num_listed-1; } else if (*l==num_listed && start_list+num_listedtotal) start_list = total-num_listed; *l = 2; } } void search_output(ImageLayout * scene, int force) { int i; if (num_found==0) { i = caret_pos; caret_pos = -10; draw_win_string(scene, cmdwin, msg[NO_MATCH_IN_SEARCH], BOTTOM); usleep(WARNING_TIME); caret_pos = i; draw_win_string(scene, cmdwin, search_string, BOTTOM); } else if (num_found==1 && force==1) { city_found = loc_pointer[0]; scene->gopt.xrot = locations[city_found]->lat; scene->gopt.yrot = locations[city_found]->lon; update_positions(scene, city_found); search_index = city_found; check_datachanges(scene); generate(scene); show_mark(scene); show_datawin(scene, 1); } else { cmd_mode = MODE_MENU; cmd_type = M_MENU_SEARCH; draw_win_cmd(scene, 0); cmd_type = M_MENU_LIST; draw_win_cmd(scene, 1); } } void convert_keysym(KeySym * key) { if (*key == XK_Control_L || *key == XK_Control_R ) { control_pressed = 0; *key = '\0'; return; } if (*key>=XK_KP_0 && *key<=XK_KP_9) *key += XK_0-XK_KP_0; if (*key==XK_KP_Add) *key = XK_plus; if (*key==XK_KP_Subtract) *key = XK_minus; if (*key==XK_KP_Multiply) *key = XK_asterisk; if (*key==XK_KP_Divide) *key = XK_slash; if (*key==XK_KP_Delete) *key = XK_BackSpace; if (*key==XK_KP_Decimal) *key = XK_period; if (*key==XK_KP_Enter) *key = XK_Return; if (*key==XK_BackSpace) *key = XK_Delete; } void regenerate_objects(ImageLayout *scene, int i, int j) { char str[256]; if (i) sprintf(str, msg[GENERATING_MAP_WITH], msg[j]); else sprintf(str, msg[GENERATING_MAP_WITHOUT], msg[j]); draw_win_string(scene, mainwin, str, BOTTOM); generate(scene); show_mark(scene); } void rotate_generate(ImageLayout *scene, int i, int j) { char str[256]; if (scene->color[i].bool==ON && scene->color[i+1].bool==OFF) { scene->color[i].bool = ON; scene->color[i+1].bool = ON; sprintf(str, msg[GENERATING_MAP_WITH_OBJECTS_AND_NAMES], msg[j]); } else if (scene->color[i].bool==OFF) { scene->color[i].bool = ON; scene->color[i+1].bool = OFF; sprintf(str, msg[GENERATING_MAP_WITH_OBJECTS], msg[j]); } else { scene->color[i].bool = OFF; scene->color[i+1].bool = OFF; sprintf(str, msg[GENERATING_MAP_WITHOUT_OBJECTS], msg[j]); } draw_win_string(scene, mainwin, str, BOTTOM); generate(scene); show_mark(scene); } void rotate_value(ImageLayout *scene, int i) { if (scene->color[i].bool == OFF) { scene->color[i].bool = ON; scene->color[i+1].bool = OFF; } else if (scene->color[i].bool == ON && scene->color[i+1].bool == OFF) scene->color[i+1].bool = ON; else if (scene->color[i].bool == ON && scene->color[i+1].bool == ON) { scene->color[i].bool = OFF; scene->color[i+1].bool = OFF; } } void show_modified_buttons(int mode, int num) { int but_x; if (num < 0 || num >= NUM_BUTTONS) return; but_x = w_button*num + 3; if (butpix[0]!=None) XCopyArea(dpy, butpix[0], datawin, gc, but_x, 0, w_button-1, h_button-1, but_x, 0); if (butpix[1]!=None && mode==1 && num>=0 && butpix[1]!=None) { XCopyArea(dpy, butpix[1], datawin, gc, but_x, 0, w_button-1, h_button-1, but_x, 0); } if (butpix[2]!=None && mode==2 && num>=0 && butpix[2]!=None) { XCopyArea(dpy, butpix[2], datawin, gc, but_x, 0, w_button-1, h_button-1, but_x, 0); } } void show_mouse_hint(ImageLayout * scene, int num) { int i, j, w; i = w_buttons + 8; j = 5; w = XTextWidth(xfont[0], msg[BEGIN_MOUSE_HINTS+num], strlen(msg[BEGIN_MOUSE_HINTS+num])); XSetForeground(dpy, gc, scene->color[C_BG_CMDWIN].pix); XFillRectangle(dpy, datawin, gc, i+1, j+1, w+6, fonth[0]+5); XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); XDrawRectangle(dpy, datawin, gc, i, j, w+8, fonth[0]+6); XDrawString(dpy, datawin, gc, i+4, j+fontasc[0]+3, msg[BEGIN_MOUSE_HINTS+num], strlen(msg[BEGIN_MOUSE_HINTS+num])); } void erase_mouse_hint(ImageLayout * scene, int num) { int i, j; i = w_buttons + 8; j = 5; XClearArea(dpy, datawin, i, j, datawin_width-i, fonth[0]+7, False); } int main(int argc, char **argv) { /* Global geometric structure */ ImageLayout *scene; /* misc variables */ XEvent ev; Time ev_time = 0; KeySym keysym = 0; char *string; struct stat buf; int i, j=0, l, m; int button_visit = -1, hint_shown = -1, wait_iter = 0; char str[1024]; /* Table for Mollweide function for (i=0; i<=1000; i++) { double d, e; d = e = (double)i*0.001; mollweide(&e); printf("%12.10f --> %12.10f %12.10f\n", d, e, log(1-e)/log(1-d)); } */ /* the default behaviour */ ps_viewer = strdup(PS_VIEWER); /* Should have gv installed !! */ im_viewer = strdup(IM_VIEWER); /* Should install ImageMagick !! */ html_viewer = strdup(HTML_VIEWER); /* Default is dillo */ svg_viewer = strdup(SVG_VIEWER); /* Default is inkscape */ svg_convert = strdup(SVG_CONVERT); /* Default is inkscape */ print_cmd = strdup(PRINT_CMD); /* BSD type printing system... */ editor_cmd = strdup(EDITOR); /* Default editor */ midi_cmd = strdup(MIDIPLAYER); /* Default editor */ *language = '\0'; bzero(feature_descr, 6*sizeof(char **)); cmd_string = strdup(""); expl_implicit = strdup(""); search_string = strdup(""); search_index = -1; /* the main struct for the data file */ scene = (ImageLayout *) malloc(sizeof(ImageLayout)); scene->backup = (ImageLayout *)NULL; scene->projection = SPHERICAL; scene->position = NULL; scene->num_positions = 0; scene->aspect = 1.0; scene->accuracy = 1.0; scene->width = 0; scene->height = 0; scene->pixmap = 0; scene->prepixmap = 0; scene->numdef = 0; scene->nummod = 0; scene->modpos = NULL; scene->numpoint = 0; scene->mempoint = NULL; bzero(&scene->rotation, sizeof(Matrix)); bzero(&scene->gopt, sizeof(GeomOptions)); bzero(&scene->ropt, sizeof(RenderOptions)); scene->gopt.zoom = 1.0; scene->gopt.desired_categories = 0xFFFFFFFF; /* default is all */ scene->gopt.desired_continents = 0xFFFFFFFF; /* default is all */ strcpy(scene->gopt.lineorder, lineorder0); scene->ropt.spacing_lat = 15.0; scene->ropt.spacing_lon = 15.0; scene->ropt.smartlabels = 1; /* default is +smartlabels */ memcpy(scene->ropt.mark_step, mark_step0, sizeof(mark_step0)); memcpy(scene->ropt.name_step, name_step0, sizeof(name_step0)); memcpy(scene->ropt.airport_mark, airport_mark0, sizeof(airport_mark0)); memcpy(scene->ropt.airport_size, airport_size0, sizeof(airport_size0)); memcpy(scene->ropt.peak_mark, peak_mark0, sizeof(peak_mark0)); memcpy(scene->ropt.peak_size, peak_size0, sizeof(peak_size0)); memcpy(scene->ropt.city_mark, city_mark0, sizeof(city_mark0)); memcpy(scene->ropt.city_size, city_size0, sizeof(city_size0)); strcpy(scene->ropt.city_filter, city_filter0); strcpy(scene->ropt.loc_filter, loc_filter0); *scene->mapfile = '\0'; *scene->locfile = '\0'; *scene->outfile = '\0'; *scene->macrofile = '\0'; *scene->theme = '\0'; list_flag_dirs(); for (i=0; i<=5; i++) { strcpy(scene->ropt.font[i], "6x13"); xfont[i] = NULL; } /* initial setting (which is to print nothing !!) */ for (i=0; i< C_ENDCOLOR; i++) scene->color[i].bool = INACTIVE; list_lang = list_languages(); /* read i18n file */ for (i=1; ircfile, RCFILE, 255); scene->rcfile[255] = '\0'; parse_rcfile(scene); /* Check whether user has specified its own rcfile(s) */ j = 0; for (i=1; ircfile = '\0'; ++j; continue; } strncpy(scene->rcfile, argv[i], 255); scene->rcfile[255] = '\0'; parse_rcfile(scene); ++j; } if (j==0) { /* if ~/.xrmaprc exists, use that file instead (for a rcfile) */ scene->rcfile[0] = '\0'; string = getenv("HOME"); if (string != NULL) { sprintf(scene->rcfile, "%s/.xrmaprc", string); buf.st_mode = 0; if (stat(scene->rcfile, &buf)) scene->rcfile[0] = '\0'; } if (scene->rcfile[0]) parse_rcfile(scene); } fix_features_description(scene); /* parse the command line options */ *cmd_string= '\0'; for (i=1; iprojection==SPHERICAL) scene->aspect = 1.0; /* set the window dimensions */ if (scene->width==0 && scene->height==0) { if (scene->projection==RECTANGULAR || scene->projection==CYLINDRICAL || scene->projection>=SINUSOIDAL) { scene->width = 1000; scene->height = 500 * scene->aspect; } else { scene->width = 672; scene->height = 672 * scene->aspect; } } else if (scene->height==0) { if (scene->projection==RECTANGULAR || scene->projection==CYLINDRICAL || scene->projection>=SINUSOIDAL) { scene->height = scene->width * (0.5*scene->aspect); } else { scene->height = scene->width * scene->aspect; } } else if (scene->width==0) { if (scene->projection==RECTANGULAR || scene->projection==CYLINDRICAL || scene->projection>=SINUSOIDAL) { scene->width = scene->height / (0.5*scene->aspect); } else { scene->width = scene->height / scene->aspect; } } /* set some default values */ set_radius(scene); check_spacing(scene); if (!*scene->mapfile) { strncpy(scene->mapfile, MAPFILE, 255); /* default */ scene->mapfile[255] = '\0'; } if (!*scene->locfile) { strncpy(scene->locfile, LOCFILE, 255); /* default */ scene->locfile[255] = '\0'; parse_locfile(scene); } /* We are now entering the GUI program */ runlevel = 1; /* Open X display */ dpy = XOpenDisplay(NULL); if (!dpy) { if (dump_format == DUMP_STAT) printf("ABORT\n"); fprintf(stderr, "%s\n", msg[COULDNT_OPEN_DEFAULT_X_DISPLAY]); exit(-1); } scr = DefaultScreen(dpy); color_depth = DefaultDepth(dpy, scr); bigendian = (ImageByteOrder(dpy) == MSBFirst); if (color_depth > 16) color_pad = 32; else if (color_depth > 8) color_pad = 16; else color_pad = 8; Root = RootWindow(dpy, scr); visual = DefaultVisual(dpy, scr); if (color_depth <= 8) color_table = (unsigned char *) malloc(256); else cmap = DefaultColormap(dpy, scr); /* Load X fonts */ for (i=0; i<=5; i++) { xfont[i] = XLoadQueryFont(dpy, scene->ropt.font[i]); if (xfont[i] == (XFontStruct *)NULL) { fprintf(stderr, msg[REPLACING_BY_DEFAULT_FONT],scene->ropt.font[i]); fprintf(stderr, "\n"); strcpy(scene->ropt.font[i], "fixed"); xfont[i] = XLoadQueryFont(dpy, scene->ropt.font[i]); } if (xfont[i] == (XFontStruct *)NULL) { fprintf(stderr, msg[CANT_OPEN_FONT], scene->ropt.font[i]); fprintf(stderr, "\n"); exit(1); } set_font_params(i); } /* get all colors from X colormap */ get_all_colors(scene); /* open the X windows */ mainwin = make_window(scene->width, scene->height); show_title(scene, mainwin); datawin_width = 634; datawin_height = 340; datawin = make_window(datawin_width, datawin_height); show_title(scene, datawin); flagwin_width = 720; flagwin_height = 480; flagwin = make_window(flagwin_width, flagwin_height); show_title(scene, flagwin); cmdwin_width = 634; cmdwin_height = cmdwin_height0; cmdwin = make_window(cmdwin_width, cmdwin_height); show_title(scene, cmdwin); explwin_width = 360; explwin_height = explwin_height0; explwin = make_window(explwin_width, explwin_height); show_title(scene, explwin); if (!datapix) datapix = xim2pix(readIMG(scene, PIXMAPPATH, datapix_name, 0, &scene->color[C_BG_TEXT])); if (!cmdpix) cmdpix = xim2pix(readIMG(scene, PIXMAPPATH, cmdpix_name, 0, &scene->color[C_BG_TEXT])); if (!explpix) explpix = xim2pix(readIMG(scene, PIXMAPPATH, explpix_name, 0, &scene->color[C_BG_TEXT])); set_auxil_win_background(scene); for (i=0; i<=2; i++) { if (butpix_name[i]) strcpy(str, butpix_name[i]); else sprintf(str, DEFAULTBUTTONS, i); butpix[i] = xim2pix(readIMG(scene, PIXMAPPATH, str, 0, &scene->color[C_BG_TEXT])); } get_button_dimensions(); if (dump_format!=DUMP_STAT && (img_output==OUT_NONE || preview>0.0)) XMapWindow(dpy, mainwin); create_GCs(scene); parse_theme(scene); if (!scene->backup) scene->backup = (ImageLayout *) malloc(sizeof(ImageLayout)); memcpy(scene->backup, scene, sizeof(ImageLayout)); /* generate the image */ if (start_menu && img_output == OUT_NONE) { image_init(scene); ((ImageLayout *)scene->backup)->pixmap = scene->pixmap; /* disturb a little bit the zoom value to force update in case 'activate' is run */ ((ImageLayout *)scene->backup)->gopt.zoom = scene->gopt.zoom * 1.000001; keysym = (KeySym) start_menu; start_menu = 0; goto startkey; } else { if (*search_string) { search_city(scene); if (num_found!=1) generate(scene); search_output(scene, 1); } else generate(scene); } /* quit after preview time if user only wants file output */ if (img_output != OUT_NONE) { if (preview>0.0) { usleep((int)(preview*1000000)); } exit(0); } /* check X events */ for (;;) { if (!XCheckIfEvent(dpy, &ev, evpred, (XPointer)0)) { usleep(20000); i = 0; if (datawin_on && button_visit>=0) { if (hint_shown != button_visit) { ++wait_iter; if (wait_iter>=20) { if (hint_shown >=0) erase_mouse_hint(scene, hint_shown); show_mouse_hint(scene, button_visit); hint_shown = button_visit; wait_iter = 0; } } } if (datawin_on && button_visit==-1) { if (hint_shown >=0) { erase_mouse_hint(scene, hint_shown); hint_shown = -1; } } if (time_count==0 && datawin_on && city_found>=0 && city_foundobj!='l') { i = locations[city_found]->tz; set_time(i, str); update_time(scene, str); } time_count = (time_count+1)%33; continue; } if (ev.type==EnterNotify || ev.type==LeaveNotify) { if (ev.xexpose.window == mainwin && but_main_pressed!=2) clear_mainwin_strips(scene); if (ev.xexpose.window == datawin) { show_modified_buttons(0, button_visit); erase_mouse_hint(scene, button_visit); button_visit = -1; hint_shown = -1; but_data_pressed = 0; } continue; } if (ev.type==ButtonRelease) but_main_pressed = 0; if (ev.type==ButtonPress) but_main_pressed = ev.xbutton.button; if (ev.xclient.message_type == wm_protocols && ev.xclient.format == 32 && ev.xclient.data.l[0] == wm_delete_window) { if (ev.xexpose.window == mainwin) { if (brief_menu==3) exit(0); brief_menu = 3; show_brief_menu(scene); } if (ev.xexpose.window == cmdwin) { close_cmdwin(scene); } if (ev.xexpose.window == datawin) { close_datawin(scene); } if (ev.xexpose.window == explwin) { close_explwin(scene); } if (ev.xexpose.window == flagwin) { close_flagwin(scene); } } if (ev.xexpose.window == flagwin) { if (ev.type == ButtonPress && ev.xbutton.button<=Button3) { XClearArea(dpy, flagwin, 10, 10, 200, (1+((num_flag_dirs+1)>>1))*(fonth[0]+12)+9, False); XSetForeground(dpy, gc, scene->color[C_FG_TEXT].pix); strcpy(str, msg[READJUST_WINDOW]); XDrawString(dpy, flagwin, gc, 32, 20+fontasc[0], str, strlen(str)); XDrawRectangle(dpy, flagwin, gc, 16, 17, 187, fonth[0]+6); for (i=0; i>1))*(fonth[0]+12), 90, fonth[0]+6); strcpy(str, flag_dir[i]); XDrawString(dpy, flagwin, gc, 40+95*(i&1), 20+fontasc[0]+(1+(i>>1))*(fonth[0]+12), str, strlen(str)); } XFlush(dpy); } if (ev.type == ButtonRelease && ev.xbutton.button<=Button3) { j = -2; for (i=0; i<=((num_flag_dirs+1)>>1); i++) if (ev.xbutton.x>=16 && ev.xbutton.x<=203 && ev.xbutton.y>=17+i*(fonth[0]+12) && ev.xbutton.y<=13+(i+1)*(fonth[0]+12)) { if (i==0) j = -1; else { j = 2*i-2; if (ev.xbutton.x>=113) j += 1; else if (ev.xbutton.x>=106) j = -2; } break; } if (j==-1) show_flagwin(scene, 1); else if (big_flag_image) show_flagwin(scene, 0); flag_viewer(j); } if (ev.type == KeyRelease) { char buffer[1]; XLookupString((XKeyEvent *)&ev, buffer, 1, &keysym, NULL); if (keysym == XK_equal || keysym == XK_KP_Equal) show_flagwin(scene, 1); } } if (ev.xexpose.window == explwin) switch(ev.type) { case LeaveNotify: but_expl_pressed &= ~2; break; case EnterNotify: but_expl_pressed |= 2; break; case MotionNotify: case ButtonPress: if (ev.type==ButtonPress && ev.xbutton.button<=Button3) but_expl_pressed = 1; case ButtonRelease: if (ev.type==ButtonRelease) { but_expl_pressed = 0; if (ev.xbutton.button==4) goto expl_up; if (ev.xbutton.button==5) goto expl_down; } if (ev.xbutton.y>=0 && ev.xbutton.y8*i*char_width && ev.xbutton.x<8*(i+1)*char_width) { j = i; break; } if (j==-1 && ev.xbutton.x>explwin_width-8*char_width) { close_explwin(); break; } if (j==0) { if (getenv("HOME")) { strcpy(expl_currdir, getenv("HOME")); strcat(expl_currdir, "/"); } } if (j==1) { strcpy(expl_currdir, SHAREDIR); strcat(expl_currdir, "/"); } if (j==2) { strcpy(expl_currdir, "/"); } if (j==3) { getcwd(expl_currdir, sizeof(expl_currdir)); strcat(expl_currdir, "/"); } if (j>=0 && j<=3) { free_dirlist(expl_dirtable); expl_dirtable = NULL; expl_shift = 0; show_explwin(scene, 0, 1); } } else if (ev.xbutton.y<2*(fonth[0]+8)) { if (ev.type!=ButtonRelease) break; expl_shift = 0; show_explwin(scene, 0, 1); } else { if (ev.xbutton.x>explwin_width-13 && ev.xbutton.x=explwin_height-12) { if (ev.type!=ButtonPress) break; goto expl_down; } else { if (ev.type==MotionNotify && but_expl_pressed!=1) break; expl_shift = ((ev.xbutton.y-2*fonth[0]-28)*expl_table_entries)/ (explwin_height-2*fonth[0]-40); if (expl_shift>=expl_table_entries-2) expl_shift = expl_table_entries-2; show_explwin(scene, 0, 2); } } else { if (ev.type!=ButtonRelease) break; show_explwin(scene, ev.xbutton.x, ev.xbutton.y); } } break; case KeyRelease: { char buffer[1]; XLookupString((XKeyEvent *)&ev, buffer, 1, &keysym, NULL); if (keysym==XK_Up || keysym == XK_Page_Up) { expl_up: if (expl_shift<=0) break; expl_shift -= expl_lines - 2; if (expl_shift<0) expl_shift = 0; show_explwin(scene, 0, 2); } else if (keysym==XK_Down || keysym == XK_Page_Down) { expl_down: if (expl_shift>=expl_table_entries - 3) break; expl_shift += expl_lines - 3; if (expl_shift>expl_table_entries - 3) expl_shift = expl_table_entries - 3; show_explwin(scene, 0, 2); } else if (keysym==XK_Escape) { close_explwin(scene); ev.xexpose.window = mainwin; XMapRaised(dpy, mainwin); XSetInputFocus(dpy, mainwin, RevertToPointerRoot, CurrentTime); } } break; default: break; } if (ev.xexpose.window == datawin) switch(ev.type) { case ButtonPress: case MotionNotify : if (ev.xbutton.button > Button3) break; j = 1; for (i=0; ii*w_button+3 && ev.xbutton.x<(i+1)*w_button && ev.xbutton.y>3 && ev.xbutton.y Button3) break; but_data_pressed = 0; show_modified_buttons(1, button_visit); erase_mouse_hint(scene, button_visit); button_visit = -1; hint_shown = -1; wait_iter = 0; show_mark(scene); if (city_found>=0 && locations[city_found]->obj=='l' && locations[city_found]->rank==-1) { if (ev.xbutton.x>5*w_button+3 && ev.xbutton.x<6*w_button && ev.xbutton.y>3 && ev.xbutton.y<24 ) { goto recenter; } break; } for (i=0; ii*w_button+3 && ev.xbutton.x<(i+1)*w_button && ev.xbutton.y>3 && ev.xbutton.y=0 && ( locations[city_found]->obj=='c' || locations[city_found]->obj=='a' || locations[city_found]->obj=='b' || locations[city_found]->obj=='p' || locations[city_found]->obj=='l')) { if (locations[city_found]->obj=='l') j = locations[city_found]->rank; else j = timezones[locations[city_found]->tz]->country; strcpy(code, countries[j]->code2); code[0] = tolower(code[0]); code[1] = tolower(code[1]); strcpy(cia_code, countries[j]->cia); j = 0; if (i==0) { factbook_retry: if (j==0) sprintf(path, "%s/%s-%s.txt", CIATEXTPATH, code, language); if (j==1) sprintf(path, "%s/%s-en.txt", CIATEXTPATH, code); if (j==2) sprintf(path, "%s/%s.txt", CIATEXTPATH, code); ++j; } else if (i==1) { html_retry: if (j==0) sprintf(path, "%s/%s-%s.html", CIAGEOSPATH, cia_code, language); if (j==1) sprintf(path, "%s/%s-en.html", CIAGEOSPATH, cia_code); if (j==2) sprintf(path, "%s/%s.html", CIAGEOSPATH, cia_code); ++j; } else if (i==2) { anthem_retry: if (j==0) sprintf(path, "%s/%s-%s.ant", ANTHEMPATH, code, language); if (j==1) sprintf(path, "%s/%s-en.ant", ANTHEMPATH, code); if (j==2) sprintf(path, "%s/%s.ant", ANTHEMPATH, code); ++j; } else if (i==3) { static char *suff[] = { "mid", "mp3", "ogg" }; music_retry: sprintf(path, "%s/%s.%s", HYMNPATH, code, suff[j]); ++j; } else if (i==4) { map_retry: if (j==0) { sprintf(path, "%s/%s.pdf", PDFMAPSPATH, code); sprintf(cmd, "%s %s &", ps_viewer, path); } if (j==1) { sprintf(path, "%s/%s-map.gif", CIAMAPSPATH, cia_code); sprintf(cmd, "%s %s &", im_viewer, path); } ++j; } else if (i==5) { goto recenter; } bzero(&buf, sizeof(buf)); buf.st_mode = 0; stat(path, &buf); if (!S_ISREG(buf.st_mode)) { if (i==0 && j<=2) goto factbook_retry; if (i==1 && j<=2) goto html_retry; if (i==2 && j<=2) goto anthem_retry; if (i==3 && j<=2) goto music_retry; if (i==4 && j<=2) goto map_retry; break; } if (i==1) { sprintf(cmd, "%s %s &", html_viewer, path); system(cmd); break; } if (i<=2) { secure_tmpnam(tmpname); strcat(tmpname, "_xrmap_"); strcat(tmpname, code); if (i==0) strcat(tmpname, ".txt"); else if (i==2) strcat(tmpname, ".ant"); ft = fopen(tmpname, "w"); if (ft) { if (data_text && *data_text) fprintf(ft, data_text); if (i==2) fprintf(ft, "%s\n\n", msg[NATIONAL_ANTHEM]); fclose(ft); sprintf(cmd, "( cat %s >> %s ; %s %s ; rm -f %s ) &", path, tmpname, editor_cmd, tmpname, tmpname); system(cmd); } break; } if (i==3) { sprintf(cmd, "%s %s &", midi_cmd, path); system(cmd); break; } if (i==4) { system(cmd); break; } } } if (ev.xbutton.button == 3) { recenter: if (city_found>=0 && city_foundgopt.xrot = locations[city_found]->lat; scene->gopt.yrot = locations[city_found]->lon; draw_win_string(scene, mainwin, msg[RECENTERING_TO_POINT], BOTTOM); generate(scene); show_mark(scene); city_shown = 1; break; } } if ((ev.xbutton.x>=4 && ev.xbutton.x<4+pixmap_width[0] && ev.xbutton.y>=h_button+4 && ev.xbutton.y=12+pixmap_width[0] && ev.xbutton.x<12+pixmap_width[0]+pixmap_width[1] && ev.xbutton.y>=h_button+4 && ev.xbutton.yobj=='l') { i = locations[city_found]->rank; if (i>=0) ptr = countries[i]->flags; } else { i = locations[city_found]->tz; if (i>=0) ptr = timezones[i]->flags; } if (ptr) { strncpy(path, ptr, 78); path[78] = '\0'; ptr = path; if ((ptrp = index(ptr, ','))) { *ptrp = '\0'; ptrp += 1; } if (ptrp && ev.xbutton.x>4+pixmap_width[0]) ptr = ptrp; if (flag_name && strcmp(ptr, flag_name)) { if (big_flag_image) XDestroyImage(big_flag_image); big_flag_image = NULL; free(flag_name); } flag_name = strdup(ptr); show_flagwin(scene, 1); break; } } break; case KeyPress: case KeyRelease: { char buffer[1]; XLookupString((XKeyEvent *)&ev, buffer, 1, &keysym, NULL); if (keysym==XK_k || keysym==XK_K) { close_datawin(scene); break; } ev.xexpose.window = mainwin; XMapRaised(dpy, mainwin); XSetInputFocus(dpy, mainwin, RevertToPointerRoot, CurrentTime); break; } default: break; } if (ev.xexpose.window == cmdwin) switch(ev.type) { case KeyPress : { char buffer[1]; XLookupString((XKeyEvent *) &ev, buffer, 1, &keysym, NULL); if (keysym == XK_Control_L || keysym == XK_Control_R ) { control_pressed = 1; } } break; case KeyRelease : { char buffer[1]; XLookupString((XKeyEvent *) &ev, buffer, 1, &keysym, NULL); /* printf("%d\n", keysym); */ convert_keysym(&keysym); if (keysym==0) break; if ((keysym==XK_k || keysym==XK_K) && !text_input_mode()) { close_datawin(scene); close_cmdwin(scene); break; } if (keysym==XK_Escape) { do_escape(scene); break; } if (keysym==XK_Return || keysym==XK_exclam) { do_activate(scene, keysym); break; } if (cmd_mode==MODE_MENU && cmd_type==M_MENU_START) { if (keysym==XK_d || keysym==XK_D || keysym==XK_f || keysym==XK_F || keysym==XK_h || keysym==XK_H || keysym==XK_n || keysym==XK_N || keysym==XK_c || keysym==XK_C || keysym==XK_o || keysym==XK_O || keysym==XK_q || keysym==XK_Q || keysym==XK_s || keysym==XK_S) { if (keysym==XK_h || keysym==XK_H) { cmd_mode = MODE_HELP; cmd_type = M_HELP_START; draw_win_cmd(scene, 1); break; } cmd_mode = MODE_RUN; cmd_type = M_RUN_START; goto startkey; } } if (!expert && keysym==XK_Up) { if (!click_input_mode()) break; if (cmd_mode==MODE_HELP && cmd_type==M_HELP_SHORTCUTS) { if (start_shortcut>0) --start_shortcut; draw_win_cmd(scene, 2); break; } l = line_clicked; if (l==-1) l = box_numitems; else if (l==1) { l = -1; line_clicked = -1; *cmd_string = '\0'; caret_pos = 0; } else --l; goto pre_do_click; } if (!expert && keysym==XK_Down) { if (!click_input_mode()) break; if (cmd_mode==MODE_HELP && cmd_type==M_HELP_SHORTCUTS) { ++start_shortcut; draw_win_cmd(scene, 2); break; } l = line_clicked; if (l==-1) l = 1; else { ++l; if (l>box_numitems) { l = -1; line_clicked = -1; *cmd_string = '\0'; caret_pos = 0; } } pre_do_click: if (cmd_mode==MODE_MENU && cmd_type==M_MENU_LIST) adjust_list(num_found, &l); if (cmd_mode==MODE_HELP && cmd_type==M_HELP_EDIT) adjust_list(scene->numpoint, &l); goto do_click; } if (!expert && keysym==XK_Tab) { if (cmd_mode==MODE_FILE) cmd_type = (cmd_type%M_FILE_SAVE)+1; else if (cmd_mode==MODE_OPTION) cmd_type = (cmd_type%M_OPTION_CAT)+1; else if (cmd_mode==MODE_COLOR) cmd_type = (cmd_type%M_COLOR_CIL)+1; if (cmd_mode==MODE_HELP) { cmd_type = (cmd_type%M_HELP_EDIT)+1; if (cmd_type==M_HELP_SHORTCUTS) start_shortcut = 0; } line_clicked = -1; draw_win_cmd(scene, 0); break; } if (!expert && keysym==XK_Page_Up) { if (cmd_type) { if (cmd_mode==MODE_MENU && cmd_type==M_MENU_LIST) cmd_type = M_MENU_SEARCH; else cmd_type = 0; } else { cmd_mode = MODE_MENU; cmd_type = M_MENU_START; } draw_win_cmd(scene, 0); break; } if (text_input_mode()) { if (control_pressed) { if (keysym==XK_space) { keysym = 31; goto specialchar; } if (keysym==XK_a || keysym==XK_A) caret_pos = 0; else if (keysym==XK_b || keysym==XK_B || keysym==XK_p || keysym==XK_P) { if (caret_pos>0) --caret_pos; } else if (keysym==XK_f || keysym==XK_F || keysym==XK_n || keysym==XK_N) { if (caret_pos0) --caret_pos; } else if (keysym==XK_Delete) { int l, m; l = strlen(cmd_string); if (caret_pos) { for (m=caret_pos-1; m=32 && keysym<=255) { int l, m; specialchar: if (cmd_string) l = strlen(cmd_string); else l = 0; cmd_string = (char *)realloc(cmd_string, l+2); cmd_killed_char = '\0'; for (m=l; m>caret_pos; m--) cmd_string[m] = cmd_string[m-1]; cmd_string[caret_pos] = keysym; cmd_string[l+1] = '\0'; ++caret_pos; } draw_win_string(scene, cmdwin, cmd_string, BOTTOM); } break; } break; case ButtonPress : if (ev.xbutton.button > Button3) break; line_pos = -1; expl_output = 0; if (cmd_mode && ev.xbutton.y<=fonth[0]+5) break; if (cmd_mode==MODE_MENU) break; if (cmd_mode && ev.xbutton.y>=cmdwin_height-fonth[0]-6) { if (text_input_mode()) do_caret(scene, ev.xbutton.x); break; } break; case ButtonRelease : expl_output = 0; if (ev.xbutton.button==2 && cmd_mode && text_input_mode() && ev.xbutton.y>=cmdwin_height-fonth[0]-6) { char *ptr; int i, l, lp; ptr = read_primary(); l = strlen(ptr); for (i=0; i=caret_pos; i--) cmd_string[i+l] = cmd_string[i]; for (i=0; i=cmdwin_height-fonth[0]-6) { char *ptr; int l, lp; l = caret_pos; do_caret(scene, ev.xbutton.x); if (caret_pos>l) lp = caret_pos; else { lp = l; l = caret_pos; } ptr = strdup(cmd_string+l); ptr[lp-l] = '\0'; write_primary(ptr); free(ptr); } if (ev.xbutton.button >= Button4 && cmd_mode == MODE_HELP && cmd_type == M_HELP_SHORTCUTS) { if (ev.xbutton.button == Button4) { if (start_shortcut>0) --start_shortcut; } if (ev.xbutton.button == Button5) { ++start_shortcut; } draw_win_cmd(scene, 2); break; } if (ev.xbutton.button >= Button4 && ((cmd_mode == MODE_MENU && cmd_type == M_MENU_LIST) || (cmd_mode == MODE_HELP && (cmd_type == M_HELP_EDIT || cmd_type == M_HELP_EXTRA)))) { if (ev.xbutton.button == Button4) { if (start_list>0) --start_list; } if (ev.xbutton.button == Button5) { int m; if (cmd_mode == MODE_MENU) m = num_found; else { if (cmd_type == M_HELP_EXTRA) m = num_doc; else m = scene->numpoint; } ++start_list; if (start_list + num_listed >= m) start_list = m - num_listed; if (start_list<0) start_list = 0; } draw_win_cmd(scene, 1); break; } if (ev.xbutton.button >= Button4) break; if (!expert && ev.xbutton.y<=fonth[0]+5) { if (ev.xbutton.x>=cmdwin_width-action_width) { brief_menu = 3; do_escape(scene); show_brief_menu(scene); break; } if (ev.xbutton.x>=cmdwin_width-2*action_width) { do_escape(scene); break; } if (ev.xbutton.x>=cmdwin_width-3*action_width) { do_activate(scene, XK_exclam); break; } cmd_mode = MODE_MENU; for (i=M_MENU_HELP; i>=1; i--) { if (ev.xbutton.x>= XTextWidth(xfont[0], labels_generalmenu, spacing_generalmenu*(i-1)-1)) break; } if (i==M_MENU_HELP) { cmd_mode = MODE_HELP; cmd_type = M_HELP_START; } if (i==M_MENU_FILE) { cmd_mode = MODE_FILE; cmd_type = M_FILE_START; } if (i==M_MENU_CMD) { cmd_mode = MODE_CMD; cmd_type = M_CMD_START; } if (i==M_MENU_SEARCH) { cmd_type = M_MENU_SEARCH; free(cmd_string); cmd_string = strdup(search_string); caret_pos = strlen(search_string); } if (i==M_MENU_OPTION) { cmd_mode = MODE_OPTION; cmd_type = M_OPTION_START; } if (i==M_MENU_COLOR) { cmd_mode = MODE_COLOR; cmd_type = M_COLOR_START; } if (i==M_MENU_HELP) { cmd_mode = MODE_HELP; cmd_type = M_HELP_START; } draw_win_cmd(scene, 0); break; } if (!expert && ev.xbutton.y>=fonth[0]+16 && ev.xbutton.y<=2*fonth[0]+21) { line_clicked = -1; *cmd_string = '\0'; caret_pos = 0; if (cmd_mode==MODE_FILE) { cmd_type = M_FILE_SAVE; for (i=M_FILE_SAVE; i>=1; i--) { if (ev.xbutton.x< XTextWidth(xfont[0], labels_filemenu, spacing_filemenu*i-1)) cmd_type = i; } if (cmd_type == M_FILE_SAVE) overwrite = 0; } if (cmd_mode==MODE_OPTION) { cmd_type = M_OPTION_CAT; for (i=M_OPTION_CAT; i>=1; i--) { if (ev.xbutton.x=1; i--) { if (ev.xbutton.x=1; i--) { if (ev.xbutton.xbox_y + box_numitems*box_spacing) ++start_shortcut; if (ev.xbutton.y>box_y + box_spacing && ev.xbutton.y0) --start_shortcut; } draw_win_cmd(scene, 2); break; } /* Click released on the bottom strip */ if (ev.xbutton.y>=cmdwin_height-fonth[0]-6) { if (point_shown) draw_win_cmd(scene, 0); else if (text_input_mode()) do_caret(scene, ev.xbutton.x); break; } /* Click released somewhere not on the top/bottom strips */ if (click_input_mode()) { l = -1; if (ev.xbutton.x>box_x && ev.xbutton.xbox_y+j*box_spacing && ev.xbutton.y=1 && l<=box_numitems) { if (cmd_mode==MODE_HELP && cmd_type==M_HELP_SHORTCUTS) { draw_win_cmd(scene, 1); break; } if (cmd_mode==MODE_HELP && cmd_type==M_HELP_DOC) { char cmd[256]; if (l==box_numitems) show_manual(); else { if (strstr(doc_descr[l-1], ".rc")) { sprintf(cmd, "xrmap -rcfile %s/%s &", DOCPATH, doc_descr[l-1]); } else if (strstr(doc_descr[l-1], ".png") || strstr(doc_descr[l-1], ".jpg") || strstr(doc_descr[l-1], ".gif")) { sprintf(cmd, "%s %s/%s &", im_viewer, DOCPATH, doc_descr[l-1]); } else { if (strncmp(editor_cmd, "emx", 3)) sprintf(cmd, "%s %s/%s &", editor_cmd, DOCPATH, doc_descr[l-1]); else sprintf(cmd, "%s -edit 0 %s/%s &", editor_cmd, DOCPATH, doc_descr[l-1]); } system(cmd); } line_clicked = l; draw_win_cmd(scene, 1); break; } if (cmd_mode==MODE_HELP && cmd_type==M_HELP_EXTRA) { char cmd[256]; if (start_list && l==1) { start_list -= (num_listed/2 - 1); if (start_list<0) start_list = 0; line_clicked = -1; draw_win_cmd(scene, 1); break; } if (start_list + num_listed < num_doc && l==num_listed) { start_list += (num_listed/2 - 1); line_clicked = -1; draw_win_cmd(scene, 1); break; } if (strncmp(editor_cmd, "emx", 3)) sprintf(cmd, "%s %s/%s &", editor_cmd, CIAEXTRAPATH, doc_descr[start_list+l-1]); else sprintf(cmd, "%s -edit 0 %s/%s &", editor_cmd, CIAEXTRAPATH, doc_descr[start_list+l-1]); system(cmd); line_clicked = l; draw_win_cmd(scene, 1); break; } if (cmd_mode==MODE_HELP && cmd_type==M_HELP_EDIT) { int level; line_clicked = l; if (click_truncated_list(l,scene->numpoint, &level)) { int i = l+start_list-1; write_point_primary(scene, i); show_mark(scene); } else line_clicked = -10; draw_win_cmd(scene, level); break; } if (line_clicked == l || (cmd_mode==MODE_MENU && cmd_type==M_MENU_LIST)) { int j=0; if (cmd_mode==MODE_FILE) { if (cmd_type==M_FILE_DATA) { if (l==1) sprintf(expl_currdir, "%s/rc/",SHAREDIR); if (l>=2 && l<=4) { getcwd(expl_currdir, 256); strcat(expl_currdir, "/"); } if (l==5) sprintf(expl_currdir, "%s/themes/",SHAREDIR); if (l==6) sprintf(expl_currdir, "%s/pixmaps/optional/", SHAREDIR); if (expl_dirtable) free_dirlist(expl_dirtable); expl_dirtable = NULL; expl_shift = 0; if (expl_implicit) free(expl_implicit); expl_implicit = strdup(expl_currdir); if (l==6) sprintf(expl_implicit,"%s/pixmaps/",SHAREDIR); expl_output = 1; show_explwin(scene, 0, 0); } if (cmd_type==M_FILE_PRINTCFG) { if (l==4) { if (ps_rot==0) ps_rot = 90; else if (ps_rot==90) ps_rot = -90; else if (ps_rot==-90) ps_rot = 0; cmd_string = (char *) realloc(cmd_string, 4); cmd_killed_char = '\0'; sprintf(cmd_string, "%d", ps_rot); caret_pos = strlen(cmd_string); } if (l==6) { ps_frame = 1-ps_frame; cmd_string = (char *) realloc(cmd_string, 2); cmd_string[0] = (ps_frame)? '+':'-'; cmd_string[1] = '\0'; cmd_killed_char = '\0'; } if (l==7) { ps_grayscale = 1-ps_grayscale; cmd_string = (char *) realloc(cmd_string, 2); cmd_string[0] = (ps_grayscale)? '+':'-'; cmd_string[1] = '\0'; cmd_killed_char = '\0'; } if (l==8) { im_compress = 1-im_compress; cmd_string = (char *) realloc(cmd_string, 2); cmd_string[0] = (im_compress)? '+':'-'; cmd_string[1] = '\0'; cmd_killed_char = '\0'; } if (l==9 && *scene->macrofile) { sprintf(str, "if [ ! -r %s ] ; " "then cat %s > %s ; fi", scene->macrofile, SHAREDIR"/postscript/private.ps", scene->macrofile); system(str); sprintf(str, "%s %s &", editor_cmd, scene->macrofile); system(str); } } if (cmd_type==M_FILE_SAVE) { if (line_clicked==1) { getcwd(expl_currdir, 256); strcat(expl_currdir, "/"); if (expl_dirtable) free_dirlist(expl_dirtable); expl_dirtable = NULL; expl_shift = 0; expl_output = 1; show_explwin(scene, 0, 0); } if (line_clicked==5) { draw_win_cmd(scene, 2); goto print_automatic; } do_activate(scene, XK_Return); break; } } if (cmd_mode==MODE_MENU) { if (cmd_type==M_MENU_SEARCH) { search_by = l; do_activate(scene, XK_Return); break; } if (cmd_type==M_MENU_LIST) { int level; if (click_truncated_list(l,num_found, &level)) { city_found = loc_pointer[start_list+l-1]; line_clicked = l; if (search_by==6) { search_index = start_list+l-1; memcpy(&scene->gopt, &scene->position[start_list+l-1].xrot, 4*sizeof(double)); if (datawin_on) show_datawin(scene, 1); draw_win_cmd(scene, level); break; } search_index = city_found; scene->gopt.xrot=locations[city_found]->lat; scene->gopt.yrot=locations[city_found]->lon; show_datawin(scene, 1); } draw_win_cmd(scene, level); break; } } if (cmd_mode==MODE_OPTION) { if (cmd_type==M_OPTION_PARAM) { if (l==1) { scene->projection = (scene->projection+1)%NUMPROJ; cmd_string = (char *) realloc(cmd_string, 3); cmd_killed_char = '\0'; visible = 1; sprintf(cmd_string, "%d", scene->projection); } if (l==NUM_PARAM-3) { scene->ropt.latcoord = (scene->ropt.latcoord + 1) % 3; scene->ropt.loncoord = scene->ropt.latcoord; cmd_string = (char *) realloc(cmd_string, 4); cmd_killed_char = '\0'; cmd_string[0] = get_grid_coordinates(scene->ropt.latcoord, 0); cmd_string[1] = get_grid_coordinates(scene->ropt.loncoord, 1); cmd_string[2] = '\0'; } if (l==NUM_PARAM-2) { dms = 1-dms; cmd_string[0] = (dms)? '+':'-'; cmd_string[1] = '\0'; update_auxil_windows(scene); } if (l==NUM_PARAM-1) { scene->gopt.transparent = 1-scene->gopt.transparent; cmd_string = (char *) realloc(cmd_string, 2); cmd_string[0] = (scene->gopt.transparent)? '+' : '-'; cmd_string[1] = '\0'; cmd_killed_char = '\0'; } if (l==NUM_PARAM) { secure = 1-secure; cmd_string = (char *) realloc(cmd_string, 2); cmd_string[0] = (secure)? '+' : '-'; cmd_string[1] = '\0'; cmd_killed_char = '\0'; } } if (cmd_type==M_OPTION_HIERARCHY) { if (l==NUM_HIERARCHY-3) { scene->ropt.smartlabels = 1-scene->ropt.smartlabels; cmd_string = (char *) realloc(cmd_string, 2); cmd_string[0] = (scene->ropt.smartlabels)? '+':'-'; cmd_string[1] = '\0'; cmd_killed_char = '\0'; } if (l==NUM_HIERARCHY-2) { scene->ropt.placetext = 1-scene->ropt.placetext; cmd_string = (char *) realloc(cmd_string, 2); cmd_string[0] = (scene->ropt.placetext)? '+':'-'; cmd_string[1] = '\0'; cmd_killed_char = '\0'; } if (l==NUM_HIERARCHY) { char *ptr = strstr (list_lang, language)+3; if (!ptr || ptr>=list_lang+strlen(list_lang)) ptr = list_lang; cmd_string = (char *) realloc(cmd_string, 4); strncpy(language, ptr, 2); language[2] = '\0'; strcpy(cmd_string, language); read_i18n_file(scene); fix_features_description(scene); draw_win_cmd(scene, 0); break; } } if (cmd_type==M_OPTION_MARKS) { switch(l) { case 1: rotate_value(scene, C_CITY_CIRCLE); break; case 2: rotate_value(scene,C_AIRPORT_SYMBOL); break; case 3: rotate_value(scene, C_OBSERV_SYMBOL); break; case 4: rotate_value(scene, C_PEAK_TRIANGLE); break; case 5: scene->color[C_LOC_LAND].bool = !scene->color[C_LOC_LAND].bool; break; case 6: scene->color[C_LOC_WATER].bool = !scene->color[C_LOC_WATER].bool; break; case 7: scene->color[C_LON_GRID].bool = !scene->color[C_LON_GRID].bool; break; case 8: scene->color[C_LAT_GRID].bool = !scene->color[C_LAT_GRID].bool; break; case 9: scene->color[C_MAIN_LINES].bool = !scene->color[C_MAIN_LINES].bool; break; case 10: scene->color[C_EARTH_CONTOUR].bool = !scene->color[C_EARTH_CONTOUR].bool; break; case 11: scene->color[C_BG_SKY].bool = !scene->color[C_BG_SKY].bool; break; case 12: scene->color[C_FG_STARS].bool = !scene->color[C_FG_STARS].bool; break; default: break; } cmd_string = realloc(cmd_string, 3); value2str(scene, l, cmd_string, 0); } if (cmd_type>=M_OPTION_CONTIN) { j = 1<<(l-1); } if (cmd_type==M_OPTION_CONTIN) { if (scene->gopt.desired_continents & j) { scene->gopt.desired_continents &= ~j; *cmd_string = '-'; } else { scene->gopt.desired_continents |= j; *cmd_string = '+'; } } if (cmd_type==M_OPTION_CAT) { if (scene->gopt.desired_categories & j) { scene->gopt.desired_categories &= ~j; *cmd_string = '-'; } else { scene->gopt.desired_categories |= j; *cmd_string = '+'; } } } if (cmd_mode==MODE_COLOR) { if (cmd_type>=M_COLOR_LABELS+(l==1)) { j = feature_index[cmd_type-1]+l-1; scene->color[j].bool = 1-scene->color[j].bool; *cmd_string = (scene->color[j].bool)? '+' : '-'; } } } else { if (cmd_mode==MODE_FILE && cmd_type==M_FILE_SAVE && line_clicked==1 && *cmd_string) strcpy(scene->outfile, cmd_string); line_clicked = l; if (cmd_mode==MODE_MENU && cmd_type==M_MENU_SEARCH) { search_by = l; draw_win_cmd(scene, 2); break; } value2str(scene, line_clicked, str, 0); l = strlen(str); cmd_string = (char *)realloc(cmd_string, l+2); strcpy(cmd_string, str); cmd_killed_char = '\0'; if (cmd_mode==MODE_OPTION && cmd_type==M_OPTION_HIERARCHY) { if (line_clicked==1) cmd_string[5] = '\0'; if (line_clicked==NUM_HIERARCHY) cmd_string[2] = '\0'; l = strlen(cmd_string); } caret_pos = l; } } draw_win_cmd(scene, 2); break; } if (cmd_mode==MODE_MENU) break; if (cmd_mode && ev.xbutton.y>=scene->height-fonth[0]-6) { do_caret(scene, ev.xbutton.x); break; } break; } if (ev.xexpose.window == mainwin) switch(ev.type) { case KeyPress : { char buffer[1]; XLookupString((XKeyEvent *) &ev, buffer, 1, &keysym, NULL); if (keysym == XK_Control_L || keysym == XK_Control_R ) { control_pressed = 1; } } break; case KeyRelease : { char buffer[1]; XLookupString((XKeyEvent *) &ev, buffer, 1, &keysym, NULL); startkey: convert_keysym(&keysym); if (brief_menu) { if (keysym == XK_Escape) brief_menu = 0; if ((brief_menu==1 || brief_menu==2) && keysym == XK_space) brief_menu = 3-brief_menu; if (brief_menu == 3 && keysym != XK_q && keysym != XK_Q) brief_menu = 0; if (brief_menu == 4) brief_menu = 0; } show_brief_menu(scene); if (keysym==0) break; else if (keysym==XK_Return) { exposed |= MAIN_WINDOW; } else if (keysym==XK_at) { if (!explwin_on) { getcwd(expl_currdir, sizeof(expl_currdir)); strcat(expl_currdir, "/"); open_explwin(scene); } } else if (keysym==XK_colon) { double fact; fact = 1.0; if (scene->gopt.zoom>1.0) fact = 1.0/(1.0+0.5*atan(scene->gopt.zoom)); sprintf(str, "earthview -h %d -lat %g %g -lon %g %g &", scene->height, scene->gopt.xrot - fact*90.0/scene->gopt.zoom, scene->gopt.xrot + fact*90.0/scene->gopt.zoom, scene->gopt.yrot - fact*180.0/scene->gopt.zoom, scene->gopt.yrot + fact*180.0/scene->gopt.zoom); system(str); } else if (keysym==XK_degree) { dms = 1-dms; } else if (keysym==XK_less) { parse_locfile(scene); list_flag_dirs(); generate(scene); show_mark(scene); } else if (keysym==XK_ampersand || keysym==XK_Print) { char name[256]; print_automatic: strcpy(name, scene->outfile); secure_tmpnam(scene->outfile); strcat(scene->outfile, "_xrmap_out.eps"); sprintf(str, msg[WRITING_IMAGE_TO_FILE], scene->outfile); draw_win_string(scene, mainwin, str, BOTTOM); if (cmd_mode == MODE_FILE && cmd_type==M_FILE_SAVE) { draw_win_string(scene, cmdwin, str, BOTTOM); } img_output = OUT_EPS; overwrite = 1; generate(scene); img_output = OUT_NONE; sprintf(str, "( %s %s ; rm -f %s ) &", ps_viewer, scene->outfile, scene->outfile); system(str); overwrite = 0; if (cmd_mode == MODE_FILE && cmd_type==M_FILE_SAVE) { draw_win_cmd(scene, 2); } else strcpy(scene->outfile, name); break; } else if (keysym==XK_Delete) { if (scene->num_positions>=2) { XYZPosition pos; i = scene->num_positions-1; pos = scene->position[i]; for (j=i; j>0; j--) scene->position[j] =scene->position[j-1]; scene->position[0] = pos; memcpy(&scene->gopt, &scene->position[i].xrot, 4*sizeof(double)); generate(scene); if (scene->position[i].loc>=0) { city_found = scene->position[i].loc; show_datawin(scene, 1); } break; } } else if (keysym==XK_q || keysym==XK_Q) { if (brief_menu == 3) exit(0); brief_menu = 3; show_brief_menu(scene); } else if (keysym==XK_d || keysym==XK_D) { normalize_size_cmdwin(); open_cmdwin(scene); break; } else if (keysym==XK_asterisk) edit_rc_output(scene); else if (keysym==XK_exclam) { cmdwin_height = fonth[0]+6; expert = 1; XResizeWindow(dpy, cmdwin, cmdwin_width, cmdwin_height); XMapRaised(dpy, cmdwin); XResizeWindow(dpy, cmdwin, cmdwin_width, cmdwin_height); cmd_mode = MODE_CMD; cmd_type = M_CMD_START; draw_win_cmd(scene, 0); } else if (keysym==XK_k || keysym==XK_K) { close_datawin(scene); break; } else if (keysym==XK_f || keysym==XK_F) { filemenu(scene); normalize_size_cmdwin(); draw_win_cmd(scene, 0); break; } #ifdef SEG_SCAN else if (keysym==XK_w || keysym==XK_W) { seg_scan(scene); } #endif else if (keysym==XK_o || keysym==XK_O) { cmd_mode = MODE_OPTION; cmd_type = M_OPTION_START; normalize_size_cmdwin(); draw_win_cmd(scene, 0); } else if (keysym==XK_c || keysym==XK_C) { cmd_mode = MODE_COLOR; cmd_type = M_COLOR_START; normalize_size_cmdwin(); draw_win_cmd(scene, 0); } else if (keysym==XK_n || keysym==XK_N) { cmd_mode = MODE_HELP; cmd_type = M_HELP_EDIT; start_list = 0; normalize_size_cmdwin(); draw_win_cmd(scene, 0); } else if (keysym==XK_s || keysym==XK_S) { cmd_mode = MODE_MENU; cmd_type = M_MENU_SEARCH; free(cmd_string); cmd_string = strdup(search_string); caret_pos = strlen(search_string); normalize_size_cmdwin(); draw_win_cmd(scene, 0); } else if (keysym==XK_m || keysym==XK_M || keysym==XK_Tab) { normalize_size_cmdwin(); if (cmdwin_on) { XMapRaised(dpy, cmdwin); } else { cmd_mode = MODE_MENU; cmd_type = M_MENU_START; draw_win_cmd(scene, 0); } } else if (keysym==XK_i || keysym==XK_I) rotate_generate(scene, C_CITY_CIRCLE, OBJECT_TYPE_CITIES); else if (keysym==XK_a || keysym==XK_A) rotate_generate(scene, C_AIRPORT_SYMBOL, OBJECT_TYPE_AIRPORTS); else if (keysym==XK_b || keysym==XK_B) rotate_generate(scene, C_OBSERV_SYMBOL, OBJECT_TYPE_OBSERVATORIES); else if (keysym==XK_p || keysym==XK_P) rotate_generate(scene, C_PEAK_TRIANGLE, OBJECT_TYPE_PEAKS); else if (keysym==XK_l || keysym==XK_L) { if (scene->color[C_LOC_LAND].bool==ON || scene->color[C_LOC_WATER].bool==ON) { scene->color[C_LOC_LAND].bool = OFF; scene->color[C_LOC_WATER].bool = OFF; regenerate_objects(scene, WITHOUT,OBJECT_TYPE_LOCATIONS); } else { scene->color[C_LOC_LAND].bool = ON; scene->color[C_LOC_WATER].bool = ON; regenerate_objects(scene, WITH, OBJECT_TYPE_LOCATIONS); } } else if (keysym==XK_e || keysym==XK_E) { if (scene->projection == SPHERICAL) { scene->color[C_EARTH_CONTOUR].bool = !scene->color[C_EARTH_CONTOUR].bool; if (scene->color[C_EARTH_CONTOUR].bool) regenerate_objects(scene, WITH, OBJECT_TYPE_EARTH_CONTOUR); else regenerate_objects(scene, WITHOUT, OBJECT_TYPE_EARTH_CONTOUR); } } else if (keysym==XK_g || keysym==XK_G) { if (scene->color[C_LAT_GRID].bool==ON || scene->color[C_LON_GRID].bool==ON) { int done = 0; if (scene->color[C_LAT_GRID].bool==ON && scene->ropt.latcoord == 0) { done = 1; scene->ropt.latcoord = 1; } if (scene->color[C_LON_GRID].bool==ON && scene->ropt.loncoord == 0) { done = 1; scene->ropt.loncoord = 1; } if (!done) { scene->ropt.latcoord = 0; scene->ropt.loncoord = 0; scene->color[C_MAIN_LINES].bool = OFF; scene->color[C_LAT_GRID].bool = OFF; scene->color[C_LON_GRID].bool = OFF; regenerate_objects(scene, WITHOUT, OBJECT_TYPE_GRIDLINES); } else regenerate_objects(scene, WITH, OBJECT_TYPE_GRIDLINES); } else { scene->color[C_MAIN_LINES].bool = ON; scene->color[C_LAT_GRID].bool = ON; scene->color[C_LON_GRID].bool = ON; regenerate_objects(scene, WITH, OBJECT_TYPE_GRIDLINES); } } else if (keysym==XK_t || keysym==XK_T) { scene->color[C_MAIN_LINES].bool = !scene->color[C_MAIN_LINES].bool; if (scene->color[C_MAIN_LINES].bool) regenerate_objects(scene, WITH, OBJECT_TYPE_TROPICS); else regenerate_objects(scene, WITHOUT, OBJECT_TYPE_TROPICS); } else if (keysym==XK_r || keysym==XK_R) { reverse = 1 - reverse; get_all_colors(scene); draw_win_string(scene, mainwin, msg[REVERSING_COLORS], BOTTOM); generate(scene); } else if (keysym==XK_plus) { draw_win_string(scene, mainwin, msg[ZOOMING_BY_SQRT2], BOTTOM); scene->gopt.zoom *= sqrt(2); if (scene->gopt.zoom>MAXZOOM) scene->gopt.zoom = MAXZOOM; generate(scene); } else if (keysym==XK_minus) { draw_win_string(scene, mainwin, msg[REDUCING_BY_SQRT2], BOTTOM); scene->gopt.zoom /= sqrt(2); if (scene->gopt.zoomgopt.zoom = MINZOOM; generate(scene); } else if (keysym==XK_Right) { scene->gopt.yrot += angle_inc(scene->gopt.zoom); sprintf(str, msg[MOVING_TO_LONGITUDE], scene->gopt.yrot); draw_win_string(scene, mainwin, str, BOTTOM); generate(scene); } else if (keysym==XK_Left) { scene->gopt.yrot -= angle_inc(scene->gopt.zoom); sprintf(str, msg[MOVING_TO_LONGITUDE], scene->gopt.yrot); draw_win_string(scene, mainwin, str, BOTTOM); generate(scene); } else if (keysym==XK_Up) { scene->gopt.xrot += angle_inc(scene->gopt.zoom); sprintf(str, msg[MOVING_TO_LATITUDE], scene->gopt.xrot); draw_win_string(scene, mainwin, str, BOTTOM); generate(scene); } else if (keysym==XK_Down) { scene->gopt.xrot -= angle_inc(scene->gopt.zoom); sprintf(str, msg[MOVING_TO_LATITUDE], scene->gopt.xrot); draw_win_string(scene, mainwin, str, BOTTOM); generate(scene); } else if (keysym==XK_Home) { scene->gopt.yrot -= 15.0; sprintf(str, msg[MOVING_TO_LONGITUDE], scene->gopt.yrot); draw_win_string(scene, mainwin, str, BOTTOM); generate(scene); } else if (keysym==XK_End) { scene->gopt.yrot += 15.0; sprintf(str, msg[MOVING_TO_LONGITUDE], scene->gopt.yrot); draw_win_string(scene, mainwin, str, BOTTOM); generate(scene); } else if (keysym==XK_Page_Up) { scene->gopt.xrot += 15.0; sprintf(str, msg[MOVING_TO_LATITUDE], scene->gopt.xrot); draw_win_string(scene, mainwin, str, BOTTOM); generate(scene); } else if (keysym==XK_Page_Down) { scene->gopt.xrot -= 15.0; sprintf(str, msg[MOVING_TO_LATITUDE], scene->gopt.xrot); draw_win_string(scene, mainwin, str, BOTTOM); generate(scene); } else if (keysym == XK_h || keysym == XK_H) show_manual(); else if (keysym == XK_v || keysym == XK_V) { show_version(scene, mainwin); } else if (keysym == XK_question) { sprintf(str, msg[ZOOM_AND_POSITION], scene->gopt.zoom, scene->aspect, scene->gopt.xrot, scene->gopt.yrot, scene->gopt.zrot); draw_win_string(scene, mainwin, str, TOP); } else if (keysym == XK_quotedbl) { cmd_mode = MODE_HELP; cmd_type = M_HELP_SHORTCUTS; normalize_size_cmdwin(); XMapRaised(dpy, cmdwin); line_clicked = -1; cmdwin_on = 1; draw_win_cmd(scene, 0); } else if (keysym != XK_Shift_L && keysym != XK_Shift_R ) { if (brief_menu==0) brief_menu = 1; show_brief_menu(scene); } } break; case ButtonPress : but_main_pressed = ev.xbutton.button; if (but_main_pressed!=2) show_point(scene, ev.xbutton.x, ev.xbutton.y, !secure); if (but_main_pressed==3) { mouse_x1 = mouse_x2 = ev.xbutton.x; mouse_y1 = mouse_y2 = ev.xbutton.y; maxmove = 0; } break; case ButtonRelease : but_main_pressed = 0; clear_mainwin_strips(scene); if (brief_menu) { int m = 0; if (brief_menu == 1) m = BEGIN_MAP_FEATURES - BEGIN_LIST_SHORTCUTS + 1; if (brief_menu == 2) m = END_MAP_FEATURES - BEGIN_MAP_FEATURES + 1; if (brief_menu == 3) m = 1; j = 0; for (i=1; i<=m; i++) { if (ev.xbutton.x>=30 && ev.xbutton.x<=91 && ev.xbutton.y>= i * (fonth[0]+12) + 20 && ev.xbutton.y<=(i+1)* (fonth[0]+12) + 13) j = i; } if (brief_menu==1 && j==1) { brief_menu = 3; show_brief_menu(scene); break; } if ((brief_menu==1 || brief_menu==2) && j==m) { brief_menu = 3-brief_menu; show_brief_menu(scene); break; } if (brief_menu==3 && j==1) exit(0); if (brief_menu==4) { brief_menu = 0; show_brief_menu(scene); break; } if (j>=1) { if (brief_menu==1) keysym = msg[BEGIN_LIST_SHORTCUTS+j-1][3]; if (brief_menu==2) keysym = msg[BEGIN_MAP_FEATURES+j-1][3]; brief_menu = 0; XClearWindow(dpy, mainwin); show_mark(scene); goto startkey; } if (brief_menu) { if (ev.xbutton.button==2) brief_menu = 3-brief_menu; else brief_menu = 0; } show_brief_menu(scene); break; } if (cmd_mode==MODE_HELP && cmd_type==M_HELP_EDIT && ev.xbutton.button==1) { double x, y; if (inverse_coord(scene, ev.xbutton.x, ev.xbutton.y, &x, &y)) { ++scene->numpoint; scene->mempoint = (double *) realloc(scene->mempoint, 2*scene->numpoint*sizeof(double)); scene->mempoint[2*scene->numpoint-2] = x; scene->mempoint[2*scene->numpoint-1] = y; line_clicked = scene->numpoint - start_list; } write_point_primary(scene, scene->numpoint-1); show_mark(scene); if (cmdwin_on) draw_win_cmd(scene, 1); } /* Button 2 released, raise the menu */ if (ev.xbutton.button==2) { if (brief_menu == 0) brief_menu = 1; else if (brief_menu <= 2) brief_menu = 3 - brief_menu; show_brief_menu(scene); } /* Button 3 released, recenter the map */ if (ev.xbutton.button==3) { double x, y; if (maxmove<=2) { if (inverse_coord(scene, ev.xbutton.x, ev.xbutton.y, &x, &y)) { scene->gopt.xrot = x; scene->gopt.yrot = y; draw_win_string(scene, mainwin, msg[RECENTERING_TO_POINT], BOTTOM); show_new_center(scene,ev.xbutton.x,ev.xbutton.y,7); generate(scene); } else XClearWindow(dpy, mainwin); } else { int u, v; double f, g; u = (mouse_x1+mouse_x2)/2; v = (mouse_y1+mouse_y2)/2; if (inverse_coord(scene, u, v, &x, &y)) { f=(1.0+abs(mouse_x2-mouse_x1))/(1.0+scene->width); g=(1.0+abs(mouse_y2-mouse_y1))/(1.0+scene->height); if (f/g<5.0 && g/f<5.0) { scene->gopt.xrot = x; scene->gopt.yrot = y; scene->gopt.zoom /= sqrt((f*f+g*g)*0.5); if (scene->gopt.zoom>MAXZOOM) scene->gopt.zoom = MAXZOOM; draw_win_string(scene, mainwin, msg[RECENTERING_TO_POINT],BOTTOM); show_new_center(scene, u, v, 7); generate(scene); } else XClearWindow(dpy, mainwin); } else XClearWindow(dpy, mainwin); } show_mark(scene); } break; /* User has moved the mouse */ case MotionNotify : if (brief_menu) break; if (but_main_pressed==1 || but_main_pressed==3) show_point(scene, ev.xbutton.x, ev.xbutton.y, 0); if (but_main_pressed==3) show_area_border(scene, ev.xbutton.x, ev.xbutton.y); break; } if (XPending(dpy)) continue; /* ConfigureNotify events that have been postponed */ if (notified & MAIN_WINDOW) { int x, y; unsigned int w, h; if (get_window_placement(mainwin, &x, &y, &w, &h) && (w!=scene->width || h!=scene->height) ) { sprintf(str, msg[RESIZING_WINDOW], w, h); scene->width = w; scene->height = h; draw_win_string(scene, mainwin, str, BOTTOM); set_radius(scene); generate(scene); exposed |= DATA_WINDOW; } } if (cmdwin_on && (notified & CMD_WINDOW)) { int x, y; unsigned int w, h; if (get_window_placement(cmdwin, &x, &y, &w, &h) && (w!=cmdwin_width || h!=cmdwin_height) ) { cmdwin_width = w; cmdwin_height = h; exposed |= CMD_WINDOW; } } if (datawin_on && (notified & DATA_WINDOW)) { int x, y; (void) get_window_placement(datawin, &x, &y, &datawin_width, &datawin_height); time_count = 0; exposed |= DATA_WINDOW; } if (explwin_on && (notified & EXPL_WINDOW)) { int x, y; unsigned int w, h; if (get_window_placement(explwin, &x, &y, &w, &h) && (w!=explwin_width || h!=explwin_height) ) { if (h<=6*fonth[0]+48) h = 6*fonth[0]+48; explwin_width = w; explwin_height = h; expl_shift = 0; exposed |= EXPL_WINDOW; } } if (notified & FLAG_WINDOW) { int x, y; unsigned int w, h; if (get_window_placement(flagwin, &x, &y, &w, &h) && (w!=flagwin_width || h!=flagwin_height) ) { if (big_flag_image) XDestroyImage(big_flag_image); big_flag_image = NULL; flagwin_width = w; flagwin_height = h; exposed |= FLAG_WINDOW; } } notified = 0; /* Expose events that have been postponed */ if (exposed & MAIN_WINDOW) { if (brief_menu>0) show_brief_menu(scene); show_mark(scene); } if (cmdwin_on && (exposed & CMD_WINDOW)) draw_win_cmd(scene, 0); if (datawin_on && (exposed & DATA_WINDOW)) show_datawin(scene, 0); if (explwin_on && (exposed & EXPL_WINDOW)) show_explwin(scene, 0, 0); if (flagwin_on && (exposed & FLAG_WINDOW)) show_flagwin(scene, 0); exposed = 0; } return 0; }