/* xrmap - vector based global map generating program
*
* Copyright (C) 2001-2003 Jean-Pierre Demailly <demailly@ujf-grenoble.fr>
* ftp://ftp.ac-grenoble.fr/ge/geosciences
*
* loosely derived from "rmap"
* Copyright (C) 2000 Reza Naima <reza@reza.net>
* 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 <sys/timeb.h> */
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/keysymdef.h>
#include <X11/keysym.h>
#include <X11/xpm.h>
#ifdef ZLIB
#include <zlib.h>
#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_type<M_FILE_SAVE)||
(cmd_mode==MODE_FILE && cmd_type==M_FILE_SAVE && line_clicked==1) ||
(cmd_mode==MODE_HELP && cmd_type==M_HELP_EDIT) ||
(cmd_mode==MODE_OPTION && cmd_type>M_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<l; i++) {
c = string[i];
if (c<='Z') {
if (c>='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<C_FG_TEXT) {
color.red = 65535 - exact.red;
color.green = 65535 - exact.green;
color.blue = 65535 - exact.blue;
if (color_depth <= 8) {
r = color.red >> 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; j<C_ENDCOLOR; j++) {
i = (j+C_BG_MAP) % C_ENDCOLOR;
if (scene->color[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 (position<BOTTOM/2) {
yt = (position-TOP)*(fonth[0]+16);
y0 = yt + fontasc[0] + 2;
} else {
yt = height - (BOTTOM-position)*(fonth[0]+4);
y0 = yt - xfont[0]->max_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; j<y+h; j++) {
mask = mask1;
skip = j*tb_width;
i = i1;
while (i<=i2) {
if (textboxes[i+skip] & mask) return;
if ((++i)<i2) mask = -1; else mask = mask2;
}
}
for (j=y; j<y+h; j++) {
mask = mask1;
skip = j*tb_width;
i = i1;
while(i<=i2) {
textboxes[i+skip] |= mask;
if ((++i)<i2) mask = -1; else mask = mask2;
}
}
}
XDrawString(dpy, scene->pixmap, 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; i<l-1; i++) if (text[i]=='\\' && text[i+1]=='n') {
text[i] = '\0';
ptr1 = text+i+2;
break;
}
if (s->ropt.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_pos<l &&
XTextWidth(xfont[0], cmd_string, caret_pos+1)<u-4) ++caret_pos;
draw_win_string(scene, cmdwin, cmd_string, BOTTOM);
XFlush(dpy);
}
void normalize_size_cmdwin()
{
if (cmdwin_height<=3*(fonth[0]+16)) {
cmdwin_height = cmdwin_height0;
XResizeWindow(dpy, cmdwin, cmdwin_width, cmdwin_height);
}
expert = 0;
}
void show_new_center(ImageLayout * scene, int u, int v, int wid)
{
XSetForeground(dpy, gc, scene->color[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<l; i++)
if (str[i]<'\040') str[i]='\040';
}
char * parse_item(char *str, int *num)
{
char *ptr0, *ptr, *ptrp;
char c;
int i;
if (!str) return NULL;
if (!*str) return NULL;
ptr0 = str;
while (*ptr0 && isspace(*ptr0)) ++ptr0;
ptr = index(ptr0, ',');
if (!ptr) ptr = index(ptr0, ' ');
if (!ptr) return NULL;
c = *ptr;
*ptr = '\0';
if (*ptr0>='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 && i<C_ENDCOLOR) {
if (scene->color[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; j<scene->numdef; 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; i<l-5; i++) str[i] = ptr[i+5];
str[l-5] = ',';
str[l-4] = '\0';
}
for (i=0; i<scene->numpoint; i++) {
sprintf(needle, ",%d,", i);
if (strstr(str, needle)) scene->mempoint[2*i] = 100.0;
}
j = 0;
for (i=0; i<scene->numpoint; 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<ret; i++) {
if (j>=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; i<j; i++) {
if (str[i] == '%') {
str[i] = '\0';
j = i;
break;
}
}
/* remove trailing blank characters */
while (j>0 && 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, "<colors>", 8))
parselevel = 0;
else
if (!strncasecmp(str, "<parameters>", 12))
parselevel = 1;
else
if (!strncasecmp(str, "<defines>", 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)<n || 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; i<strlen(scene->gopt.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<END_USAGE; i++)
printf(" %s\n", msg[i]);
printf("\n");
for (i=BEGIN_LIST_PARAMETERS; i<END_LIST_PARAMETERS; i++) {
l = strlen(msg[i])-2;
if (msg[i][l]=='%' && msg[i][l+1]=='d')
sprintf(msg[i]+l, "%d", C_ENDCOLOR-1);
printf(" %s\n", msg[i]);
}
}
int set_proj(char *s)
{
int run;
int projection;
run = runlevel;
runlevel = 1;
visible = 1;
if (!strpcmp(s, "spherical", -3))
projection = SPHERICAL;
else
if (!strpcmp(s, "rectangular", -3))
projection = RECTANGULAR;
else
if (!strpcmp(s, "cylindrical", -3))
projection = CYLINDRICAL;
else
if (!strpcmp(s, "mercator", -3))
projection = MERCATOR;
else
if (!strpcmp(s, "miller", -3))
projection = MILLER;
else
if (!strpcmp(s, "sinusoidal", -3))
projection = SINUSOIDAL;
else
if (!strpcmp(s, "elliptic", -3))
projection = ELLIPTIC;
else
if (!strpcmp(s, "mollweide", -3))
projection = MOLLWEIDE;
else {
projection = atoi(s);
if (projection<SPHERICAL || projection>=NUMPROJ)
projection = SPHERICAL;
}
runlevel = run;
return projection;
}
void free_countries()
{
int i;
for (i=0; i<numcountry; i++) {
free(countries[i]->name);
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; i<numtz; i++) {
free(timezones[i]->code);
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; i<numloc; i++) {
if (locations[i]->name) 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; i<numloc; i++) {
if (locations[i]->obj==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; i<n; i++)
rank[order[i]] = i;
for (i=0; i<numcountry; i++)
minrank[i] = numloc;
if (step==0 && mode!='p') {
for (i=0; i<numloc; i++)
if (locations[i]->obj==mode) {
locations[i]->worldrank = rank[i]+1;
}
}
if (step==1) {
for (i=0; i<numloc; i++) {
if (locations[i]->obj==mode) {
j = timezones[locations[i]->tz]->continent;
if (rank[i]<minrank[j]) minrank[j] = rank[i];
}
}
for (i=0; i<numloc; i++) {
if (locations[i]->obj==mode) {
j = timezones[locations[i]->tz]->continent;
locations[i]->contrank = rank[i]-minrank[j]+1;
}
}
}
if (step==2) {
for (i=0; i<numloc; i++) {
if (locations[i]->obj==mode) {
j = timezones[locations[i]->tz]->country;
if (rank[i]<minrank[j]) minrank[j] = rank[i];
}
}
for (i=0; i<numloc; i++) {
if (locations[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; i<l; i++) {
if (str[i]=='\\') {
++i;
if (str[i]=='n') {
str[j] = ' ';
++j;
}
} else {
str[j] = str[i];
++j;
}
}
str[j] = '\0';
}
/*
int closest_locality(double x, double y)
{
double dist, distp;
int i, i0;
dist = 1.0E9;
i0 = -1;
for (i=0; i<numloc; i++)
if (locations[i]->obj=='c') {
distp = fabs(locations[i]->lat-x)+fabs(locations[i]->lon-y);
if (distp<dist) {
i0 = i;
dist = distp;
}
} else break;
return i0;
}
j = closest_locality(locations[numloc]->lat, 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, "<reset_countries>", 17)) {
free_countries();
continue;
}
if (!strncmp(str, "<reset_TZ>", 10)) {
free_TZ();
continue;
}
if (!strncmp(str, "<reset_locations>", 17)) {
free_locations();
continue;
}
if (!strncmp(str, "<reset_preselected>", 19)) {
free_preselected();
continue;
}
if (!strncmp(str, "<countries>", 11)) {
datatype = T_COUNTRIES;
numfields = 12;
continue;
}
if (!strncmp(str, "<timezones>", 11)) {
datatype = T_TIMEZONES;
numfields = 6;
continue;
}
if (!strncmp(str, "<cities>", 8)) {
datatype = T_CITIES;
itz = 0;
numfields = 11;
continue;
}
if (!strncmp(str, "<airports>", 10)) {
datatype = T_AIRPORTS;
itz = 0;
numfields = 8;
continue;
}
if (!strncmp(str, "<observatories>", 15)) {
datatype = T_OBSERVATORIES;
itz = 0;
numfields = 6;
continue;
}
if (!strncmp(str, "<peaks>", 7)) {
datatype = T_PEAKS;
itz = 0;
numfields = 9;
continue;
}
if (!strncmp(str, "<locations>", 11)) {
datatype = T_LOCATIONS;
numfields = 8;
continue;
}
if (!strncmp(str, "<preselected>", 13)) {
datatype = T_PRESELECTED;
numfields = 3;
continue;
}
if (datatype==T_COUNTRIES && !strncmp(str, "</countries>", 12)) {
datatype = T_NONE;
numfields = 0;
continue;
}
if (datatype==T_TIMEZONES && !strncmp(str, "</timezones>", 12)) {
datatype = T_NONE;
numfields = 0;
continue;
}
if (datatype==T_CITIES && !strncmp(str, "</cities>", 9)) {
datatype = T_NONE;
numfields = 0;
continue;
}
if (datatype==T_AIRPORTS && !strncmp(str, "</airports>", 11)) {
datatype = T_NONE;
numfields = 0;
continue;
}
if (datatype==T_OBSERVATORIES &&
!strncmp(str, "</observatories>", 16)) {
datatype = T_NONE;
numfields = 0;
continue;
}
if (datatype==T_PEAKS && !strncmp(str, "</peaks>", 8)) {
datatype = T_NONE;
numfields = 0;
continue;
}
if (datatype==T_LOCATIONS && !strncmp(str, "</locations>", 12)) {
datatype = T_NONE;
numfields = 0;
continue;
}
if (datatype==T_PRESELECTED &&
!strncmp(str, "</preselected>", 14)) {
datatype = T_NONE;
numfields = 0;
continue;
}
}
bool = 0;
for (i=0; i<numfields; i++) {
while (*str && isspace(*str)) ++str;
ptr = str;
while (*ptr && *ptr!='|') ++ptr;
if (!*ptr && i<numfields-1) bool=1;
*ptr = '\0';
ptrp = ptr+1;
--ptr;
while(isspace(*ptr)) { *ptr = '\0'; --ptr; }
strcpy(field[i], str);
str = ptrp;
}
if (bool) {
fprintf(stderr, msg[FIELD_MISSING], field[0], sect[datatype]);
fprintf(stderr, "\n");
continue;
}
if (datatype==T_COUNTRIES) {
i = (field[0][0]-'A')*26+(field[0][1]-'A');
country_table[i] = numcountry;
countries = realloc(countries,
(numcountry+1)*sizeof(Country *));
countries[numcountry] = malloc(sizeof(Country));
strcpy(countries[numcountry]->code2, 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; i<numtz; i++) {
j = (i+itz)%numtz;
if (!strcmp(field[0], timezones[j]->code)) {
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; i<numtz; i++) {
j = (i+itz)%numtz;
if (!strcmp(field[0], timezones[j]->code)) {
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; i<numtz; i++) {
j = (i+itz)%numtz;
if (!strcmp(field[0], timezones[j]->code)) {
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; i<numtz; i++) {
j = (i+itz)%numtz;
if (!strcmp(field[0], timezones[j]->code)) {
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<strlen(field[0]); i++) {
c = field[0][i];
if (c=='-') c=' ';
if (c>='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; i<numloc; i++) {
if (fabs(locations[i]->lat-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; i<numloc; i++) {
if (locations[i]->alt<=-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<num_msg; i++) free(msg[i]);
free(msg);
msg = NULL;
}
num_msg = 0;
setup_change |= LANG_CHANGE;
while ((ptr = fgets(buf, 510, fd))) {
if (!strncmp(ptr, "#END_OF_I18N_FILE", 17)) break;
if (*ptr=='#') continue;
msg = (char **) realloc(msg, (num_msg+1)*sizeof(char *));
l = strlen(ptr)-1;
if (ptr[l]=='\n') {
ptr[l] = '\0';
--l;
}
while(l>=0 && isspace(ptr[l])) {
ptr[l] = '\0';
--l;
}
if (l<0) continue;
msg[num_msg] = strdup(ptr);
++num_msg;
}
fclose(fd);
if (num_msg<END_OF_I18N_FILE) {
fprintf(stderr, "Language dialog file %s incomplete !!\n", i18n_file);
if (!strstr(i18n_file, "xrmap_msg.en")) goto retry;
exit(-1);
}
n = END_LABELS_GENERALMENU-BEGIN_LABELS_GENERALMENU;
spacing_generalmenu = atoi(msg[SPACING_GENERALMENU]);
l = n * spacing_generalmenu + 20;
if (labels_generalmenu) free(labels_generalmenu);
labels_generalmenu =
(char *)malloc((l+1) * sizeof(char));
for (i=0; i<l; i++) labels_generalmenu[i] = ' ';
labels_generalmenu[l] = '\0';
for (i=0; i<n; i++) {
ptr = msg[BEGIN_LABELS_GENERALMENU+i];
for (j=0; j<strlen(ptr); j++)
labels_generalmenu[i*spacing_generalmenu+j] = ptr[j];
}
n = END_LABELS_FILEMENU-BEGIN_LABELS_FILEMENU;
spacing_filemenu = atoi(msg[SPACING_FILEMENU]);
l = n * spacing_filemenu + 20;
if (labels_filemenu) free(labels_filemenu);
labels_filemenu =
(char *)malloc((l+1) * sizeof(char));
for (i=0; i<l; i++) labels_filemenu[i] = ' ';
labels_filemenu[l] = '\0';
for (i=0; i<n; i++) {
ptr = msg[BEGIN_LABELS_FILEMENU+i];
for (j=0; j<strlen(ptr); j++)
labels_filemenu[i*spacing_filemenu+j] = ptr[j];
}
n = END_LABELS_OPTIONMENU-BEGIN_LABELS_OPTIONMENU;
spacing_optionmenu = atoi(msg[SPACING_OPTIONMENU]);
l = n * spacing_optionmenu + 20;
if (labels_optionmenu) free(labels_optionmenu);
labels_optionmenu =
(char *)malloc((l+1) * sizeof(char));
for (i=0; i<l; i++) labels_optionmenu[i] = ' ';
labels_optionmenu[l] = '\0';
for (i=0; i<n; i++) {
ptr = msg[BEGIN_LABELS_OPTIONMENU+i];
for (j=0; j<strlen(ptr); j++)
labels_optionmenu[i*spacing_optionmenu+j] = ptr[j];
}
n = END_LABELS_COLORMENU-BEGIN_LABELS_COLORMENU;
spacing_colormenu = atoi(msg[SPACING_COLORMENU]);
l = n * spacing_colormenu + 20;
if (labels_colormenu) free(labels_colormenu);
labels_colormenu =
(char *)malloc((l+1) * sizeof(char));
for (i=0; i<l; i++) labels_colormenu[i] = ' ';
labels_colormenu[l] = '\0';
for (i=0; i<n; i++) {
ptr = msg[BEGIN_LABELS_COLORMENU+i];
for (j=0; j<strlen(ptr); j++)
labels_colormenu[i*spacing_colormenu+j] = ptr[j];
}
n = END_LABELS_HELPMENU-BEGIN_LABELS_HELPMENU;
spacing_helpmenu = atoi(msg[SPACING_HELPMENU]);
l = n * spacing_helpmenu + 20;
if (labels_helpmenu) free(labels_helpmenu);
labels_helpmenu =
(char *)malloc((l+1) * sizeof(char));
for (i=0; i<l; i++) labels_helpmenu[i] = ' ';
labels_helpmenu[l] = '\0';
for (i=0; i<n; i++) {
ptr = msg[BEGIN_LABELS_HELPMENU+i];
for (j=0; j<strlen(ptr); j++)
labels_helpmenu[i*spacing_helpmenu+j] = ptr[j];
}
l = END_PROJTYPES - BEGIN_PROJTYPES;
if (projtype) free(projtype);
projtype = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) projtype[i] = msg[BEGIN_PROJTYPES+i];
l = END_ITEMTYPES - BEGIN_ITEMTYPES;
if (itemtype) free(itemtype);
itemtype = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) itemtype[i] = msg[BEGIN_ITEMTYPES+i];
l = END_WINTITLE_DESCRIPTION - BEGIN_WINTITLE_DESCRIPTION;
if (wintitle_descr) free(wintitle_descr);
wintitle_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) wintitle_descr[i] = msg[BEGIN_WINTITLE_DESCRIPTION+i];
l = END_DATAFILE_DESCRIPTION - BEGIN_DATAFILE_DESCRIPTION;
if (datafile_descr) free(datafile_descr);
datafile_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) datafile_descr[i] = msg[BEGIN_DATAFILE_DESCRIPTION+i];
l = END_EXTERNAL_DESCRIPTION - BEGIN_EXTERNAL_DESCRIPTION;
if (external_descr) free(external_descr);
external_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) external_descr[i] = msg[BEGIN_EXTERNAL_DESCRIPTION+i];
l = END_PRINTCFG_DESCRIPTION - BEGIN_PRINTCFG_DESCRIPTION;
if (printcfg_descr) free(printcfg_descr);
printcfg_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) printcfg_descr[i] = msg[BEGIN_PRINTCFG_DESCRIPTION+i];
l = END_SAVE_DESCRIPTION - BEGIN_SAVE_DESCRIPTION;
if (save_descr) free(save_descr);
save_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) save_descr[i] = msg[BEGIN_SAVE_DESCRIPTION+i];
l = END_SEARCHBY_DESCRIPTION - BEGIN_SEARCHBY_DESCRIPTION;
if (searchby_descr) free(searchby_descr);
searchby_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) searchby_descr[i] = msg[BEGIN_SEARCHBY_DESCRIPTION+i];
l = END_PARAMETER_DESCRIPTION - BEGIN_PARAMETER_DESCRIPTION;
if (parameter_descr) free(parameter_descr);
parameter_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) parameter_descr[i] = msg[BEGIN_PARAMETER_DESCRIPTION+i];
l = END_HIERARCHY_DESCRIPTION - BEGIN_HIERARCHY_DESCRIPTION;
if (display_descr) free(display_descr);
display_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) display_descr[i] = msg[BEGIN_HIERARCHY_DESCRIPTION+i];
l = END_FONT_DESCRIPTION - BEGIN_FONT_DESCRIPTION;
if (font_descr) free(font_descr);
font_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) font_descr[i] = msg[BEGIN_FONT_DESCRIPTION+i];
l = END_MARKS_DESCRIPTION - BEGIN_MARKS_DESCRIPTION;
if (marks_descr) free(marks_descr);
marks_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) marks_descr[i] = msg[BEGIN_MARKS_DESCRIPTION+i];
l = END_CONTINENT_DESCRIPTION - BEGIN_CONTINENT_DESCRIPTION;
if (continent_descr) free(continent_descr);
continent_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) continent_descr[i] = msg[BEGIN_CONTINENT_DESCRIPTION+i];
l = END_CATEGORY_DESCRIPTION - BEGIN_CATEGORY_DESCRIPTION;
if (category_descr) free(category_descr);
category_descr = (char **)malloc(l*sizeof(char *));
for (i=0; i<l; i++) category_descr[i] = msg[BEGIN_CATEGORY_DESCRIPTION+i];
for (i=BEGIN_COLOR_DESCRIPTION; i<END_COLOR_DESCRIPTION; i++) {
ptr = msg[i];
ptr[2] = '\0';
l = atoi(ptr);
if (l>=0 && l<C_ENDCOLOR)
scene->color[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;j<strlen(str);j++) {
ch = toupper(str[j]);
if (index(scene->ropt.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;j<strlen(str);j++) {
ch = toupper(str[j]);
if (index(scene->ropt.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.zoom<MINZOOM) goto error;
if (scene->gopt.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; i<scene->num_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; y<ximage->height; y++)
for (x=0; x<ximage->width; 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; y<ximage->height; y++)
for (x=0; x<ximage->width; 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<colors>\n");
for (i=0; i<C_ENDCOLOR; i++) {
sprintf(str, "%02d %c %s\n", i,
((scene->color[i].bool)? '+':'-'),
scene->color[i].name);
print_string(str);
}
print_string("\n<parameters>\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<defines>\n");
for (i=0; i<scene->numdef; i++) {
print_string(scene->def[i]+1);
print_string("\n");
}
if (scene->numpoint) {
print_string("input");
j = dms;
dms = -1;
for (i=0; i<scene->numpoint; 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; j<scene->height - 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; i<scene->width - 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<<timezones[i]->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<bits[0]; j++) {
if (pt.coord[Y]-space+j >= s->height) break;
u = bits[j+1];
for (i=0; i<bits[0]; i++) {
if (u&1)
draw_pixel(s, x-space+i, y-space+j, pix);
u = u>>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; i<num_flag_dirs; i++) {
if (strstr(name, flag_formats[i])) { j = i; break; }
}
image = readIMG(scene, NULL, name, h, &scene->color[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; i<strlen(name); i++)
if (name[i]=='\037') name[i] = ' ';
if (str) free(str);
pt = project(scene, spher2cart(scene, spt));
draw_string(scene, &pt, name, scene->currentfont, 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; i<npoints; i++) {
sprintf(line, "%d %d l\n",
points[i].x, scene->height-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<strlen(search_string); i++)
if (search_string[i]=='\037') search_string[i] = ' ';
if (mode>=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; j<scene->height; j++) {
if (j<j1 || j>j2)
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; i<scene->width; i++) {
if (i>=i1 && i<i2)
draw_pixel(scene, i, j, bg);
else {
if ((i<i1-2 || i>i2+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; i<C_ENDCOLOR; i++) {
sprintf(line, "/c%d {%.4f %.4f %.4f RGB} def\n", i,
scene->color[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<C_ENDCOLOR; i++) {
lw = 0.5;
if (i==0) lw = 0.8;
if (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<<i) & scene->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<<k) & scene->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; j<n; j++) {
dxp = epsx * ((dx*(j+1))/n - (dx*j)/n);
dyp = epsy * ((dy*(j+1))/n - (dy*j)/n);
i = 10 + 2 * (nstrokes-n+j);
(*seg)[i] = (char)(dxp&255);
(*seg)[i+1] = (char)(dyp&255);
}
}
}
}
}
if (!arc_file) return;
i0 = -1;
if (arc_numseg) {
for (u=0; u<140; u++) {
if (check_cat_and_cont(scene, u)) {
for (i=0; i<arc_numseg[u]; i++) {
pix = scene->color[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; j<nstrokes; j++) {
k = 10+2*j;
xi = xi + (int)((signed char)ptr[k]);
yi = yi + (int)((signed char)ptr[++k]);
pt1 = pt2;
sp.sph[LONGITUDE] = ((double)xi)/3600.00;
sp.sph[LATITUDE] = ((double)yi)/3600.00;
if (arc_search && i!=i0) {
if (fabs(sp.sph[LONGITUDE]-arc_x)+
fabs(sp.sph[LATITUDE]-arc_y)<0.05) {
pix = scene->color[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<seg_nummarked; i++) {
j = seg_specified[i];
if (j>=0 && j<numseg) seg_marked[j] = 1;
}
}
}
}
#endif /* SEG_SELECT */
void dump_arcs(ImageLayout *scene)
{
FILE *fd;
char * seg;
char magic[16];
char filename[280];
int mem_numseg[140];
int i, j, k, u, numseg, maxlength, nstrokes, bool_write;
int xi, yi, minlong, maxlong, minlat, maxlat;
int index1 = 0, index2 = 0;
int address0, address1, address2, count = 0;
int total_numseg, total_address0, total_address2;
if (!dump_file) return;
if (dump_format != DUMP_ASCII) dump_split = 0;
fd = NULL;
if (!strcasecmp(dump_file, "-")) {
if (dump_split) {
fprintf(stderr, "%s\n", msg[CANNOT_SPLIT_STDOUT_OUTPUT]);
dump_split = 0;
}
fd = stdout;
} else
if (!dump_split) {
fd = fopen(dump_file, "w");
if (!fd) warning_output(dump_file);
}
/* Compute index table and maxlength of segments */
if (use_memory)
numseg = str4toint(&header->index[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; i<index2; i++) {
address1 = address2;
address2 = str4toint(segment_index[i].address);
#ifdef SEG_SELECT
if (!seg_select(i)) {
--j;
continue;
}
#endif
nstrokes = (address2-address1-6)/2;
if (nstrokes>maxlength) maxlength = nstrokes;
}
mem_numseg[u] = j;
}
if (arc_numseg) {
for (i=0; i<arc_numseg[u]; i++) {
seg = arc_index[u][i];
nstrokes = str4toint(seg);
if (nstrokes>maxlength) 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; i<index2; i++) {
address1 = address2;
address2 = str4toint(segment_index[i].address);
#ifdef SEG_SELECT
if (!seg_select(i)) continue;
#endif
nstrokes = (address2-address1-6)/2;
seg = &fullmap_buffer[address1 - address0];
xi = str3toint(seg);
yi = str3toint(seg+3);
fprintf(fd, "new = %d\n", k);
fprintf(fd, dump_precision,
((double)xi)/3600.0, ((double)yi)/3600.0);
++k;
for (j=0; j<nstrokes; j++) {
xi = xi + (int)((signed char)seg[6+2*j]);
yi = yi + (int)((signed char)seg[7+2*j]);
fprintf(fd, dump_precision,
((double)xi)/3600.0, ((double)yi)/3600.0);
}
}
}
if (arc_numseg) {
if (arc_numseg[u]>0 && !bool_write) {
fprintf(fd, "\n%%%% %s/%d\n", continent_name[u/28], u%28);
fprintf(fd, "typ = %d\n", u);
}
for (i=0; i<arc_numseg[u]; i++) {
seg = arc_index[u][i];
nstrokes = str4toint(seg);
xi = str3toint(seg+4);
yi = str3toint(seg+7);
fprintf(fd, "new = %d\n%.5f %.5f\n", count,
((double)xi)/3600.0, ((double)yi)/3600.0);
++count;
for (j=0; j<nstrokes; j++) {
xi = xi + (int)((signed char)seg[10+2*j]);
yi = yi + (int)((signed char)seg[11+2*j]);
fprintf(fd, "%.5f %.5f\n",
((double)xi)/3600.0, ((double)yi)/3600.0);
}
}
}
}
fprintf(fd, "end\n\n");
goto dump_finish;
}
/* This is the DUMP_JPD case */
/* Write Magic header (12 bytes) + maxlength (4 bytes) */
bzero(magic, 16);
strcpy(magic, HEADER_MAGIC);
for (u=0; u<12; u++) fprintf(fd, "%c", magic[u]);
fpr4(fd, maxlength);
if (dump_verbose) {
fprintf(stderr, msg[WROTE_JPD_MAGIC_STRING], maxlength);
fprintf(stderr, "\n");
}
/* Write segment counts for the 5*28=140 continents * types
* 560 bytes in total
*/
k = 0;
for (u=0; u<140; u++) {
k += mem_numseg[u] + ((arc_numseg)? arc_numseg[u] : 0);
fpr4(fd, k);
}
if (dump_verbose) {
fprintf(stderr, msg[WROTE_JPD_INDEX_TABLE]);
fprintf(stderr, "\n");
}
/* Write numseg headers of 16 bytes;
* the segments themselves will start at address 576+numseg*16
*/
index2 = 0;
total_address2 = total_address0;
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; i<index2; i++) {
address1 = address2;
address2 = str4toint(segment_index[i].address);
#ifdef SEG_SELECT
if (!seg_select(i)) continue;
#endif
total_address2 += address2 - address1;
fpr3(fd, str3toint(segment_index[i].minlong));
fpr3(fd, str3toint(segment_index[i].maxlong));
fpr3(fd, str3toint(segment_index[i].minlat));
fpr3(fd, str3toint(segment_index[i].maxlat));
fpr4(fd, total_address2);
}
}
if (arc_numseg) {
if (!check_cat_and_cont(scene, u)) continue;
for (i=0; i<arc_numseg[u]; i++) {
seg = arc_index[u][i];
nstrokes = str4toint(seg);
xi = str3toint(seg+4);
yi = str3toint(seg+7);
minlong = maxlong = xi;
minlat = maxlat = yi;
for (j=0; j<nstrokes; j++) {
xi = xi + (int)((signed char)seg[10+2*j]);
yi = yi + (int)((signed char)seg[11+2*j]);
if (xi<minlong) minlong = xi;
if (xi>maxlong) maxlong = xi;
if (yi<minlat) minlat = yi;
if (yi>maxlat) 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; i<index2; i++) {
address1 = address2;
address2 = str4toint(segment_index[i].address);
#ifdef SEG_SELECT
if (!seg_select(i)) continue;
#endif
seg = &fullmap_buffer[address1 - address0];
for (j=0; j<address2-address1; j++)
fprintf(fd, "%c", seg[j]);
}
}
if (arc_numseg) {
if (!check_cat_and_cont(scene, u)) continue;
for (i=0; i<arc_numseg[u]; i++) {
seg = arc_index[u][i];
nstrokes = str4toint(seg);
for (j=0; j<6+2*nstrokes; j++)
fprintf(fd, "%c", seg[j+4]);
}
}
}
dump_finish:
if (dump_verbose) {
fprintf(stderr, msg[WROTE_SEGMENT_STROKES_IN_TOTAL], total_numseg);
fprintf(stderr, "\n\n");
}
fflush(fd);
if (strcasecmp(dump_file, "-")) fclose(fd);
if (!runlevel)
exit(0);
}
#define SEG_SCAN
#ifdef SEG_SCAN
int seg_scan(ImageLayout *scene)
{
#define MAXNUM 7000
int ind[MAXNUM];
int x0[MAXNUM];
int y0[MAXNUM];
int x1[MAXNUM];
int y1[MAXNUM];
int ns[MAXNUM];
int sh[MAXNUM];
int b[MAXNUM];
int e[MAXNUM];
int num[MAXNUM];
int length[MAXNUM];
int closed[MAXNUM];
int *group[MAXNUM];
int *marked;
char *seg;
int i, j, k, g, l, n, u;
int max, i0, count = 50, numseg, nstrokes, NUM;
int xi, yi, xi0, yi0;
int index1 = 0, index2 = 0;
int address0, address1, address2;
NUM = 0;
numseg = str4toint(&header->index[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<index2; i++) {
address1 = address2;
address2 = str4toint(segment_index[i].address);
nstrokes = (address2-address1-6)/2;
seg = &fullmap_buffer[address1 - address0];
xi = xi0 = str3toint(seg);
yi = yi0 = str3toint(seg+3);
for (j=0; j<nstrokes; j++) {
xi = xi + (int)((signed char)seg[6+2*j]);
yi = yi + (int)((signed char)seg[7+2*j]);
}
if (xi!=xi0 || yi!=yi0) {
ind[NUM] = i;
marked[i] = 1;
x0[NUM] = xi0;
y0[NUM] = yi0;
x1[NUM] = xi;
y1[NUM] = yi;
ns[NUM] = nstrokes;
sh[NUM] = abs(xi-xi0)+abs(yi-yi0);
++NUM;
}
}
}
printf("Number of non closed segments %d\n", NUM);
fprintf(stderr, "\nNumber of non closed segments %d\n", NUM);
fprintf(stderr, "Examining loops of such segments\n");
for (i=0; i<NUM; i++) {
b[i] = -1;
e[i] = -1;
num[i] = -1;
}
n = 0;
l = 0;
while (n<=count) {
fprintf(stderr, " [%d]", n);
++l;
if (l==10) {
fprintf(stderr, "\n");
l = 0;
}
for (i=0; i<NUM; i++) {
if (b[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<NUM; j++) {
if (b[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<NUM; i++) {
printf("%05d / %d %d (%d): %d %d %d %d ; %d %d (%d)\n",
sh[i], i, ind[i], ns[i],
x0[i], y0[i], x1[i], y1[i], b[i], e[i], num[i]);
}
for (i=0; i<NUM; i++) group[i] = NULL;
for (i=0; i<NUM; i++) length[i] = 0;
for (i=0; i<NUM; i++) closed[i] = 0;
g = 0;
iter1:
i = 0;
while(i<NUM && (e[i] == -1 || !marked[ind[i]])) {
++i;
if (i==NUM) goto finished;
}
l = 0;
length[g] = 1;
printf("Group %d\n", g);
group[g] = malloc(sizeof(int));
group[g][0] = i;
marked[ind[i]] = 0;
i0 = i;
printf(" %d", i);
++l;
if (e[i] == i) {
if (num[i]<=count) closed[g] = 1;
printf(" closed [%d]\n\n", num[i]);
++g;
goto iter1;
}
iter2:
i = e[i];
if (i == -1) {
printf(" open\n\n");
++g;
goto iter1;
}
if (!marked[ind[i]]) {
printf(" open\n\n");
++g;
goto iter1;
}
printf(" %d", i);
++l;
if (l>=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; k<length[g]; k++) {
j = group[g][k];
if (num[j]>max) max = num[j];
}
if (max<=count) closed[g] = 1;
printf(" closed [%d]\n\n", max);
++g;
goto iter1;
}
goto iter2;
finished:
for (i=0; i<NUM; i++) if (marked[ind[i]] && e[i] == -1) {
marked[ind[i]] = 0;
e[i] = -2;
printf("isolated : %d\n", i);
}
seg_mode = 3;
img_output = OUT_DUMP;
dump_format = DUMP_JPD;
/* select only the almost closed ones... */
for (i=0; i<numseg; i++) seg_marked[i] = 0;
for (g=0; g<NUM; g++) if (length[g]>0 && closed[g]>0) {
for (i=0; i<length[g]; i++) {
j = group[g][i];
k = ind[j];
seg_marked[k] = 1;
}
}
dump_file = strdup("closed");
dump_arcs(scene);
/* select the open ones... */
for (i=0; i<numseg; i++) seg_marked[i] = 0;
for (g=0; g<NUM; g++) if (length[g]>0 && closed[g]==0) {
for (i=0; i<length[g]; i++) {
j = group[g][i];
k = ind[j];
seg_marked[k] = 1;
}
}
dump_file = strdup("open");
dump_arcs(scene);
/* select the isolated ones... */
for (i=0; i<numseg; i++) seg_marked[i] = 0;
for (i=0; i<NUM; i++) if (e[i] == -2) {
j = ind[i];
seg_marked[j] = 1;
}
dump_file = strdup("isolated");
dump_arcs(scene);
for (i=0; i<numseg; i++)
if (marked[i] != 0) printf("!! %d (%d)\n", i, marked[i]);
exit(0);
}
#endif /* SEG_SCAN */
void writeout_stat(ImageLayout *scene, int numseg)
{
int i, u;
i = 0;
if (arc_file) {
dump_file = strdup("-");
arcinfo_lines(scene);
if (arc_numseg)
for (u=0; u<140; u++) i += arc_numseg[u];
}
printf("JPD=%d ARC=%d\n", numseg, i);
exit(0);
}
#endif /* ARCINFO */
void generate(ImageLayout *scene) {
/* misc variables */
SpherePt sp;
ScreenPt pt1, pt2;
int u, i, j, k, l, m, n, ret, lon, lat, jump=0;
int numseg, maxlength, nstrokes, address0 = 0;
int address1, address2, index1, index2;
Pixel pix=0;
/* filehandles */
void *fh = NULL;
char line[80];
cmd_string = realloc(cmd_string, 2);
*cmd_string = '\0';
cmd_killed_char = '\0';
caret_pos = 0;
setup_change = 0;
if (textboxes) {
free(textboxes);
textboxes = NULL;
}
if (scene->prepixmap && 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; i<C_ENDCOLOR; i++)
if (scene->color[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; i<scene->numdef; 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; u<ret; u++) {
for (i=0; i<numloc; i++) {
if (locations[i]->obj == 'c') {
m = locations[i]->population;
if (m>=index1 && m<index2) {
locations[i]->draw &= 0x3fffffff;
draw_location(scene, locations[i]);
}
} else
if (locations[i]->obj == 'p') {
m = locations[i]->alt;
if (m>=address1 && m<address2) {
locations[i]->draw &= 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; i<scene->numdef; 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<<i) & scene->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<<k) & scene->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; i<index2; i++) {
#ifdef SEG_SELECT
if (seg_mode) {
if (!seg_select(i)) continue;
}
#endif
ret = segment_in_scene(scene, &segment_index[i]);
if (ret == YES) {
if (i)
address1 = str4toint(segment_index[i-1].address);
else
address1 = address0;
address2 = str4toint(segment_index[i].address);
nstrokes = (address2-address1-6)/2;
if (fullmap_buffer) {
segment_buffer = &fullmap_buffer[address1 - address0];
} else {
#ifdef ZLIB
gzseek((gzFile *)fh, address1, SEEK_SET);
gzread((gzFile *)fh, segment_buffer, address2-address1);
#else
fseek((FILE *)fh, address1, SEEK_SET);
fread(segment_buffer, 1, address2-address1, (FILE *)fh);
#endif
}
#ifdef SEG_SELECT
seg_repeat:
#endif
lon = str3toint(segment_buffer);
lat = str3toint(&segment_buffer[3]);
sp.sph[LONGITUDE] = ((double)lon)/3600.0;
sp.sph[LATITUDE] = ((double)lat)/3600.0;
pt2 = project(scene, spher2cart(scene, sp));
#ifdef SUPERTRACE
fprintf(stderr, "i = %d addr1 = %d, addr2 = %d n = %d\n"
" orig_lat = %g orig_lon = %g\n",
i, address1, address2, nstrokes,
s2.sph[LATITUDE], s2.sph[LONGITUDE]);
#endif
path_start = 1;
#ifdef SEG_SELECT
if (seg_marked[i])
pix = scene->color[C_FG_TICKS].pix;
else
pix = scene->color[j].pix;
#endif
for (n=0; n<nstrokes; n++) {
/* iterate and draw all the appropriate points */
pt1 = pt2;
m = 6+2*n;
lon += (int)segment_buffer[m];
lat += (int)segment_buffer[m+1];
#ifdef SUPERTRACE
fprintf(stderr, "dx = %d, dy = %d\n",
(int)segment_buffer[m],
(int)segment_buffer[m+1]);
#endif
if (n<nstrokes-1 && n%jump>0) 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; i<numloc; i++) {
if (search_by==1) {
strcpy(fieldname, locations[i]->name);
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 (delta<deltamin) {
deltamin = delta;
loc_pointer[0] = i;
}
} else {
loc_pointer=(int*)realloc(loc_pointer,(num_found+1)*sizeof(int));
loc_pointer[num_found] = (search_by<=4)? i : presel_pointer[i];
++num_found;
}
}
}
if (num_found==1)
search_index = loc_pointer[0];
else
search_index = -1;
free(needle);
}
void twist_string(ImageLayout *scene, int i, char *str)
{
if (scene->color[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 (f<MINZOOM) break;
if (f>MAXZOOM) 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; j<i; j++) {
if (text[j]=='\n' && !strncmp(text+j+1, "Xrmap-", 6)) {
k = j;
while (isspace(text[k])) k--;
while (text[k]!='\n') k++;
ptr = strstr(text+j+1, "xrmap(1x)");
if (ptr) ptr = strstr(ptr+2, "xrmap(1x)");
if (ptr) {
j = ptr-text+1;
while (text[j]!='\n') j++;
while (isspace(text[j])) j++;
while (text[j]!='\n') j--;
for (l=k; l<j; l++) text[l] = '\0';
} else
for (l=k+3; l<j; l++) text[l] = '\0';
}
}
for (j=0; j<i; j++) {
if (text[j]) fputc(text[j], man);
}
free(text);
fflush(man);
fclose(man);
chmod(tmpname, 0555);
if (!strcmp(editor_cmd, "emx"))
sprintf(cmd, "(emx -edit 0 %s ; rm -f %s ) &", tmpname, tmpname);
else
sprintf(cmd, "(%s %s ; rm -f %s ) &", editor_cmd, tmpname, tmpname);
system(cmd);
}
void show_version(ImageLayout * scene, Window win)
{
char str[512];
sprintf(str, msg[VERSION_FORMAT],
PACKAGE, VERSION, DATEPKG, " ", COPYRIGHT);
draw_win_string(scene, win, str, BOTTOM);
}
void draw_win_cmd(ImageLayout * scene, int level)
{
int i, j;
char str[256], name[128], lat[40], lon[40];
if (!cmdwin_on && cmd_mode>MODE_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;i<END_LABELS_GENERALMENU-BEGIN_LABELS_GENERALMENU;i++) {
j = XTextWidth(xfont[0], str, spacing_generalmenu*i-1);
draw_separator(scene, j, TOP);
}
if (cmd_mode==MODE_MENU && cmd_type==M_MENU_START) {
XClearArea(dpy, cmdwin, 0, fonth[0]+6,
cmdwin_width, cmdwin_height, False);
draw_win_string(scene, cmdwin, msg[BRIEF_MENU_SHORTCUTS], BOTTOM);
}
}
if (cmd_mode==MODE_CMD) {
if (level<=1)
draw_tick(scene, MODE_MENU, M_MENU_CMD, TOP);
for (j=0; j<=1; j++)
draw_win_string(scene, cmdwin, msg[LIST_OF_MAIN_COMMANDS+j], TOP+j+1);
}
if (cmd_mode==MODE_FILE) {
if (level<=1)
draw_tick(scene, MODE_MENU, M_MENU_FILE, TOP);
strcpy(str, labels_filemenu);
draw_win_string(scene, cmdwin, str, TOP+1);
for (i=1; i<END_LABELS_FILEMENU-BEGIN_LABELS_FILEMENU; i++) {
j = XTextWidth(xfont[0], str, spacing_filemenu*i-1);
draw_separator(scene, j, TOP+1);
}
if (level<=1) {
draw_tick(scene, MODE_FILE, cmd_type, TOP+1);
}
if (cmd_type==M_FILE_DATA)
draw_rect_cmd(scene, datafile_descr, NUM_DATAFILE, TOP+1, level);
else
if (cmd_type==M_FILE_EXTERNAL)
draw_rect_cmd(scene, external_descr, NUM_EXTERNAL, TOP+1, level);
else
if (cmd_type==M_FILE_PRINTCFG)
draw_rect_cmd(scene, printcfg_descr, NUM_PRINTCFG, TOP+1, level);
else
if (cmd_type==M_FILE_SAVE) {
draw_rect_cmd(scene, save_descr, NUM_SAVE, TOP+1, level);
}
if (cmd_type==M_FILE_SAVE) {
if (overwrite==1) {
sprintf(str, msg[OUTPUT_FILE_ALREADY_EXISTS],
scene->outfile);
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; i<num_found; i++)
loc_pointer[i] = scene->position[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; i<num_listed; i++) {
j = loc_pointer[i+start_list];
if (i==0 && start_list>0)
strcpy(str, GO_UP);
else
if (i==num_listed-1 && start_list+num_listed<num_found)
strcpy(str, GO_DOWN);
else {
if (j==search_index) line_clicked = i+1;
if (search_by==6) {
if (j>=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; i<num_listed; i++) free(cityname_descr[i]);
free(cityname_descr);
}
}
if (cmd_mode==MODE_OPTION) {
if (level<=1)
draw_tick(scene, MODE_MENU, M_MENU_OPTION, TOP);
strcpy(str, labels_optionmenu);
draw_win_string(scene, cmdwin, str, TOP+1);
for (i=1;i<END_LABELS_OPTIONMENU-BEGIN_LABELS_OPTIONMENU;i++) {
j = XTextWidth(xfont[0], str, spacing_optionmenu*i-1);
draw_separator(scene, j, TOP+1);
}
if (level<=1)
draw_tick(scene, cmd_mode, cmd_type, TOP+1);
if (cmd_type==M_OPTION_PARAM)
draw_rect_cmd(scene, parameter_descr, NUM_PARAM, TOP+1, level);
if (cmd_type==M_OPTION_HIERARCHY)
draw_rect_cmd(scene, display_descr, NUM_HIERARCHY, TOP+1, level);
if (cmd_type==M_OPTION_FONT)
draw_rect_cmd(scene, font_descr, NUM_FONTS, TOP+1, level);
if (cmd_type==M_OPTION_MARKS)
draw_rect_cmd(scene, marks_descr, NUM_MARKS, TOP+1, level);
if (cmd_type==M_OPTION_CONTIN)
draw_rect_cmd(scene, continent_descr, NUM_CONTIN, TOP+1, level);
if (cmd_type==M_OPTION_CAT)
draw_rect_cmd(scene, category_descr, NUM_CAT, TOP+1, level);
}
if (cmd_mode==MODE_COLOR) {
if (level<=1)
draw_tick(scene, MODE_MENU, M_MENU_COLOR, TOP);
strcpy(str, labels_colormenu);
draw_win_string(scene, cmdwin, str, TOP+1);
for (i=1; i<END_LABELS_COLORMENU-BEGIN_LABELS_COLORMENU; i++) {
j = XTextWidth(xfont[0], str, spacing_colormenu*i-1);
draw_separator(scene, j, TOP+1);
}
if (level<=1)
draw_tick(scene, cmd_mode, cmd_type, TOP+1);
if (cmd_type>M_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; i<END_LABELS_HELPMENU-BEGIN_LABELS_HELPMENU; i++) {
j = XTextWidth(xfont[0], str, spacing_helpmenu*i-1);
draw_separator(scene, j, TOP+1);
}
if (level<=1)
draw_tick(scene, cmd_mode, cmd_type, TOP+1);
if (cmd_type==M_HELP_SHORTCUTS) {
char *ptr1, *ptr2, n;
n = (cmdwin_height-2*(fonth[0]+16)-13)/(fonth[0]+5);
if (n>END_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; i<num_doc; i++)
if (doc_descr[i]) free(doc_descr[i]);
free(doc_descr);
doc_descr = NULL;
}
for (dirent = readdir(dir); dirent != NULL;
dirent = readdir(dir))
if (strcmp(dirent->d_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; i<num_listed; i++) {
if (i==0 && start_list>0)
strcpy(str, GO_UP);
else
if (i==num_listed-1 && start_list+num_listed<scene->numpoint)
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; i<num_listed; i++)
if (data_descr[i]) free(data_descr[i]);
if (data_descr) free(data_descr);
}
}
/* Draw bottom text bar only when needed, i.e. when
user has to enter text input */
if (text_input_mode())
draw_win_string(scene, cmdwin, cmd_string, BOTTOM);
XFlush(dpy);
}
void fix_features_description(ImageLayout * scene)
{
int i, j, n;
for (i=0; i<6; i++) {
if (feature_descr[i]) free(feature_descr[i]);
feature_descr[i] = (char **)
malloc(feature_length[i]*sizeof(char **));
for (n=0; n<feature_length[i]; n++) {
j = feature_index[i]+n;
if (scene->color[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(j<l1 || j<l2) {
if (j<l1)
w1 = XTextWidth(xfont[0], &str[j], 1);
else
w1 = 0;
if (j<l2)
w2 = XTextWidth(xfont[0], &time_string[j], 1);
else
w2 = 0;
if (x1!=x2) {
w2 = XTextWidth(xfont[0], time_string, l2);
XClearArea(dpy, datawin, x1, y-fontasc[0], w2, fonth[0], False);
XDrawString(dpy, datawin, gc, x1, y, &str[j], l1-j);
break;
}
if (j<l2 || (j<l1 && str[j]!=time_string[j]))
XClearArea(dpy, datawin, x1, y-fontasc[0], w1, fonth[0], False);
if (j<l1)
XDrawString(dpy, datawin, gc, x1, y, &str[j], 1);
x1 += w1;
x2 += w2;
++j;
}
strcpy(time_string, str);
}
void write_point_primary(ImageLayout * scene, int i)
{
char str[256];
sprintf(str, "|%.6f,%.6f", scene->mempoint[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; l<scene->numpoint; 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; i<num_flag_dirs; i++) {
free(flag_dir[i]);
free(flag_type[i]);
}
free(flag_dir);
free(flag_type);
free(flag_ordering);
}
}
int set_flag_dirs()
{
int i, j, n, error;
char *ptr, *ptrp;
char dirname[256];
struct stat buf;
free_flag_data();
num_flag_dirs = 0;
flag_dir = NULL;
flag_type = NULL;
flag_ordering = NULL;
error = 0;
ptr = flag_descr;
while (ptr) {
ptrp = index(ptr, ':');
if (!ptrp) {
flag_ordering = strdup(ptr);
break;
}
*ptrp = '\0';
n = num_flag_dirs;
++num_flag_dirs;
flag_dir = (char **) realloc(flag_dir, num_flag_dirs*sizeof(char*));
flag_type = (char **) realloc(flag_type, num_flag_dirs*sizeof(char*));
flag_dir[n] = strdup(ptr);
buf.st_mode = 0;
sprintf(dirname, "%s/%s", FLAGPATH, flag_dir[n]);
stat(dirname, &buf);
if (!S_ISDIR(buf.st_mode)) error = 1;
*ptrp = ':';
ptr = ptrp+1;
ptrp = index(ptr, '|');
if (ptrp) *ptrp = '\0';
flag_type[n] = strdup(ptr);
for (i=0; i<strlen(ptr); i++)
flag_type[n][i] = tolower(flag_type[n][i]);
j = 1;
for (i=0; i<num_flag_types; i++) {
if (!strcmp(flag_type[n], flag_formats[i])) {
j = 0;
break;
}
}
error |= j;
if (ptrp) *ptrp = '|'; else break;
ptr = ptrp+1;
if (!*ptr) break;
}
if (error || !flag_ordering) return 1;
if (strlen(flag_ordering)<2*num_flag_dirs+1) return 1;
if (flag_ordering[num_flag_dirs] != ',') return 1;
for (i=0; i<2*num_flag_dirs+1; i++) if (i!=num_flag_dirs) {
j = flag_ordering[i] - '1';
if (j>9)
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<num_flag_types; i++) {
if (!strcasecmp(ftype, flag_formats[i])) { j = i; break; }
}
if (j == -1) continue;
for (i=0; i<strlen(ftype); i++) ftype[i] = toupper(ftype[i]);
n += strlen(name) + strlen(ftype) + 2;
i = (flag_descr == NULL);
flag_descr = (char*) realloc(flag_descr, n);
if (i) flag_descr[0] = '\0'; else strcat(flag_descr, "|");
strcat(flag_descr, name);
strcat(flag_descr, ":");
strcat(flag_descr, ftype);
}
closedir(dir);
set_flag_dirs();
weight = (int *)malloc(num_flag_dirs*sizeof(int));
order = (int *)malloc(num_flag_dirs*sizeof(int));
k = 2*num_flag_dirs+2;
n += k;
flag_descr = (char*) realloc(flag_descr, n);
flag_ordering = malloc(k);
flag_ordering[num_flag_dirs] = ',';
flag_ordering[k-1] = '\0';
for (k=0; k<=1; k++) {
for (i=0; i<num_flag_dirs; i++)
weight[i] = order[i] = 0;
for (i=0; i<num_flag_dirs; i++) {
for (j=0; j<num_flag_types; j++) {
if (!strcmp(flag_type[i], flag_formats[(k)?flag_rev[j]:j]))
weight[i] = j;
}
ptr = index(flag_dir[i], '_');
if (ptr && atoi(ptr+1)>=200) weight[i] += 1000;
}
if (k==0) {
for (i=0; i<num_flag_dirs; i++)
for (j=0; j<num_flag_dirs; j++)
if (j!=i && weight[j]>=weight[i]) ++order[j];
}
if (k==1) {
for (i=0; i<num_flag_dirs; i++)
for (j=0; j<num_flag_dirs; j++)
if (j!=i && weight[j]<=weight[i]) ++order[j];
}
for (i=0; i<num_flag_dirs; i++) weight[order[i]] = i+1;
for (i=0; i<num_flag_dirs; i++) {
ptr = &flag_ordering[i+k*(num_flag_dirs+1)];
if (weight[i]<10)
*ptr = '0'+weight[i];
else
*ptr = 'a'+weight[i]-10;
}
}
free(weight);
free(order);
strcat(flag_descr, "|");
strcat(flag_descr, flag_ordering);
/* DEBUG...
printf("%s\n", flag_descr);
for (i=0; i<num_flag_dirs; i++)
printf("%s %s\n", flag_dir[i], flag_type[i]);
*/
}
void show_datawin(ImageLayout * scene, int raise)
{
static char *flag[2] = { NULL, NULL};
static char *prev_flag[2] = { NULL, NULL};
struct stat buf;
int i, j=0, k, lstep, lmax, line_y, erase_text = 0, show_flags;
int x, y, w, h;
char str[11][256],
path[256], name[256], country[256], lat[40], lon[40],
alt[20], pop[20], rank1[20], rank2[20], rank3[20], adm_status[40];
char *ptr;
if (city_found<0) return;
if (city_found != old_city_shown) erase_text = 1;
old_city_shown = city_found;
buf.st_mode = 0;
if (stat(FLAGPATH, &buf) || !S_ISDIR(buf.st_mode))
show_flags = 0;
else
show_flags = 1;
exposed &= ~DATA_WINDOW;
data_text = realloc(data_text, 4*sizeof(char));
*data_text = '\0';
if (locations[city_found]->obj == '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; i<NUM_BUTTONS; i++) {
char s[4];
XSetForeground(dpy, gc, scene->color[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; i<scene->numdef; 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; m<strlen(rep); m++) {
if (rep[m]==' ') rep[m]='\037';
if (rep[m]==',' || rep[m]=='|') {
n++;
if (n<=2) rep[m] = ' ';
}
}
sprintf(cmd, "SHAREDIR=%s ; ", SHAREDIR);
m = strlen(cmd);
n = sscanf(rep, "%s %s %s", lat, lon, cmd+m);
free(rep);
xp = dms2decim(lat);
yp = dms2decim(lon);
if (n==3 && fabs(x-xp)+fabs(y-yp)<eps*fact) {
for (m=0; m<strlen(cmd); m++)
if (cmd[m]=='\037') cmd[m]=' ';
strcat(cmd," &");
system(cmd);
}
}
for (i=0; i<numloc; i++) {
if ((locations[i]->draw & SPOT_DRAWN) &&
fabs(x-locations[i]->lat)+fabs(y-locations[i]->lon)<eps) {
ScreenPt pt;
SpherePt spt;
spt.sph[LONGITUDE] = locations[i]->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+k<max) popul = -30000;
max = j+k;
if (locations[i]->population>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; j<scene->numpoint; 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_listed<total) {
start_list += (num_listed-3);
if (start_list+num_listed>total)
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_listed<total) {
start_list += (num_listed-3);
line_clicked = -10;
if (start_list+num_listed>total)
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; i<argc-1; i++)
if (!strpcmp(argv[i], "language", 4)) {
strncpy(language, argv[i+1], 2);
language[2] = '\0';
read_i18n_file(scene);
argv[i+1] = language;
break;
}
if (!*language) read_i18n_file(scene);
/* parse system wide rcfile */
strncpy(scene->rcfile, RCFILE, 255);
scene->rcfile[255] = '\0';
parse_rcfile(scene);
/* Check whether user has specified its own rcfile(s) */
j = 0;
for (i=1; i<argc-1; i++)
if (!strpcmp(argv[i], "rcfile", 3)) {
++i;
if (argv[i][0] == '\0' ||
!strcasecmp(argv[i],"none") ||
!strcasecmp(argv[i],"null")) {
*scene->rcfile = '\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; i<argc; i++) {
j = strlen(cmd_string);
cmd_string = (char *) realloc(cmd_string, j+strlen(argv[i])+2);
cmd_string[j] = '\177';
cmd_string[j+1] = '\0';
strcat(cmd_string, argv[i]);
}
if (*cmd_string && parse_cmd_line(scene, cmd_string, "\177")) exit(-1);
cmd_string = (char *) realloc(cmd_string, 1);
*cmd_string = '\0';
cmd_killed_char = '\0';
if (scene->projection==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_found<numloc &&
locations[city_found]->obj!='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<num_flag_dirs; i++) {
XDrawRectangle(dpy, flagwin, gc,
16+97*(i&1),
17+(1+(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.y<fonth[0]+8) {
int i, j=-1;
if (ev.type!=ButtonRelease) break;
for (i=0; i<=4; i++)
if (ev.xbutton.x>8*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_width) {
if (ev.xbutton.y<=2*fonth[0]+28) {
if (ev.type!=ButtonPress) break;
goto expl_up;
} else
if (ev.xbutton.y>=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; i<NUM_BUTTONS; i++)
if (ev.xbutton.x>i*w_button+3 &&
ev.xbutton.x<(i+1)*w_button &&
ev.xbutton.y>3 &&
ev.xbutton.y<h_button-3) {
if (ev.type == ButtonPress) {
but_data_pressed = ev.xbutton.button;
show_modified_buttons(2, i);
}
j = 0;
if (button_visit != i) {
ev_time = ev.xbutton.time;
if (ev.type == MotionNotify) {
show_modified_buttons(0, button_visit);
show_modified_buttons(1, i);
}
button_visit = i;
wait_iter = 0;
}
}
if (j) {
show_modified_buttons(0, button_visit);
button_visit = -1;
wait_iter = 0;
}
break;
case ButtonRelease:
if (ev.xbutton.button > 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; i<NUM_BUTTONS; i++)
if (ev.xbutton.x>i*w_button+3 &&
ev.xbutton.x<(i+1)*w_button &&
ev.xbutton.y>3 &&
ev.xbutton.y<h_button-3) {
char cmd[512], path[256], code[4], cia_code[4];
struct stat buf;
char tmpname[80];
FILE *ft;
if (city_found>=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_found<numloc) {
XMapRaised(dpy, mainwin);
scene->gopt.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<h_button+4+pixmap_height[0]) ||
(ev.xbutton.x>=12+pixmap_width[0] &&
ev.xbutton.x<12+pixmap_width[0]+pixmap_width[1] &&
ev.xbutton.y>=h_button+4 &&
ev.xbutton.y<h_button+4+pixmap_height[1])) {
char path[80];
char *ptr, *ptrp;
ptr = ptrp = NULL;
if (locations[city_found]->obj=='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_pos<strlen(cmd_string)) ++caret_pos;
}
else
if (keysym==XK_d || keysym==XK_D) {
int l, m;
l = strlen(cmd_string);
for (m=caret_pos; m<l; m++)
cmd_string[m] = cmd_string[m+1];
}
else
if (keysym==XK_h || keysym==XK_H) {
int l, m;
l = strlen(cmd_string);
if (caret_pos) {
for (m=caret_pos-1; m<l; m++)
cmd_string[m] = cmd_string[m+1];
--caret_pos;
}
}
else
if (keysym==XK_k || keysym==XK_K) {
cmd_killed_length = strlen(cmd_string);
cmd_killed_pos = caret_pos;
cmd_killed_char = cmd_string[caret_pos];
cmd_string[caret_pos] = '\0';
}
else
if (keysym==XK_y || keysym==XK_Y) {
if (cmd_killed_char) {
caret_pos = cmd_killed_pos;
cmd_string[cmd_killed_pos] = cmd_killed_char;
cmd_string[cmd_killed_length] = '\0';
}
}
else
if (keysym==XK_e || keysym==XK_E)
caret_pos = strlen(cmd_string);
else
if (keysym==XK_w || keysym==XK_W)
write_primary(cmd_string+caret_pos);
}
else
if (keysym==XK_Right) {
if (caret_pos<strlen(cmd_string)) ++caret_pos;
}
else
if (keysym==XK_Left) {
if (caret_pos>0) --caret_pos;
}
else
if (keysym==XK_Delete) {
int l, m;
l = strlen(cmd_string);
if (caret_pos) {
for (m=caret_pos-1; m<l; m++)
cmd_string[m] = cmd_string[m+1];
--caret_pos;
}
}
else
if (keysym>=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<l; i++)
if (ptr[i]<' ') ptr[i] = ' ';
lp = strlen(cmd_string);
do_caret(scene, ev.xbutton.x);
cmd_string = realloc(cmd_string, l+lp+4);
for (i=lp; i>=caret_pos; i--)
cmd_string[i+l] = cmd_string[i];
for (i=0; i<l; i++)
cmd_string[caret_pos+i] = ptr[i];
free(ptr);
caret_pos +=l;
draw_win_string(scene, cmdwin, cmd_string, BOTTOM);
break;
}
if (ev.xbutton.button==3 && cmd_mode && text_input_mode() &&
ev.xbutton.y>=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<XTextWidth(xfont[0],
labels_optionmenu, spacing_optionmenu*i-1))
cmd_type = i;
}
}
if (cmd_mode==MODE_COLOR) {
int i;
cmd_type = M_COLOR_CIL;
for (i=M_COLOR_CIL; i>=1; i--) {
if (ev.xbutton.x<XTextWidth(xfont[0],
labels_colormenu, spacing_colormenu*i-1))
cmd_type = i;
}
}
if (cmd_mode==MODE_HELP) {
cmd_type = M_HELP_EDIT;
for (i=M_HELP_EDIT; i>=1; i--) {
if (ev.xbutton.x<XTextWidth(xfont[0],
labels_helpmenu, spacing_helpmenu*i-1))
cmd_type = i;
}
if (cmd_type==M_HELP_EDIT) {
start_list = 0;
show_mark(scene);
}
if (cmd_type==M_HELP_EXTRA)
start_list = 0;
}
draw_win_cmd(scene, 1);
break;
}
if (cmd_mode==MODE_HELP && cmd_type==M_HELP_SHORTCUTS) {
if (ev.xbutton.y>box_y + box_numitems*box_spacing)
++start_shortcut;
if (ev.xbutton.y>box_y + box_spacing &&
ev.xbutton.y<box_y + box_spacing + box_height) {
if (start_shortcut>0) --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.x<box_x+box_width) {
j = ((int)ev.xbutton.y - box_y);
m = 0;
while (j<0) { j += box_spacing; m += 1; }
j = j/box_spacing - m;
if (ev.xbutton.y>box_y+j*box_spacing &&
ev.xbutton.y<box_y+j*box_spacing+box_height)
l = j;
}
do_click:
expl_output = 0;
if (l>=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.zoom<MINZOOM) scene->gopt.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;
}
syntax highlighted by Code2HTML, v. 0.9.1