/* * Copyright (C) 2003 Tim Martin * * 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 */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "callbacks.h" #include "interface.h" #include "support.h" #include "screen.h" #include "heightmap.h" #include "utils.h" #include "map.h" #include "tiles.h" #include "client.h" #include "landvalue.h" #include "gtkhelp_reports.h" #include "sdlwin.h" #include "utils.h" static void draw_grid(GtkWidget *widget); static void recenter_screen(GtkWidget *widget, screen_t *screen, map_t *map, int mapx, int mapy); static void show_message(char *msg, void *rock); static int placeobject_iterator(map_t *map, int mapx, int mapy, void *rock); GtkWidget *about_window = NULL; GtkWidget *popreport_window = NULL; GtkWidget *finances_window = NULL; GtkWidget *stats_window = NULL; GtkWidget *newgame_window = NULL; GtkWidget *info_window = NULL; GtkWidget *gamelist_window = NULL; GtkWidget *textdisp_window = NULL; GtkWidget *taxes_window = NULL; extern GtkWidget *window1; guint idle_handler = -1; extern int debug; GtkEntry *currentposx; GtkEntry *currentposy; GtkLabel *CurrentToolLabel; GtkLabel *CurrentTimeLabel; GtkLabel *fundslabel = NULL; GtkLabel *MessageLabel; #define MAX_FRAMES_SEC 30 #define MYMIN(a,b) ((a < b) ? a : b) #define MYMAX(a,b) ((a >= b) ? a : b) GtkWidget *drawingareawidget = NULL; map_t *map = NULL; screen_t *screen; tiles_t *tiles = NULL; client_t *client; player_t *me; display_t display; int block_speed_cb = 0; static void set_current_activity(char *name); static char * default_userid(void) { return getpwuid(getuid())->pw_name; } void on_new1_activate (GtkMenuItem *menuitem, gpointer user_data) { GtkEntry *username_entry; GtkEntry *servername_entry; if (newgame_window) return; if (gamelist_window) return; newgame_window = create_newgameWindow (); username_entry = (GtkEntry *)lookup_widget(GTK_WIDGET(newgame_window), "username_entry"); gtk_entry_set_text(username_entry, default_userid()); servername_entry = (GtkEntry *)lookup_widget(GTK_WIDGET(newgame_window), "server_entry"); gtk_entry_set_text(servername_entry, "localhost"); gtk_widget_show (newgame_window); } void on_quit1_activate (GtkMenuItem *menuitem, gpointer user_data) { /* xxx quit more safely */ exit(0); } void on_about1_activate (GtkMenuItem *menuitem, gpointer user_data) { if (!about_window) { about_window = create_AboutWindow(); } gtk_widget_show (about_window); gdk_window_raise(about_window->window); } int screen_moved = 1; static int maybe_draw_spot(int mapx, int mapy, void *rock) { int screenx; int screeny; if (screen_is_square_viewable(screen, mapx, mapy, &screenx, &screeny)) { sdlwin_draw_spot(&display, map, me, screen, tiles, screen_moved, mapx, mapy, screenx, screeny); } return 0; } enum selected_type { SELECT_POINT, SELECT_BOX, SELECT_LINE }; static void selected_set(enum selected_type type, int x1, int y1, int x2, int y2, int hitype) { switch(type) { case SELECT_POINT: display.selected_cost = map_set_temporary(map, me, x1, y1, display.activity, hitype, MAPSPECIAL_HILITE_INVALID); break; case SELECT_BOX: display.selected_cost = map_set_temporary_box(map, me, x1, y1, x2, y2, display.activity, hitype, MAPSPECIAL_HILITE_INVALID); break; case SELECT_LINE: display.selected_cost = map_set_temporary_line(map, me, x1, y1, x2, y2, display.activity, hitype, MAPSPECIAL_HILITE_INVALID); break; } } static void selected_setup(enum selected_type type, int x1, int y1, int x2, int y2, int hitype) { int cash; selected_set(type, x1, y1, x2, y2, hitype); cash = player_getmoney(me); if (cash < display.selected_cost) { selected_set(type, x1, y1, x2, y2, MAPSPECIAL_HILITE_INVALID); } } static void set_cursor(int mapx, int mapy) { selected_setup(SELECT_POINT, mapx, mapy, mapx, mapy, MAPSPECIAL_CURSOR); } static void draw_grid(GtkWidget *widget) { char coststr[100]; char amountstr[12]; /* * Don't draw anything if there is no map yet */ if (!map) return; /* * could make a big increase by eliminating this call */ if (screen_moved) { screen_viewarea_clear(screen); sdlwin_clearscreen(); } /* iterate over the whole map but only draw the viewable (or * partially viewable) squares. The order we iterate in is * determined by our current rotation */ if (screen_moved) { /* xxx really should be map changed */ if (display.view == GAMEVIEW_POLICE_COVER) { display.viewtype = MAPTYPE_POLICE; display.objlist = map_find_tile_list(map, MAPTYPE_POLICE); } else if (display.view == GAMEVIEW_HOSPITAL_COVER) { display.viewtype = MAPTYPE_HOSPITAL; display.objlist = map_find_tile_list(map, MAPTYPE_HOSPITAL); } else if (display.view == GAMEVIEW_FIRE_COVER) { display.viewtype = MAPTYPE_FIRE; display.objlist = map_find_tile_list(map, MAPTYPE_FIRE); } } /* * XXX could get 10% increase by not calling this */ screen_map_iterate(screen, &maybe_draw_spot, (void *)widget); sdlwin_updatescreen(); prettyprint_money(display.selected_cost, amountstr, sizeof(amountstr)-1); snprintf(coststr, sizeof(coststr),_("Cost: %s"), amountstr); gtk_label_set_text(MessageLabel, coststr); /* * We just recalculated the spots. Re-position the hightlighted square too */ if (screen_moved) { int x, y; GdkModifierType state; int mapx; int mapy; gdk_window_get_pointer (widget->window, &x, &y, &state); if (screen_to_mapcoord(screen, x, y, &mapx, &mapy) == 0) { set_cursor(mapx, mapy); } screen_moved = 0; } } gboolean on_maindrawingarea_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data) { int x, y; GdkModifierType state; int mapx, mapy; switch (event->keyval) { case GDK_Escape: gdk_window_get_pointer (event->window, &x, &y, &state); if (screen_to_mapcoord(screen, x, y, &mapx, &mapy) != 0) { return FALSE; } set_cursor(mapx, mapy); break; } return FALSE; } static void recenter_screen(GtkWidget *widget, screen_t *screen, map_t *map, int mapx, int mapy) { int sx; int sy; int mapsizex = map_get_sizex(map); int mapsizey = map_get_sizey(map); int h = 0; /* re-center the viewable map on mapx,mapy */ mapcoord_to_screen(screen, mapsizex, mapsizey, mapx, mapy, &sx, &sy); if (map) { h = map_get_height(map, mapx, mapy); sy -= (screen_tileheight(screen) * h); } sx = sx - widget->allocation.width/2; sy = sy - widget->allocation.height/2; /* don't allow moving too far away from the map */ screen_keep_in_bounds(screen, mapsizex, mapsizey, &sx, &sy); screen_set_position(screen, sx, sy); screen_moved = 1; } extern void screen_center_on_xy(map_t *map, int mapx, int mapy) { recenter_screen(drawingareawidget, screen, map, mapx, mapy); } static gint timer_function(gpointer data) { int mapchanged; static time_t last = 0; time_t now = time(NULL); if (now - last > 5) { /* xxx configurable */ if (finances_window) { update_finances_window(finances_window, client); } if (popreport_window) { update_population_report(popreport_window, client); } if (stats_window) { update_stats_window(stats_window, client); } last = now; } if (client) { client_checkpoint(client, &mapchanged); } /* return 1 because we don't want this timer callback to go away */ return 1; } static gint idle_loop (gpointer data) { static int cnt = 0; static int lastsec = 0; static struct timeval last = {0, 0}; struct timeval now; gettimeofday(&now, NULL); if (now.tv_sec > lastsec) { if (debug) printf("%d FPS\n",cnt); cnt = 0; lastsec = now.tv_sec; } if (last.tv_sec != 0) { if ((now.tv_sec - last.tv_sec) * 1000000 + now.tv_usec - last.tv_usec < 1000000/(2*MAX_FRAMES_SEC)) { return TRUE; } } last = now; cnt++; draw_grid((GtkWidget *)data); return TRUE; } guint timeoutid = -1; static void timeout_add(void) { timeoutid = gtk_timeout_add (1000, &timer_function, NULL); } static void timeout_remove(void) { if (timeoutid != -1) { gtk_timeout_remove(timeoutid); timeoutid = -1; } } int foobar = 0; gboolean on_maindrawingarea_configure_event (GtkWidget *widget, GdkEventConfigure *event, gpointer user_data) { GtkRcStyle *rc_style; int r; int mapx = 0; int mapy = 0; if (idle_handler > -1) { gtk_idle_remove(idle_handler); } /* After filling in your GdkColor, create a GtkRcStyle */ if (!foobar) { rc_style = gtk_rc_style_new (); gtk_widget_modify_style (widget, rc_style); gtk_rc_style_unref (rc_style); } drawingareawidget = widget; sdlwin_init(widget); if (!map) { timeout_add(); } if (!screen) { r = screen_init(&screen); /* xxx screen_setmap(screen, map);*/ } screen_setsize(screen, widget->allocation.width,widget->allocation.height); /* * Figure out where the old center of the screen is */ screen_to_mapcoord_screen_center(screen, &mapx, &mapy); /* xxx recenter_screen(widget, screen, mapx, mapy);*/ currentposx = (GtkEntry *)lookup_widget(widget, "currentposx"); currentposy = (GtkEntry *)lookup_widget(widget, "currentposy"); CurrentToolLabel = (GtkLabel *)lookup_widget(widget, "CurrentToolLabel"); CurrentTimeLabel = (GtkLabel *)lookup_widget(widget, "CurrentTimeLabel"); fundslabel = (GtkLabel *)lookup_widget(widget, "fundslabel"); MessageLabel = (GtkLabel *)lookup_widget(widget, "MessageLabel"); updatemoney(); idle_handler = gtk_idle_add(idle_loop, widget); foobar = 1; return TRUE; } static void show_mapspot_info(int mapx, int mapy) { GtkCList *clist; if (!info_window) { info_window = create_info_window(); setup_info_treeview(info_window); } update_info_window(info_window, client, mapx, mapy); gtk_widget_show (info_window); gdk_window_raise(info_window->window); } /* xxx put these in the display structure */ int mousepressed = 0; int mousepressed_map_x = -1; int mousepressed_map_y = -1; gboolean on_maindrawingarea_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { int mapx; int mapy; if (screen_to_mapcoord(screen, event->x, event->y, &mapx, &mapy) != 0) { return FALSE; } if (event->button == 1) { mousepressed_map_x = mapx; mousepressed_map_y = mapy; mousepressed = 1; selected_setup(SELECT_POINT, mapx, mapy, mapx, mapy, MAPSPECIAL_SELECTED); } else if (event->button == 2) { recenter_screen(widget, screen, map, mapx, mapy); /* reset the select square */ map_temporary_reset(map); } else if (event->button == 3) { show_mapspot_info(mapx, mapy); } return TRUE; } gboolean on_maindrawingarea_motion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { int x, y; GdkModifierType state; int mapx; int mapy; char str[10]; int sizex; int sizey; int r; if (event->is_hint) { gdk_window_get_pointer (event->window, &x, &y, &state); } else { x = event->x; y = event->y; state = event->state; } /* get current map coordinate */ if (screen_to_mapcoord(screen, x, y, &mapx, &mapy) != 0) { return FALSE; } /* tell the GUI the current position */ snprintf(str,sizeof(str)-1,"%d",mapx); gtk_entry_set_text(currentposx, str); snprintf(str,sizeof(str)-1,"%d",mapy); gtk_entry_set_text(currentposy, str); tiles_getsize(tiles, display.activity, &sizex, &sizey); switch (display.activity) { case MAPOBJ_ACTION_RAISE: case MAPOBJ_ACTION_LOWER: selected_setup(SELECT_POINT, mapx, mapy, mapx, mapy, MAPSPECIAL_SELECTED); return FALSE; default: break; } if (state & GDK_BUTTON1_MASK) { /* mouse is being held down */ if (display.activity == MAPOBJ_ACTION_FLATTEN) { selected_setup(SELECT_BOX, mousepressed_map_x, mousepressed_map_y, mapx, mapy, MAPSPECIAL_SELECTED); if (display.height_change_list) { mapspot_list_free(display.height_change_list); display.height_change_list = NULL; } r = map_temporary_iterate(map, MAPSPECIAL_SELECTED, &placeobject_iterator, (void *)&display); if (r) { selected_setup(SELECT_BOX, mousepressed_map_x, mousepressed_map_y, mapx, mapy, MAPSPECIAL_HILITE_INVALID); } else { display.selected_cost = mapspot_list_length(display.height_change_list) * 1000; /* xxx */ } } else if (map_item_gettype(display.activity) == MAPTYPE_ROAD) { selected_setup(SELECT_LINE, mousepressed_map_x, mousepressed_map_y, mapx, mapy, MAPSPECIAL_SELECTED); } else { selected_setup(SELECT_BOX, mousepressed_map_x, mousepressed_map_y, mapx, mapy, MAPSPECIAL_SELECTED); } } else if (!mousepressed) { set_cursor(mapx, mapy); } return FALSE; } void updatemoney(void) { char str[100]; if (!me) return; prettyprint_money(player_getmoney(me), str, sizeof(str)-1); if (fundslabel) { gtk_label_set_text(fundslabel,str); } } static int count_cur_diff(int x, int y, void *data, float dist, void *rock) { int *cnt = (int *)rock; (*cnt) += (int)data; return 0; } static int placeobject_iterator(map_t *map, int mapx, int mapy, void *rock) { display_t *display = (display_t *)rock; int diff; int r; int i; int curdiff = 0; switch(display->activity) { case MAPOBJ_ACTION_BUYLAND: if ((map_empty_land(map, mapx, mapy)) && (map_can_buyland(map, me, mapx, mapy))) { client_buyland(client, mapx, mapy); } break; case MAPOBJ_ACTION_BUYALL: if (map_can_buyland(map, me, mapx, mapy)) { client_buyland(client, mapx, mapy); } break; case MAPOBJ_ACTION_SELLLAND: if ((map_empty_land(map, mapx, mapy)) && (map_can_sellland(map, me, mapx, mapy))) { client_sellland(client, mapx, mapy); } break; case MAPOBJ_ACTION_FLATTEN: mapspot_within_iterate(display->height_change_list, mapx, mapy, 0.0, count_cur_diff, (void *)&curdiff); diff = map_get_height(map, mousepressed_map_x, mousepressed_map_y) - (map_get_height(map, mapx, mapy) + curdiff); for (i = 0; i < abs(diff); i++) { r = map_change_height_list(&display->height_change_list, map, me, mapx, mapy, (diff > 0) ? 1 : -1); if (r) { printf(_("Error changing %d,%d\n"), mapx, mapy); return r; } } break; default: if (display->activity != MAPOBJ_INVALID) { client_setspot(client, mapx, mapy, display->activity); } } return 0; } gboolean on_maindrawingarea_button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { if (event->button == 1) { int mapx; int mapy; int addx; int addy; int r; mapspot_list_t *list = NULL; if ((!client) || (!map)) return FALSE; screen_to_mapcoord(screen, event->x, event->y, &mapx, &mapy); screen_getdirviewadds(screen, &addx, &addy); switch(display.activity) { case MAPOBJ_ACTION_RAISE: map_change_height_square(&list, map, me, mapx, mapy, 1); client_txn_start(client); client_changeheight(client, list); client_txn_commit(client); break; case MAPOBJ_ACTION_LOWER: map_change_height_square(&list, map, me, mapx, mapy, -1); client_txn_start(client); client_changeheight(client, list); client_txn_commit(client); break; case MAPOBJ_ACTION_FLATTEN: { int x1; int x2; int y1; int y2; x1 = MYMIN(mousepressed_map_x, mapx); x2 = MYMAX(mousepressed_map_x, mapx) + 1; y1 = MYMIN(mousepressed_map_y, mapy); y2 = MYMAX(mousepressed_map_y, mapy) + 1; selected_setup(SELECT_BOX, x1, y1, x2, y2, MAPSPECIAL_SELECTED); r = map_temporary_iterate(map, MAPSPECIAL_SELECTED, &placeobject_iterator, (void *)&display); if (!r) { client_txn_start(client); client_changeheight(client, display.height_change_list); client_txn_commit(client); } else { printf(_("Error flattening\n")); } display.height_change_list = NULL; } break; default: client_txn_start(client); map_temporary_iterate(map, MAPSPECIAL_SELECTED, &placeobject_iterator, (void *)&display); client_txn_commit(client); updatemoney(); break; } map_temporary_reset(map); set_cursor(mapx, mapy); screen_moved = 1; } mousepressed = 0; return FALSE; } gboolean on_maindrawingarea_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { return FALSE; } static void set_current_activity_obj(mapobj_t obj) { display.activity = obj; if (CurrentToolLabel) { gtk_label_set_text(CurrentToolLabel, "xxx"); /* xxx */ } } static void set_current_activity(char *name) { display.activity = map_item_name2obj(name); if (display.activity == MAPOBJ_INVALID) { printf(_("Map object %s not found\n"), name); } if (CurrentToolLabel) { gtk_label_set_text(CurrentToolLabel, name); } } void set_current_time(time_t curtime) { struct tm *tm; char timestr[25]; tm = gmtime(&curtime); strftime(timestr, sizeof(timestr)-1,_("%b %e, %Y"), tm); gtk_label_set_text(CurrentTimeLabel,timestr); } struct weather_buffer { char *name; GdkPixmap *pixmap; } weather_buflist[20]; /* xxx */ int weather_buflist_len = 0; static GdkPixmap * get_weather_pic(GtkImage *weatherpic, char *weather) { char buf[1024]; GdkColormap *colormap; GdkPixmap *gdkpixmap; GdkBitmap *mask; int i; /* * look in cache */ for (i = 0; i < weather_buflist_len; i++) { if (!weather_buflist[i].name) break; if (strcasecmp(weather_buflist[i].name, weather) == 0) { return weather_buflist[i].pixmap; } } /* * Not found. load it */ colormap = gtk_widget_get_colormap((GtkWidget *)weatherpic); snprintf(buf, sizeof(buf)-1,"../img/w_%s.xpm", weather); gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask, NULL, buf); if (!gdkpixmap) { snprintf(buf, sizeof(buf)-1,"%s/w_%s.xpm", IMG_DIRECTORY, weather); gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask, NULL, buf); } /* add to cache */ weather_buflist[weather_buflist_len].name = strdup(weather); weather_buflist[weather_buflist_len].pixmap = gdkpixmap; weather_buflist_len++; return gdkpixmap; } void set_current_weather(char *weather, int temp) { GtkImage *weatherpic; char buf[1024]; GtkLabel *templabel; GtkWidget *pic; GdkImage *image = NULL; /* * Temperature label */ templabel = (GtkLabel *)lookup_widget(window1, "temp_label"); snprintf(buf, sizeof(buf)-1,"%dF", temp); gtk_label_set_text(templabel, buf); /* * Change the weather picture */ weatherpic = (GtkImage *)lookup_widget(window1, "weather_pic"); snprintf(buf, sizeof(buf), "../img/w_%s.png", weather); gtk_image_set_from_file(weatherpic, buf); gtk_widget_show ((GtkWidget *)weatherpic); } void set_speed_ui(game_speeds_t speed) { GtkWidget *w; switch (speed) { case SPEED_FASTEST: w = lookup_widget(window1, "fastest1"); break; case SPEED_FAST: w = lookup_widget(window1, "fast1"); break; case SPEED_NORMAL: w = lookup_widget(window1, "normal1"); break; case SPEED_SLOW: w = lookup_widget(window1, "slow1"); break; default: case SPEED_PAUSED: w = lookup_widget(window1, "paused1"); break; } block_speed_cb = 1; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM (w), TRUE); block_speed_cb = 0; } static void zoom(int zoomchange) { int mapx = 0; int mapy = 0; screen_zoom(screen, zoomchange); screen_to_mapcoord_screen_center(screen, &mapx, &mapy); recenter_screen(drawingareawidget, screen, map, mapx, mapy); } void on_zoomin_clicked (GtkButton *button, gpointer user_data) { zoom(1); } void on_zoomout_clicked (GtkButton *button, gpointer user_data) { zoom(-1); } void on_show_grid1_activate (GtkMenuItem *menuitem, gpointer user_data) { display.grid = !display.grid; gtk_check_menu_item_set_state ((GtkCheckMenuItem *)menuitem, (gboolean)display.grid); } void on_about_ok_clicked (GtkButton *button, gpointer user_data) { gtk_widget_hide (about_window); } static void gameinfo_cb(char *name, void *rock) { GList **glistp = (GList **)rock; *glistp = g_list_append (*glistp, strdup(name)); } static char * find_app(char *name, char *trypath, char *buf, int buflen) { char *path = getenv("PATH"); char cwd[MAXPATHLEN+1]; struct stat sb; /* * First try path requested */ if (trypath) { snprintf(buf, buflen, "%s/%s", trypath, name); if (stat(buf, &sb) == 0) { return buf; } } /* * Next try current directory */ getcwd(cwd, sizeof(cwd)-1); snprintf(buf, buflen, "%s/%s", cwd, name); if (stat(buf, &sb) == 0) { return buf; } /* * Now try everything in the path */ while (path) { char *colon = strchr(path, ':'); char dir[MAXPATHLEN+1]; if (colon) { memcpy(dir, path, colon-path); dir[colon-path] = '\0'; } else { strcpy(dir, path); } snprintf(buf, buflen, "%s/%s", dir, name); if (stat(buf, &sb) == 0) { return buf; } if (colon) { path = colon+1; } else { path = NULL; } } return NULL; } extern void start_local_server(void) { pid_t pid; pid = fork(); if (pid) { /* parent */ return; } else { char serverstr[MAXPATHLEN+1]; char *server = find_app("senkenserver", "../server/", serverstr, sizeof(serverstr)-1); char xtermstr[MAXPATHLEN+1]; char *xterm = find_app("xterm", NULL, xtermstr, sizeof(xtermstr)-1); execl(xterm, "xterm", "-e", server, NULL); /* never reaches */ fprintf(stderr,_("Error execing server: %s"), strerror(errno)); exit(1); } } extern int server_connect(const char *username, const char *servername) { int r; if (!username) { username = default_userid(); } /* * Close + free old client connection */ if (client) { client_close(client); client_free(client); } r = client_init(servername, 5000, username, &show_message, NULL, &client); return r; } extern void show_select_game(void) { GtkCombo *combo; GList *gamelist = NULL; /* * Show the games list window */ gamelist_window = create_gamelistwindow (); combo = (GtkCombo *)lookup_widget(gamelist_window, "GameListMenu"); /* * Tell server we want the games list */ client_listgames(client, &gameinfo_cb, &gamelist); gtk_combo_set_popdown_strings(combo, gamelist); /* * show game list window */ gtk_widget_show (gamelist_window); } void on_login_button_clicked (GtkButton *button, gpointer user_data) { GtkEntry *username_entry; GtkEntry *servername_entry; const char *username; const char *servername; int r; /* * Figure out user name */ username_entry = (GtkEntry *)lookup_widget(GTK_WIDGET(button), "username_entry"); username = gtk_entry_get_text(username_entry); /* * Figure out server name */ servername_entry = (GtkEntry *)lookup_widget(GTK_WIDGET(button), "server_entry"); servername = gtk_entry_get_text(servername_entry); r = server_connect(username, servername); if (r) { char msg[1024]; GtkLabel *errormsg; snprintf(msg, sizeof(msg)-1, _("Error connecting to server: %s\n"), servername); errormsg = (GtkLabel *)lookup_widget(GTK_WIDGET(button), "newgame_errormsg"); gtk_label_set_text(errormsg, msg); return; } /* * Hide the newgame window now */ gtk_widget_hide (newgame_window); newgame_window = NULL; show_select_game(); } void on_population_report_activate (GtkMenuItem *menuitem, gpointer user_data) { if (!popreport_window) { popreport_window = create_popreport_window(); setup_population_treeview(popreport_window); } update_population_report(popreport_window, client); gdk_window_raise(popreport_window->window); } void on_popreport_okbutton_clicked (GtkButton *button, gpointer user_data) { gtk_widget_hide (popreport_window); popreport_window = NULL; } void on_finances_activate (GtkMenuItem *menuitem, gpointer user_data) { if (!finances_window) { finances_window = create_Finances(); setup_finances_treeview(finances_window); setup_loans_treeview(finances_window); } update_finances_window(finances_window, client); gdk_window_raise(finances_window->window); } void on_fastest1_activate (GtkMenuItem *menuitem, gpointer user_data) { if (!block_speed_cb) { client_setspeed(client, SPEED_FASTEST); } } void on_fast1_activate (GtkMenuItem *menuitem, gpointer user_data) { if (!block_speed_cb) { client_setspeed(client, SPEED_FAST); } } void on_normal1_activate (GtkMenuItem *menuitem, gpointer user_data) { if (!block_speed_cb) { client_setspeed(client, SPEED_NORMAL); } } void on_slow1_activate (GtkMenuItem *menuitem, gpointer user_data) { if (!block_speed_cb) { client_setspeed(client, SPEED_SLOW); } } void on_paused1_activate (GtkMenuItem *menuitem, gpointer user_data) { if (!block_speed_cb) { client_setspeed(client, SPEED_PAUSED); } } void on_info_okay_buttom_clicked (GtkButton *button, gpointer user_data) { gtk_widget_hide (info_window); } void on_borrow_button_clicked (GtkButton *button, gpointer user_data) { GtkEntry *entry; const char *amount_str; int amount; char *next; entry = (GtkEntry *)lookup_widget(finances_window, "borrow_amount"); amount_str = gtk_entry_get_text(entry); amount = strtoul(amount_str, &next, 10); if ((amount < 0) || (amount > 999999999) || (*next)) { printf(_("Invalid amount\n")); return; } client_borrow(client, amount); gtk_entry_set_text(entry, ""); update_finances_window(finances_window, client); } gboolean on_maindrawingarea_leave_notify_event (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data) { int x, y; GdkModifierType state; int mapx, mapy; /* release any buttons */ mousepressed = 0; gdk_window_get_pointer (widget->window, &x, &y, &state); if (screen_to_mapcoord(screen, x, y, &mapx, &mapy) == 0) { set_cursor(mapx, mapy); } return FALSE; } static void update_label(GtkLabel *label, char *str) { int cnt = 0; gtk_label_set_text(label, str); while (gtk_events_pending() && cnt < 100) { gtk_main_iteration_do(FALSE); cnt++; } } static void * loadimage_cb(char *filename, int request_width, int request_height, int *extra_height, void *rock) { #if 0 char buf[128]; snprintf(buf, sizeof(buf)-1,_("Loading tile: %s"), filename); update_label((GtkLabel *)rock, buf); #endif /* 0 */ return sdlwin_loadimage(filename, request_width, request_height, extra_height, NULL); } extern int select_game(const char *game) { GtkLabel *loadlabel; GtkWidget *load_dialog; timeout_remove(); memset(&display, 0, sizeof(display_t)); display.grid = 1; display.view = GAMEVIEW_NORMAL; display.showbuildings = 1; load_dialog = create_load_dialog(); gtk_widget_show_all (load_dialog); loadlabel = (GtkLabel *)lookup_widget(load_dialog, "load_status_label"); update_label(loadlabel, _("Contacting server")); client_selectgame(client, game); update_label(loadlabel, _("Loading tiles")); if (!tiles) { if (tiles_init(&tiles, "../img/tiles.data", &loadimage_cb, loadlabel)) { if (tiles_init(&tiles, IMG_DIRECTORY "tiles.data", &loadimage_cb, loadlabel)) { printf(_("Error initializing tiles\n")); exit(1); } } } /* * Get game data from server */ update_label(loadlabel, _("Getting map")); map = client_getmap(client, tiles); screen_setmap(screen, map); me = client_getme(client); updatemoney(); set_current_activity("Road"); /* show the goal */ on_menu_report_goal_activate(NULL, NULL); gtk_widget_destroy(load_dialog); timeout_add(); return 0; } static void show_message(char *msg, void *rock) { GtkTextView *textbox; GtkTextBuffer *buffer; int len; if (!textdisp_window) { textdisp_window = create_textdisp_window(); } textbox = (GtkTextView *)lookup_widget(textdisp_window, "textdisp_textbox"); if (!textbox) return; buffer = gtk_text_buffer_new(NULL); gtk_text_buffer_set_text(buffer, msg, -1); gtk_text_view_set_buffer(textbox, buffer); gtk_widget_show (textdisp_window); gdk_window_raise(textdisp_window->window); } void on_menu_report_goal_activate (GtkMenuItem *menuitem, gpointer user_data) { char *goal = client_getgoal(client); show_message(goal, NULL); } void on_payoff_button_clicked (GtkButton *button, gpointer user_data) { GtkTreeIter iter; GtkTreeView *loanview; GtkTreeModel *model; GtkTreeSelection *selection; int num = 0; loanview = (GtkTreeView *)lookup_widget(finances_window, "loansview"); selection = gtk_tree_view_get_selection(loanview); if (!selection) return; gtk_tree_selection_get_selected(selection, &model, &iter); gtk_tree_model_get(model, &iter, 0, &num, -1); client_payoff_loan(client, num); update_finances_window(finances_window, client); } void on_popreport_window_remove (GtkContainer *container, GtkWidget *widget, gpointer user_data) { popreport_window = NULL; } void on_Finances_remove (GtkContainer *container, GtkWidget *widget, gpointer user_data) { finances_window = NULL; } void on_stats_activate (GtkMenuItem *menuitem, gpointer user_data) { if (!stats_window) { stats_window = create_stats_window(); setup_stats_treeview(stats_window); } update_stats_window(stats_window, client); gdk_window_raise(stats_window->window); } void on_stats_okay_buttom_clicked (GtkButton *button, gpointer user_data) { gtk_widget_hide (stats_window); stats_window = NULL; } void on_zoom_in1_activate (GtkMenuItem *menuitem, gpointer user_data) { zoom(1); } void on_zoom_out1_activate (GtkMenuItem *menuitem, gpointer user_data) { zoom(-1); } void on_rotate1_activate (GtkMenuItem *menuitem, gpointer user_data) { int mapx; int mapy; screen_to_mapcoord_screen_center(screen, &mapx, &mapy); screen_rotate(screen, 1); recenter_screen(drawingareawidget, screen, map, mapx, mapy); } void on_buy_land1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity_obj(MAPOBJ_ACTION_BUYLAND); government_enable_landvalue_cache(map); } void on_zone_housing1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("ZoneHouse"); } void on_zone_office1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("ZoneOffice"); } void on_zone_industrial1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("ZoneIndustrial"); } void on_zone_commercial1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("ZoneCommercial"); } void on_zone_farm1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("ZoneFarm"); } void on_road2_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Road"); } void on_trees1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Trees"); } void on_park1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Park"); } void on_pool1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Pool"); } void on_fire_station1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("FireStation"); } static void getrate(char *name) { int rate; GtkSpinButton *spin; char spin_name[100]; rate = client_gettaxrate(client, name); snprintf(spin_name, sizeof(spin_name)-1,"%stax_control", name); spin = (GtkSpinButton *)lookup_widget(taxes_window, spin_name); if (!spin) { printf(_("Error find spincontrol named %s\n"), spin_name); return; } gtk_spin_button_set_value(spin, rate); } static void setrate(char *name) { int rate; GtkSpinButton *spin; char spin_name[100]; snprintf(spin_name, sizeof(spin_name)-1,"%stax_control", name); spin = (GtkSpinButton *)lookup_widget(taxes_window, spin_name); if (!spin) { printf(_("Error find spincontrol named %s\n"), spin_name); return; } rate = gtk_spin_button_get_value_as_int(spin); client_settaxrate(client, name, rate); } void on_tax_rates_activate (GtkMenuItem *menuitem, gpointer user_data) { int i; if (!taxes_window) { taxes_window = create_taxes_window(); } for (i = 0; i < NUM_TAX_TYPES; i++) { getrate(tax_types[i]); } gtk_widget_show (taxes_window); gdk_window_raise(taxes_window->window); } void on_taxes_okbutton_clicked (GtkButton *button, gpointer user_data) { int i; for (i = 0; i < NUM_TAX_TYPES; i++) { setrate(tax_types[i]); } gtk_widget_hide (taxes_window); taxes_window = NULL; } void on_buy_all1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity_obj(MAPOBJ_ACTION_BUYALL); government_enable_landvalue_cache(map); } void on_sell1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity_obj(MAPOBJ_ACTION_SELLLAND); government_enable_landvalue_cache(map); } void on_demolish1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity_obj(MAPOBJ_ACTION_DEMOLISH); } static void setgameview(int view) { display.view = view; screen_moved = 1; } void on_menu_normal_view_activate (GtkMenuItem *menuitem, gpointer user_data) { setgameview(GAMEVIEW_NORMAL); } void on_menu_owner_view_activate (GtkMenuItem *menuitem, gpointer user_data) { setgameview(GAMEVIEW_OWNERS); } void on_police_coverage1_activate (GtkMenuItem *menuitem, gpointer user_data) { setgameview(GAMEVIEW_POLICE_COVER); } void on_hospital_coverage1_activate (GtkMenuItem *menuitem, gpointer user_data) { setgameview(GAMEVIEW_HOSPITAL_COVER); } void on_fire_station_coverage1_activate (GtkMenuItem *menuitem, gpointer user_data) { setgameview(GAMEVIEW_FIRE_COVER); } void on_menu_mine_view_activate (GtkMenuItem *menuitem, gpointer user_data) { setgameview(GAMEVIEW_MINE); } void on_show_buildings_activate (GtkMenuItem *menuitem, gpointer user_data) { display.showbuildings = !display.showbuildings; } void on_gamelistwindow_remove (GtkContainer *container, GtkWidget *widget, gpointer user_data) { gtk_widget_hide (gamelist_window); gamelist_window = NULL; } void on_textdisp_window_remove (GtkContainer *container, GtkWidget *widget, gpointer user_data) { gtk_widget_hide (textdisp_window); textdisp_window = NULL; } void on_stats_window_remove (GtkContainer *container, GtkWidget *widget, gpointer user_data) { gtk_widget_hide (stats_window); stats_window = NULL; } void on_happiness_activate (GtkMenuItem *menuitem, gpointer user_data) { char *msg = client_gethappiness(client); show_message(msg, NULL); } void on_flatten_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity_obj(MAPOBJ_ACTION_FLATTEN); } void on_raise_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity_obj(MAPOBJ_ACTION_RAISE); } void on_lower_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity_obj(MAPOBJ_ACTION_LOWER); } void on_golf_course1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Golf"); } void on_localserverbutton_clicked (GtkButton *button, gpointer user_data) { /* * Try starting local server */ start_local_server(); } void on_info_window_remove (GtkContainer *container, GtkWidget *widget, gpointer user_data) { gtk_widget_hide (info_window); info_window = NULL; } void on_coal_power_plant_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("PowerCoal"); } void on_water_well_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Well"); } void on_garbage_dump_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("DumpEmpty"); } void on_port_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Port"); } void on_sewage_treatment_plant_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Sewage"); } void on_small_school_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("MiniSchool"); } void on_school1_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("School"); } void on_quick_help_activate (GtkMenuItem *menuitem, gpointer user_data) { char *quick_help_msg = _("To get your city started: \n" " \n" "1. Build some roads \n" "2. Build a power plant \n" "3. Zone some housing near roads. People should start building houses \n" "4. Zone some commercial, industrial, and office nearby for people to work\n" "5. To keep people happy you'll need to provide services: schools, police,\n" " hospital, fire stations, etc. \n" "6. Keep track of what's going on with the Reports->Stats window \n" "\n") ; show_message(quick_help_msg, NULL); } void on_gas_power_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("PowerGas"); } void on_well_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Well"); } void on_tower_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Tower"); } void on_landfill_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("DumpEmpty"); } void on_sheriff_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Sheriff"); } void on_police_station_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Police"); } void on_clinic_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Clinic"); } void on_hospital_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("Hospital"); } void on_nuclear_power_plant_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("PowerNuclear"); } void on_university_activate (GtkMenuItem *menuitem, gpointer user_data) { set_current_activity("University"); } void on_StartGameButton_clicked (GtkButton *button, gpointer user_data) { GtkCombo *gamelist; const char *name; gamelist = (GtkCombo *)lookup_widget(gamelist_window, "GameListMenu"); name = gtk_entry_get_text (GTK_ENTRY (gamelist->entry)); gtk_widget_hide (gamelist_window); gamelist_window = NULL; select_game(name); } void on_textdisp_okay_button_clicked (GtkButton *button, gpointer user_data) { gtk_widget_hide(textdisp_window); } void on_finances_okay_button_clicked (GtkButton *button, gpointer user_data) { gtk_widget_hide (finances_window); finances_window = NULL; }