Some miscellaneous updates to main help, for new features and otherwise.
[freeciv.git] / client / options.c
blob73910e0fa5db76cfcface140c5096db98b205d05
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <string.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
22 /* utility */
23 #include "fcintl.h"
24 #include "ioz.h"
25 #include "log.h"
26 #include "mem.h"
27 #include "registry.h"
28 #include "shared.h"
29 #include "string_vector.h"
30 #include "support.h"
32 /* common */
33 #include "events.h"
34 #include "version.h"
36 /* client/agents */
37 #include "cma_fec.h"
39 /* client/include */
40 #include "chatline_g.h"
41 #include "dialogs_g.h"
42 #include "gui_main_g.h"
43 #include "menu_g.h"
44 #include "optiondlg_g.h"
45 #include "repodlgs_g.h"
46 #include "voteinfo_bar_g.h"
48 /* client */
49 #include "audio.h"
50 #include "cityrepdata.h"
51 #include "client_main.h"
52 #include "climisc.h"
53 #include "connectdlg_common.h"
54 #include "global_worklist.h"
55 #include "mapview_common.h"
56 #include "overview_common.h"
57 #include "packhand_gen.h"
58 #include "plrdlg_common.h"
59 #include "repodlgs_common.h"
60 #include "servers.h"
61 #include "themes_common.h"
62 #include "tilespec.h"
64 #include "options.h"
67 /** Defaults for options normally on command line **/
69 char default_user_name[512] = "\0";
70 char default_server_host[512] = "localhost";
71 int default_server_port = DEFAULT_SOCK_PORT;
72 char default_metaserver[512] = DEFAULT_METASERVER_OPTION;
73 char default_tileset_name[512] = "\0";
74 char default_sound_set_name[512] = "stdsounds";
75 char default_sound_plugin_name[512] = "\0";
76 char default_chat_logfile[512] = GUI_DEFAULT_CHAT_LOGFILE;
78 bool save_options_on_exit = TRUE;
79 bool fullscreen_mode = FALSE;
81 /** Migrations **/
82 bool gui_gtk3_migrated_from_gtk2 = FALSE;
84 /** Local Options: **/
86 bool solid_color_behind_units = FALSE;
87 bool sound_bell_at_new_turn = FALSE;
88 int smooth_move_unit_msec = 30;
89 int smooth_center_slide_msec = 200;
90 int smooth_combat_step_msec = 10;
91 bool ai_manual_turn_done = TRUE;
92 bool auto_center_on_unit = TRUE;
93 bool auto_center_on_combat = FALSE;
94 bool auto_center_each_turn = TRUE;
95 bool wakeup_focus = TRUE;
96 bool goto_into_unknown = TRUE;
97 bool center_when_popup_city = TRUE;
98 bool concise_city_production = FALSE;
99 bool auto_turn_done = FALSE;
100 bool meta_accelerators = TRUE;
101 bool ask_city_name = TRUE;
102 bool popup_new_cities = TRUE;
103 bool popup_caravan_arrival = TRUE;
104 bool keyboardless_goto = TRUE;
105 bool enable_cursor_changes = TRUE;
106 bool separate_unit_selection = FALSE;
107 bool unit_selection_clears_orders = TRUE;
108 struct ft_color highlight_our_names = FT_COLOR("#000000", "#FFFF00");
110 bool voteinfo_bar_use = TRUE;
111 bool voteinfo_bar_always_show = FALSE;
112 bool voteinfo_bar_hide_when_not_player = FALSE;
113 bool voteinfo_bar_new_at_front = FALSE;
115 bool autoaccept_tileset_suggestion = FALSE;
116 bool autoaccept_soundset_suggestion = FALSE;
118 /* This option is currently set by the client - not by the user. */
119 bool update_city_text_in_refresh_tile = TRUE;
121 bool draw_city_outlines = TRUE;
122 bool draw_city_output = FALSE;
123 bool draw_map_grid = FALSE;
124 bool draw_city_names = TRUE;
125 bool draw_city_growth = TRUE;
126 bool draw_city_productions = TRUE;
127 bool draw_city_buycost = FALSE;
128 bool draw_city_trade_routes = FALSE;
129 bool draw_terrain = TRUE;
130 bool draw_coastline = FALSE;
131 bool draw_roads_rails = TRUE;
132 bool draw_irrigation = TRUE;
133 bool draw_mines = TRUE;
134 bool draw_fortress_airbase = TRUE;
135 bool draw_specials = TRUE;
136 bool draw_pollution = TRUE;
137 bool draw_cities = TRUE;
138 bool draw_units = TRUE;
139 bool draw_focus_unit = FALSE;
140 bool draw_fog_of_war = TRUE;
141 bool draw_borders = TRUE;
142 bool draw_native = FALSE;
143 bool draw_full_citybar = TRUE;
144 bool draw_unit_shields = TRUE;
145 bool player_dlg_show_dead_players = TRUE;
146 bool reqtree_show_icons = TRUE;
147 bool reqtree_curved_lines = FALSE;
149 /* options for map images */
150 char mapimg_format[64];
151 int mapimg_zoom = 2;
152 /* See the definition of MAPIMG_LAYER in mapimg.h. */
153 bool mapimg_layer[MAPIMG_LAYER_COUNT] = {
154 FALSE, /* a - MAPIMG_LAYER_AREA */
155 TRUE, /* b - MAPIMG_LAYER_BORDERS */
156 TRUE, /* c - MAPIMG_LAYER_CITIES */
157 TRUE, /* f - MAPIMG_LAYER_FOGOFWAR */
158 TRUE, /* k - MAPIMG_LAYER_KNOWLEDGE */
159 TRUE, /* t - MAPIMG_LAYER_TERRAIN */
160 TRUE /* u - MAPIMG_LAYER_UNITS */
162 char mapimg_filename[512];
164 /* gui-gtk-2.0 client specific options. */
165 char gui_gtk2_default_theme_name[512] = FC_GTK2_DEFAULT_THEME_NAME;
166 bool gui_gtk2_map_scrollbars = FALSE;
167 bool gui_gtk2_dialogs_on_top = TRUE;
168 bool gui_gtk2_show_task_icons = TRUE;
169 bool gui_gtk2_enable_tabs = TRUE;
170 bool gui_gtk2_better_fog = TRUE;
171 bool gui_gtk2_show_chat_message_time = FALSE;
172 bool gui_gtk2_new_messages_go_to_top = FALSE;
173 bool gui_gtk2_show_message_window_buttons = TRUE;
174 bool gui_gtk2_metaserver_tab_first = FALSE;
175 bool gui_gtk2_allied_chat_only = FALSE;
176 int gui_gtk2_message_chat_location = GUI_GTK_MSGCHAT_MERGED;
177 bool gui_gtk2_small_display_layout = TRUE;
178 bool gui_gtk2_mouse_over_map_focus = FALSE;
179 bool gui_gtk2_chatline_autocompletion = TRUE;
180 int gui_gtk2_citydlg_xsize = GUI_GTK2_CITYDLG_DEFAULT_XSIZE;
181 int gui_gtk2_citydlg_ysize = GUI_GTK2_CITYDLG_DEFAULT_YSIZE;
182 int gui_gtk2_popup_tech_help = GUI_POPUP_TECH_HELP_RULESET;
183 char gui_gtk2_font_city_label[512] = "Monospace 8";
184 char gui_gtk2_font_notify_label[512] = "Monospace Bold 9";
185 char gui_gtk2_font_spaceship_label[512] = "Monospace 8";
186 char gui_gtk2_font_help_label[512] = "Sans Bold 10";
187 char gui_gtk2_font_help_link[512] = "Sans 9";
188 char gui_gtk2_font_help_text[512] = "Monospace 8";
189 char gui_gtk2_font_chatline[512] = "Monospace 8";
190 char gui_gtk2_font_beta_label[512] = "Sans Italic 10";
191 char gui_gtk2_font_small[512] = "Sans 9";
192 char gui_gtk2_font_comment_label[512] = "Sans Italic 9";
193 char gui_gtk2_font_city_names[512] = "Sans Bold 10";
194 char gui_gtk2_font_city_productions[512] = "Serif 10";
195 char gui_gtk2_font_reqtree_text[512] = "Serif 10";
197 /* gui-gtk-3.0 client specific options. */
198 char gui_gtk3_default_theme_name[512] = FC_GTK3_DEFAULT_THEME_NAME;
199 bool gui_gtk3_map_scrollbars = FALSE;
200 bool gui_gtk3_dialogs_on_top = TRUE;
201 bool gui_gtk3_show_task_icons = TRUE;
202 bool gui_gtk3_enable_tabs = TRUE;
203 bool gui_gtk3_better_fog = TRUE;
204 bool gui_gtk3_show_chat_message_time = FALSE;
205 bool gui_gtk3_new_messages_go_to_top = FALSE;
206 bool gui_gtk3_show_message_window_buttons = TRUE;
207 bool gui_gtk3_metaserver_tab_first = FALSE;
208 bool gui_gtk3_allied_chat_only = FALSE;
209 int gui_gtk3_message_chat_location = GUI_GTK_MSGCHAT_MERGED;
210 bool gui_gtk3_small_display_layout = TRUE;
211 bool gui_gtk3_mouse_over_map_focus = FALSE;
212 bool gui_gtk3_chatline_autocompletion = TRUE;
213 int gui_gtk3_citydlg_xsize = GUI_GTK3_CITYDLG_DEFAULT_XSIZE;
214 int gui_gtk3_citydlg_ysize = GUI_GTK3_CITYDLG_DEFAULT_YSIZE;
215 int gui_gtk3_popup_tech_help = GUI_POPUP_TECH_HELP_RULESET;
216 char gui_gtk3_font_city_label[512] = "Monospace 8";
217 char gui_gtk3_font_notify_label[512] = "Monospace Bold 9";
218 char gui_gtk3_font_spaceship_label[512] = "Monospace 8";
219 char gui_gtk3_font_help_label[512] = "Sans Bold 10";
220 char gui_gtk3_font_help_link[512] = "Sans 9";
221 char gui_gtk3_font_help_text[512] = "Monospace 8";
222 char gui_gtk3_font_chatline[512] = "Monospace 8";
223 char gui_gtk3_font_beta_label[512] = "Sans Italic 10";
224 char gui_gtk3_font_small[512] = "Sans 9";
225 char gui_gtk3_font_comment_label[512] = "Sans Italic 9";
226 char gui_gtk3_font_city_names[512] = "Sans Bold 10";
227 char gui_gtk3_font_city_productions[512] = "Serif 10";
228 char gui_gtk3_font_reqtree_text[512] = "Serif 10";
230 /* gui-sdl client specific options. */
231 char gui_sdl_default_theme_name[512] = FC_SDL_DEFAULT_THEME_NAME;
232 bool gui_sdl_fullscreen = FALSE;
233 struct video_mode gui_sdl_screen = VIDEO_MODE(640, 480);
234 bool gui_sdl_do_cursor_animation = TRUE;
235 bool gui_sdl_use_color_cursors = TRUE;
237 /* gui-qt client specific options. */
238 char gui_qt_font_city_label[512] = "Monospace,8,-1,5,50,0,0,0,0,0";
239 char gui_qt_font_notify_label[512] = "Monospace,8,-1,5,75,0,0,0,0,0";
240 char gui_qt_font_spaceship_label[512] = "Monospace,8,-1,5,50,0,0,0,0,0";
241 char gui_qt_font_help_label[512] = "Sans Serif,10,-1,5,75,0,0,0,0,0";
242 char gui_qt_font_help_link[512] = "Sans Serif,9,-1,5,50,0,0,0,0,0";
243 char gui_qt_font_help_text[512] = "Monospace,8,-1,5,50,0,0,0,0,0";
244 char gui_qt_font_chatline[512] = "Monospace,8,-1,5,50,0,0,0,0,0";
245 char gui_qt_font_beta_label[512] = "Sans Serif,10,-1,5,50,1,0,0,0,0";
246 char gui_qt_font_small[512] = "Sans Serif,9,-1,5,50,0,0,0,0,0";
247 char gui_qt_font_comment_label[512] = "Sans Serif,9,-1,5,50,1,0,0,0,0";
248 char gui_qt_font_city_names[512] = "Sans Serif,10,-1,5,75,0,0,0,0,0";
249 char gui_qt_font_city_productions[512] = "Sans Serif,10,-1,5,50,1,0,0,0,0";
250 char gui_qt_font_reqtree_text[512] = "Sans Serif,10,-1,5,50,1,0,0,0,0";
252 /* Set to TRUE after the first call to options_init(), to avoid the usage
253 * of non-initialized datas when calling the changed callback. */
254 static bool options_fully_initialized = FALSE;
257 /****************************************************************************
258 Option set structure.
259 ****************************************************************************/
260 struct option_set {
261 struct option * (*option_by_number) (int);
262 struct option * (*option_first) (void);
264 int (*category_number) (void);
265 const char * (*category_name) (int);
268 /****************************************************************************
269 Returns the option corresponding of the number in this option set.
270 ****************************************************************************/
271 struct option *optset_option_by_number(const struct option_set *poptset,
272 int id)
274 fc_assert_ret_val(NULL != poptset, NULL);
276 return poptset->option_by_number(id);
279 /****************************************************************************
280 Returns the option corresponding of the name in this option set.
281 ****************************************************************************/
282 struct option *optset_option_by_name(const struct option_set *poptset,
283 const char *name)
285 fc_assert_ret_val(NULL != poptset, NULL);
287 options_iterate(poptset, poption) {
288 if (0 == strcmp(option_name(poption), name)) {
289 return poption;
291 } options_iterate_end;
292 return NULL;
295 /****************************************************************************
296 Returns the first option of this option set.
297 ****************************************************************************/
298 struct option *optset_option_first(const struct option_set *poptset)
300 fc_assert_ret_val(NULL != poptset, NULL);
302 return poptset->option_first();
305 /****************************************************************************
306 Returns the number of categories of this option set.
307 ****************************************************************************/
308 int optset_category_number(const struct option_set *poptset)
310 fc_assert_ret_val(NULL != poptset, 0);
312 return poptset->category_number();
315 /****************************************************************************
316 Returns the name (translated) of the category of this option set.
317 ****************************************************************************/
318 const char *optset_category_name(const struct option_set *poptset,
319 int category)
321 fc_assert_ret_val(NULL != poptset, NULL);
323 return poptset->category_name(category);
327 /****************************************************************************
328 The base class for options.
329 ****************************************************************************/
330 struct option {
331 /* A link to the option set. */
332 const struct option_set *poptset;
333 /* Type of the option. */
334 enum option_type type;
336 /* Common accessors. */
337 const struct option_common_vtable {
338 int (*number) (const struct option *);
339 const char * (*name) (const struct option *);
340 const char * (*description) (const struct option *);
341 const char * (*help_text) (const struct option *);
342 int (*category) (const struct option *);
343 bool (*is_changeable) (const struct option *);
344 struct option * (*next) (const struct option *);
345 } *common_vtable;
346 /* Specific typed accessors. */
347 union {
348 /* Specific boolean accessors (OT_BOOLEAN == type). */
349 const struct option_bool_vtable {
350 bool (*get) (const struct option *);
351 bool (*def) (const struct option *);
352 bool (*set) (struct option *, bool);
353 } *bool_vtable;
354 /* Specific integer accessors (OT_INTEGER == type). */
355 const struct option_int_vtable {
356 int (*get) (const struct option *);
357 int (*def) (const struct option *);
358 int (*minimum) (const struct option *);
359 int (*maximum) (const struct option *);
360 bool (*set) (struct option *, int);
361 } *int_vtable;
362 /* Specific string accessors (OT_STRING == type). */
363 const struct option_str_vtable {
364 const char * (*get) (const struct option *);
365 const char * (*def) (const struct option *);
366 const struct strvec * (*values) (const struct option *);
367 bool (*set) (struct option *, const char *);
368 } *str_vtable;
369 /* Specific enum accessors (OT_ENUM == type). */
370 const struct option_enum_vtable {
371 int (*get) (const struct option *);
372 int (*def) (const struct option *);
373 const struct strvec * (*values) (const struct option *);
374 bool (*set) (struct option *, int);
375 int (*cmp) (const char *, const char *);
376 } *enum_vtable;
377 /* Specific bitwise accessors (OT_BITWISE == type). */
378 const struct option_bitwise_vtable {
379 unsigned (*get) (const struct option *);
380 unsigned (*def) (const struct option *);
381 const struct strvec * (*values) (const struct option *);
382 bool (*set) (struct option *, unsigned);
383 } *bitwise_vtable;
384 /* Specific font accessors (OT_FONT == type). */
385 const struct option_font_vtable {
386 const char * (*get) (const struct option *);
387 const char * (*def) (const struct option *);
388 const char * (*target) (const struct option *);
389 bool (*set) (struct option *, const char *);
390 } *font_vtable;
391 /* Specific color accessors (OT_COLOR == type). */
392 const struct option_color_vtable {
393 struct ft_color (*get) (const struct option *);
394 struct ft_color (*def) (const struct option *);
395 bool (*set) (struct option *, struct ft_color);
396 } *color_vtable;
397 /* Specific video mode accessors (OT_VIDEO_MODE == type). */
398 const struct option_video_mode_vtable {
399 struct video_mode (*get) (const struct option *);
400 struct video_mode (*def) (const struct option *);
401 bool (*set) (struct option *, struct video_mode);
402 } *video_mode_vtable;
405 /* Called after the value changed. */
406 void (*changed_callback) (struct option *option);
408 /* Volatile. */
409 void *gui_data;
412 #define OPTION(poption) ((struct option *) (poption))
414 #define OPTION_INIT(optset, spec_type, spec_table_var, common_table, \
415 spec_table, changed_cb) { \
416 .poptset = optset, \
417 .type = spec_type, \
418 .common_vtable = &common_table, \
420 .spec_table_var = &spec_table \
421 }, \
422 .changed_callback = changed_cb, \
423 .gui_data = NULL \
425 #define OPTION_BOOL_INIT(optset, common_table, bool_table, changed_cb) \
426 OPTION_INIT(optset, OT_BOOLEAN, bool_vtable, common_table, bool_table, \
427 changed_cb)
428 #define OPTION_INT_INIT(optset, common_table, int_table, changed_cb) \
429 OPTION_INIT(optset, OT_INTEGER, int_vtable, common_table, int_table, \
430 changed_cb)
431 #define OPTION_STR_INIT(optset, common_table, str_table, changed_cb) \
432 OPTION_INIT(optset, OT_STRING, str_vtable, common_table, str_table, \
433 changed_cb)
434 #define OPTION_ENUM_INIT(optset, common_table, enum_table, changed_cb) \
435 OPTION_INIT(optset, OT_ENUM, enum_vtable, common_table, enum_table, \
436 changed_cb)
437 #define OPTION_BITWISE_INIT(optset, common_table, bitwise_table, \
438 changed_cb) \
439 OPTION_INIT(optset, OT_BITWISE, bitwise_vtable, common_table, \
440 bitwise_table, changed_cb)
441 #define OPTION_FONT_INIT(optset, common_table, font_table, changed_cb) \
442 OPTION_INIT(optset, OT_FONT, font_vtable, common_table, font_table, \
443 changed_cb)
444 #define OPTION_COLOR_INIT(optset, common_table, color_table, changed_cb) \
445 OPTION_INIT(optset, OT_COLOR, color_vtable, common_table, color_table, \
446 changed_cb)
447 #define OPTION_VIDEO_MODE_INIT(optset, common_table, video_mode_table, \
448 changed_cb) \
449 OPTION_INIT(optset, OT_VIDEO_MODE, video_mode_vtable, common_table, \
450 video_mode_table, changed_cb)
453 /****************************************************************************
454 Returns the option set owner of this option.
455 ****************************************************************************/
456 const struct option_set *option_optset(const struct option *poption)
458 fc_assert_ret_val(NULL != poption, NULL);
460 return poption->poptset;
463 /****************************************************************************
464 Returns the number of the option.
465 ****************************************************************************/
466 int option_number(const struct option *poption)
468 fc_assert_ret_val(NULL != poption, -1);
470 return poption->common_vtable->number(poption);
473 /****************************************************************************
474 Returns the name of the option.
475 ****************************************************************************/
476 const char *option_name(const struct option *poption)
478 fc_assert_ret_val(NULL != poption, NULL);
480 return poption->common_vtable->name(poption);
483 /****************************************************************************
484 Returns the description (translated) of the option.
485 ****************************************************************************/
486 const char *option_description(const struct option *poption)
488 fc_assert_ret_val(NULL != poption, NULL);
490 return poption->common_vtable->description(poption);
493 /****************************************************************************
494 Returns the help text (translated) of the option.
495 ****************************************************************************/
496 const char *option_help_text(const struct option *poption)
498 fc_assert_ret_val(NULL != poption, NULL);
500 return poption->common_vtable->help_text(poption);
503 /****************************************************************************
504 Returns the type of the option.
505 ****************************************************************************/
506 enum option_type option_type(const struct option *poption)
508 fc_assert_ret_val(NULL != poption, -1);
510 return poption->type;
513 /****************************************************************************
514 Returns the category of the option.
515 ****************************************************************************/
516 int option_category(const struct option *poption)
518 fc_assert_ret_val(NULL != poption, -1);
520 return poption->common_vtable->category(poption);
523 /****************************************************************************
524 Returns the name (tranlated) of the category of the option.
525 ****************************************************************************/
526 const char *option_category_name(const struct option *poption)
528 fc_assert_ret_val(NULL != poption, NULL);
530 return optset_category_name(poption->poptset,
531 poption->common_vtable->category(poption));
534 /****************************************************************************
535 Returns TRUE if this option can be modified.
536 ****************************************************************************/
537 bool option_is_changeable(const struct option *poption)
539 fc_assert_ret_val(NULL != poption, FALSE);
541 return poption->common_vtable->is_changeable(poption);
544 /****************************************************************************
545 Returns the next option or NULL if this is the last.
546 ****************************************************************************/
547 struct option *option_next(const struct option *poption)
549 fc_assert_ret_val(NULL != poption, NULL);
551 return poption->common_vtable->next(poption);
554 /****************************************************************************
555 Set the option to its default value. Returns TRUE if the option changed.
556 ****************************************************************************/
557 bool option_reset(struct option *poption)
559 fc_assert_ret_val(NULL != poption, FALSE);
561 switch (option_type(poption)) {
562 case OT_BOOLEAN:
563 return option_bool_set(poption, option_bool_def(poption));
564 case OT_INTEGER:
565 return option_int_set(poption, option_int_def(poption));
566 case OT_STRING:
567 return option_str_set(poption, option_str_def(poption));
568 case OT_ENUM:
569 return option_enum_set_int(poption, option_enum_def_int(poption));
570 case OT_BITWISE:
571 return option_bitwise_set(poption, option_bitwise_def(poption));
572 case OT_FONT:
573 return option_font_set(poption, option_font_def(poption));
574 case OT_COLOR:
575 return option_color_set(poption, option_color_def(poption));
576 case OT_VIDEO_MODE:
577 return option_video_mode_set(poption, option_video_mode_def(poption));
579 return FALSE;
582 /****************************************************************************
583 Set the function to call every time this option changes. Can be NULL.
584 ****************************************************************************/
585 void option_set_changed_callback(struct option *poption,
586 void (*callback) (struct option *))
588 fc_assert_ret(NULL != poption);
590 poption->changed_callback = callback;
593 /****************************************************************************
594 Force to use the option changed callback.
595 ****************************************************************************/
596 void option_changed(struct option *poption)
598 fc_assert_ret(NULL != poption);
600 if (!options_fully_initialized) {
601 /* Prevent to use non-initialized datas. */
602 return;
605 if (poption->changed_callback) {
606 poption->changed_callback(poption);
609 option_gui_update(poption);
612 /****************************************************************************
613 Set the gui data for this option.
614 ****************************************************************************/
615 void option_set_gui_data(struct option *poption, void *data)
617 fc_assert_ret(NULL != poption);
619 poption->gui_data = data;
622 /****************************************************************************
623 Returns the gui data of this option.
624 ****************************************************************************/
625 void *option_get_gui_data(const struct option *poption)
627 fc_assert_ret_val(NULL != poption, NULL);
629 return poption->gui_data;
632 /****************************************************************************
633 Returns the current value of this boolean option.
634 ****************************************************************************/
635 bool option_bool_get(const struct option *poption)
637 fc_assert_ret_val(NULL != poption, FALSE);
638 fc_assert_ret_val(OT_BOOLEAN == poption->type, FALSE);
640 return poption->bool_vtable->get(poption);
643 /****************************************************************************
644 Returns the default value of this boolean option.
645 ****************************************************************************/
646 bool option_bool_def(const struct option *poption)
648 fc_assert_ret_val(NULL != poption, FALSE);
649 fc_assert_ret_val(OT_BOOLEAN == poption->type, FALSE);
651 return poption->bool_vtable->def(poption);
654 /****************************************************************************
655 Sets the value of this boolean option. Returns TRUE if the value changed.
656 ****************************************************************************/
657 bool option_bool_set(struct option *poption, bool val)
659 fc_assert_ret_val(NULL != poption, FALSE);
660 fc_assert_ret_val(OT_BOOLEAN == poption->type, FALSE);
662 if (poption->bool_vtable->set(poption, val)) {
663 option_changed(poption);
664 return TRUE;
666 return FALSE;
669 /****************************************************************************
670 Returns the current value of this integer option.
671 ****************************************************************************/
672 int option_int_get(const struct option *poption)
674 fc_assert_ret_val(NULL != poption, 0);
675 fc_assert_ret_val(OT_INTEGER == poption->type, 0);
677 return poption->int_vtable->get(poption);
680 /****************************************************************************
681 Returns the default value of this integer option.
682 ****************************************************************************/
683 int option_int_def(const struct option *poption)
685 fc_assert_ret_val(NULL != poption, 0);
686 fc_assert_ret_val(OT_INTEGER == poption->type, 0);
688 return poption->int_vtable->def(poption);
691 /****************************************************************************
692 Returns the minimal value of this integer option.
693 ****************************************************************************/
694 int option_int_min(const struct option *poption)
696 fc_assert_ret_val(NULL != poption, 0);
697 fc_assert_ret_val(OT_INTEGER == poption->type, 0);
699 return poption->int_vtable->minimum(poption);
702 /****************************************************************************
703 Returns the maximal value of this integer option.
704 ****************************************************************************/
705 int option_int_max(const struct option *poption)
707 fc_assert_ret_val(NULL != poption, 0);
708 fc_assert_ret_val(OT_INTEGER == poption->type, 0);
710 return poption->int_vtable->maximum(poption);
713 /****************************************************************************
714 Sets the value of this integer option. Returns TRUE if the value changed.
715 ****************************************************************************/
716 bool option_int_set(struct option *poption, int val)
718 fc_assert_ret_val(NULL != poption, FALSE);
719 fc_assert_ret_val(OT_INTEGER == poption->type, FALSE);
721 if (poption->int_vtable->set(poption, val)) {
722 option_changed(poption);
723 return TRUE;
725 return FALSE;
728 /****************************************************************************
729 Returns the current value of this string option.
730 ****************************************************************************/
731 const char *option_str_get(const struct option *poption)
733 fc_assert_ret_val(NULL != poption, NULL);
734 fc_assert_ret_val(OT_STRING == poption->type, NULL);
736 return poption->str_vtable->get(poption);
739 /****************************************************************************
740 Returns the default value of this string option.
741 ****************************************************************************/
742 const char *option_str_def(const struct option *poption)
744 fc_assert_ret_val(NULL != poption, NULL);
745 fc_assert_ret_val(OT_STRING == poption->type, NULL);
747 return poption->str_vtable->def(poption);
750 /****************************************************************************
751 Returns the possible string values of this string option.
752 ****************************************************************************/
753 const struct strvec *option_str_values(const struct option *poption)
755 fc_assert_ret_val(NULL != poption, NULL);
756 fc_assert_ret_val(OT_STRING == poption->type, NULL);
758 return poption->str_vtable->values(poption);
761 /****************************************************************************
762 Sets the value of this string option. Returns TRUE if the value changed.
763 ****************************************************************************/
764 bool option_str_set(struct option *poption, const char *str)
766 fc_assert_ret_val(NULL != poption, FALSE);
767 fc_assert_ret_val(OT_STRING == poption->type, FALSE);
768 fc_assert_ret_val(NULL != str, FALSE);
770 if (poption->str_vtable->set(poption, str)) {
771 option_changed(poption);
772 return TRUE;
774 return FALSE;
777 /****************************************************************************
778 Returns the value corresponding to the user-visible (translatable but not
779 translated) string. Returns -1 if not matched.
780 ****************************************************************************/
781 int option_enum_str_to_int(const struct option *poption, const char *str)
783 const struct strvec *values;
784 int val;
786 fc_assert_ret_val(NULL != poption, -1);
787 fc_assert_ret_val(OT_ENUM == poption->type, -1);
788 values = poption->enum_vtable->values(poption);
789 fc_assert_ret_val(NULL != values, -1);
791 for (val = 0; val < strvec_size(values); val++) {
792 if (0 == poption->enum_vtable->cmp(strvec_get(values, val), str)) {
793 return val;
796 return -1;
799 /****************************************************************************
800 Returns the user-visible (translatable but not translated) string
801 corresponding to the value. Returns NULL on error.
802 ****************************************************************************/
803 const char *option_enum_int_to_str(const struct option *poption, int val)
805 const struct strvec *values;
807 fc_assert_ret_val(NULL != poption, NULL);
808 fc_assert_ret_val(OT_ENUM == poption->type, NULL);
809 values = poption->enum_vtable->values(poption);
810 fc_assert_ret_val(NULL != values, NULL);
812 return strvec_get(values, val);
815 /****************************************************************************
816 Returns the current value of this enum option (as an integer).
817 ****************************************************************************/
818 int option_enum_get_int(const struct option *poption)
820 fc_assert_ret_val(NULL != poption, -1);
821 fc_assert_ret_val(OT_ENUM == poption->type, -1);
823 return poption->enum_vtable->get(poption);
826 /****************************************************************************
827 Returns the current value of this enum option as a user-visible
828 (translatable but not translated) string.
829 ****************************************************************************/
830 const char *option_enum_get_str(const struct option *poption)
832 fc_assert_ret_val(NULL != poption, NULL);
833 fc_assert_ret_val(OT_ENUM == poption->type, NULL);
835 return strvec_get(poption->enum_vtable->values(poption),
836 poption->enum_vtable->get(poption));
839 /****************************************************************************
840 Returns the default value of this enum option (as an integer).
841 ****************************************************************************/
842 int option_enum_def_int(const struct option *poption)
844 fc_assert_ret_val(NULL != poption, -1);
845 fc_assert_ret_val(OT_ENUM == poption->type, -1);
847 return poption->enum_vtable->def(poption);
850 /****************************************************************************
851 Returns the default value of this enum option as a user-visible
852 (translatable but not translated) string.
853 ****************************************************************************/
854 const char *option_enum_def_str(const struct option *poption)
856 fc_assert_ret_val(NULL != poption, NULL);
857 fc_assert_ret_val(OT_ENUM == poption->type, NULL);
859 return strvec_get(poption->enum_vtable->values(poption),
860 poption->enum_vtable->def(poption));
863 /****************************************************************************
864 Returns the possible string values of this enum option, as user-visible
865 (translatable but not translated) strings.
866 ****************************************************************************/
867 const struct strvec *option_enum_values(const struct option *poption)
869 fc_assert_ret_val(NULL != poption, NULL);
870 fc_assert_ret_val(OT_ENUM == poption->type, NULL);
872 return poption->enum_vtable->values(poption);
875 /****************************************************************************
876 Sets the value of this enum option. Returns TRUE if the value changed.
877 ****************************************************************************/
878 bool option_enum_set_int(struct option *poption, int val)
880 fc_assert_ret_val(NULL != poption, FALSE);
881 fc_assert_ret_val(OT_ENUM == poption->type, FALSE);
883 if (poption->enum_vtable->set(poption, val)) {
884 option_changed(poption);
885 return TRUE;
887 return FALSE;
890 /****************************************************************************
891 Sets the value of this enum option from a string, which is matched as a
892 user-visible (translatable but not translated) string. Returns TRUE if the
893 value changed.
894 ****************************************************************************/
895 bool option_enum_set_str(struct option *poption, const char *str)
897 fc_assert_ret_val(NULL != poption, FALSE);
898 fc_assert_ret_val(OT_ENUM == poption->type, FALSE);
899 fc_assert_ret_val(NULL != str, FALSE);
901 if (poption->enum_vtable->set(poption,
902 option_enum_str_to_int(poption, str))) {
903 option_changed(poption);
904 return TRUE;
906 return FALSE;
909 /****************************************************************************
910 Returns the current value of this bitwise option.
911 ****************************************************************************/
912 unsigned option_bitwise_get(const struct option *poption)
914 fc_assert_ret_val(NULL != poption, 0);
915 fc_assert_ret_val(OT_BITWISE == poption->type, 0);
917 return poption->bitwise_vtable->get(poption);
920 /****************************************************************************
921 Returns the default value of this bitwise option.
922 ****************************************************************************/
923 unsigned option_bitwise_def(const struct option *poption)
925 fc_assert_ret_val(NULL != poption, 0);
926 fc_assert_ret_val(OT_BITWISE == poption->type, 0);
928 return poption->bitwise_vtable->def(poption);
931 /****************************************************************************
932 Returns the mask of this bitwise option.
933 ****************************************************************************/
934 unsigned option_bitwise_mask(const struct option *poption)
936 const struct strvec *values;
938 fc_assert_ret_val(NULL != poption, 0);
939 fc_assert_ret_val(OT_BITWISE == poption->type, 0);
941 values = poption->bitwise_vtable->values(poption);
942 fc_assert_ret_val(NULL != values, 0);
944 return (1 << strvec_size(values)) - 1;
947 /****************************************************************************
948 Returns a vector of strings describing every bit of this option, as
949 user-visible (translatable but not translated) strings.
950 ****************************************************************************/
951 const struct strvec *option_bitwise_values(const struct option *poption)
953 fc_assert_ret_val(NULL != poption, NULL);
954 fc_assert_ret_val(OT_BITWISE == poption->type, NULL);
956 return poption->bitwise_vtable->values(poption);
959 /****************************************************************************
960 Sets the value of this bitwise option. Returns TRUE if the value changed.
961 ****************************************************************************/
962 bool option_bitwise_set(struct option *poption, unsigned val)
964 fc_assert_ret_val(NULL != poption, FALSE);
965 fc_assert_ret_val(OT_BITWISE == poption->type, FALSE);
967 if (0 != (val & ~option_bitwise_mask(poption))
968 || !poption->bitwise_vtable->set(poption, val)) {
969 return FALSE;
972 option_changed(poption);
973 return TRUE;
976 /****************************************************************************
977 Returns the current value of this font option.
978 ****************************************************************************/
979 const char *option_font_get(const struct option *poption)
981 fc_assert_ret_val(NULL != poption, NULL);
982 fc_assert_ret_val(OT_FONT == poption->type, NULL);
984 return poption->font_vtable->get(poption);
987 /****************************************************************************
988 Returns the default value of this font option.
989 ****************************************************************************/
990 const char *option_font_def(const struct option *poption)
992 fc_assert_ret_val(NULL != poption, NULL);
993 fc_assert_ret_val(OT_FONT == poption->type, NULL);
995 return poption->font_vtable->def(poption);
998 /****************************************************************************
999 Returns the target style name of this font option.
1000 ****************************************************************************/
1001 const char *option_font_target(const struct option *poption)
1003 fc_assert_ret_val(NULL != poption, NULL);
1004 fc_assert_ret_val(OT_FONT == poption->type, NULL);
1006 return poption->font_vtable->target(poption);
1009 /****************************************************************************
1010 Sets the value of this font option. Returns TRUE if the value changed.
1011 ****************************************************************************/
1012 bool option_font_set(struct option *poption, const char *font)
1014 fc_assert_ret_val(NULL != poption, FALSE);
1015 fc_assert_ret_val(OT_FONT == poption->type, FALSE);
1016 fc_assert_ret_val(NULL != font, FALSE);
1018 if (poption->font_vtable->set(poption, font)) {
1019 option_changed(poption);
1020 return TRUE;
1022 return FALSE;
1025 /****************************************************************************
1026 Returns the current value of this color option.
1027 ****************************************************************************/
1028 struct ft_color option_color_get(const struct option *poption)
1030 fc_assert_ret_val(NULL != poption, ft_color(NULL, NULL));
1031 fc_assert_ret_val(OT_COLOR == poption->type, ft_color(NULL, NULL));
1033 return poption->color_vtable->get(poption);
1036 /****************************************************************************
1037 Returns the default value of this color option.
1038 ****************************************************************************/
1039 struct ft_color option_color_def(const struct option *poption)
1041 fc_assert_ret_val(NULL != poption, ft_color(NULL, NULL));
1042 fc_assert_ret_val(OT_COLOR == poption->type, ft_color(NULL, NULL));
1044 return poption->color_vtable->def(poption);
1047 /****************************************************************************
1048 Sets the value of this color option. Returns TRUE if the value
1049 changed.
1050 ****************************************************************************/
1051 bool option_color_set(struct option *poption, struct ft_color color)
1053 fc_assert_ret_val(NULL != poption, FALSE);
1054 fc_assert_ret_val(OT_COLOR == poption->type, FALSE);
1056 if (poption->color_vtable->set(poption, color)) {
1057 option_changed(poption);
1058 return TRUE;
1060 return FALSE;
1063 /****************************************************************************
1064 Returns the current value of this video mode option.
1065 ****************************************************************************/
1066 struct video_mode option_video_mode_get(const struct option *poption)
1068 fc_assert_ret_val(NULL != poption, video_mode(-1, -1));
1069 fc_assert_ret_val(OT_VIDEO_MODE == poption->type, video_mode(-1, -1));
1071 return poption->video_mode_vtable->get(poption);
1074 /****************************************************************************
1075 Returns the default value of this video mode option.
1076 ****************************************************************************/
1077 struct video_mode option_video_mode_def(const struct option *poption)
1079 fc_assert_ret_val(NULL != poption, video_mode(-1, -1));
1080 fc_assert_ret_val(OT_VIDEO_MODE == poption->type, video_mode(-1, -1));
1082 return poption->video_mode_vtable->def(poption);
1085 /****************************************************************************
1086 Sets the value of this video mode option. Returns TRUE if the value
1087 changed.
1088 ****************************************************************************/
1089 bool option_video_mode_set(struct option *poption, struct video_mode mode)
1091 fc_assert_ret_val(NULL != poption, FALSE);
1092 fc_assert_ret_val(OT_VIDEO_MODE == poption->type, FALSE);
1094 if (poption->video_mode_vtable->set(poption, mode)) {
1095 option_changed(poption);
1096 return TRUE;
1098 return FALSE;
1102 /****************************************************************************
1103 Client option set.
1104 ****************************************************************************/
1105 static struct option *client_optset_option_by_number(int id);
1106 static struct option *client_optset_option_first(void);
1107 static int client_optset_category_number(void);
1108 static const char *client_optset_category_name(int category);
1110 static struct option_set client_optset_static = {
1111 .option_by_number = client_optset_option_by_number,
1112 .option_first = client_optset_option_first,
1113 .category_number = client_optset_category_number,
1114 .category_name = client_optset_category_name
1116 const struct option_set *client_optset = &client_optset_static;
1118 struct copt_val_name {
1119 const char *support; /* Untranslated long support name, used
1120 * for saving. */
1121 const char *pretty; /* Translated, used to display to the
1122 * users. */
1125 /****************************************************************************
1126 Virtuals tables for the client options.
1127 ****************************************************************************/
1128 static int client_option_number(const struct option *poption);
1129 static const char *client_option_name(const struct option *poption);
1130 static const char *client_option_description(const struct option *poption);
1131 static const char *client_option_help_text(const struct option *poption);
1132 static int client_option_category(const struct option *poption);
1133 static bool client_option_is_changeable(const struct option *poption);
1134 static struct option *client_option_next(const struct option *poption);
1136 static const struct option_common_vtable client_option_common_vtable = {
1137 .number = client_option_number,
1138 .name = client_option_name,
1139 .description = client_option_description,
1140 .help_text = client_option_help_text,
1141 .category = client_option_category,
1142 .is_changeable = client_option_is_changeable,
1143 .next = client_option_next
1146 static bool client_option_bool_get(const struct option *poption);
1147 static bool client_option_bool_def(const struct option *poption);
1148 static bool client_option_bool_set(struct option *poption, bool val);
1150 static const struct option_bool_vtable client_option_bool_vtable = {
1151 .get = client_option_bool_get,
1152 .def = client_option_bool_def,
1153 .set = client_option_bool_set
1156 static int client_option_int_get(const struct option *poption);
1157 static int client_option_int_def(const struct option *poption);
1158 static int client_option_int_min(const struct option *poption);
1159 static int client_option_int_max(const struct option *poption);
1160 static bool client_option_int_set(struct option *poption, int val);
1162 static const struct option_int_vtable client_option_int_vtable = {
1163 .get = client_option_int_get,
1164 .def = client_option_int_def,
1165 .minimum = client_option_int_min,
1166 .maximum = client_option_int_max,
1167 .set = client_option_int_set
1170 static const char *client_option_str_get(const struct option *poption);
1171 static const char *client_option_str_def(const struct option *poption);
1172 static const struct strvec *
1173 client_option_str_values(const struct option *poption);
1174 static bool client_option_str_set(struct option *poption, const char *str);
1176 static const struct option_str_vtable client_option_str_vtable = {
1177 .get = client_option_str_get,
1178 .def = client_option_str_def,
1179 .values = client_option_str_values,
1180 .set = client_option_str_set
1183 static int client_option_enum_get(const struct option *poption);
1184 static int client_option_enum_def(const struct option *poption);
1185 static const struct strvec *
1186 client_option_enum_pretty_names(const struct option *poption);
1187 static bool client_option_enum_set(struct option *poption, int val);
1189 static const struct option_enum_vtable client_option_enum_vtable = {
1190 .get = client_option_enum_get,
1191 .def = client_option_enum_def,
1192 .values = client_option_enum_pretty_names,
1193 .set = client_option_enum_set,
1194 .cmp = fc_strcasecmp
1197 static unsigned client_option_bitwise_get(const struct option *poption);
1198 static unsigned client_option_bitwise_def(const struct option *poption);
1199 static const struct strvec *
1200 client_option_bitwise_pretty_names(const struct option *poption);
1201 static bool client_option_bitwise_set(struct option *poption, unsigned val);
1203 static const struct option_bitwise_vtable client_option_bitwise_vtable = {
1204 .get = client_option_bitwise_get,
1205 .def = client_option_bitwise_def,
1206 .values = client_option_bitwise_pretty_names,
1207 .set = client_option_bitwise_set
1210 static const char *client_option_font_get(const struct option *poption);
1211 static const char *client_option_font_def(const struct option *poption);
1212 static const char *client_option_font_target(const struct option *poption);
1213 static bool client_option_font_set(struct option *poption, const char *font);
1215 static const struct option_font_vtable client_option_font_vtable = {
1216 .get = client_option_font_get,
1217 .def = client_option_font_def,
1218 .target = client_option_font_target,
1219 .set = client_option_font_set
1222 static struct ft_color client_option_color_get(const struct option *poption);
1223 static struct ft_color client_option_color_def(const struct option *poption);
1224 static bool client_option_color_set(struct option *poption,
1225 struct ft_color color);
1227 static const struct option_color_vtable client_option_color_vtable = {
1228 .get = client_option_color_get,
1229 .def = client_option_color_def,
1230 .set = client_option_color_set
1233 static struct video_mode
1234 client_option_video_mode_get(const struct option *poption);
1235 static struct video_mode
1236 client_option_video_mode_def(const struct option *poption);
1237 static bool client_option_video_mode_set(struct option *poption,
1238 struct video_mode mode);
1240 static const struct option_video_mode_vtable client_option_video_mode_vtable = {
1241 .get = client_option_video_mode_get,
1242 .def = client_option_video_mode_def,
1243 .set = client_option_video_mode_set
1246 enum client_option_category {
1247 COC_GRAPHICS,
1248 COC_OVERVIEW,
1249 COC_SOUND,
1250 COC_INTERFACE,
1251 COC_MAPIMG,
1252 COC_NETWORK,
1253 COC_FONT,
1254 COC_MAX
1257 /****************************************************************************
1258 Derived class client option, inherinting of base class option.
1259 ****************************************************************************/
1260 struct client_option {
1261 struct option base_option; /* Base structure, must be the first! */
1263 const char *name; /* Short name - used as an identifier */
1264 const char *description; /* One-line description */
1265 const char *help_text; /* Paragraph-length help text */
1266 enum client_option_category category;
1267 enum gui_type specific; /* GUI_STUB for common options. */
1269 union {
1270 /* OT_BOOLEAN type option. */
1271 struct {
1272 bool *const pvalue;
1273 const bool def;
1274 } boolean;
1275 /* OT_INTEGER type option. */
1276 struct {
1277 int *const pvalue;
1278 const int def, min, max;
1279 } integer;
1280 /* OT_STRING type option. */
1281 struct {
1282 char *const pvalue;
1283 const size_t size;
1284 const char *const def;
1286 * A function to return a string vector of possible string values,
1287 * or NULL for none.
1289 const struct strvec *(*const val_accessor) (void);
1290 } string;
1291 /* OT_ENUM type option. */
1292 struct {
1293 int *const pvalue;
1294 const int def;
1295 struct strvec *support_names, *pretty_names; /* untranslated */
1296 const struct copt_val_name * (*const name_accessor) (int value);
1297 } enumerator;
1298 /* OT_BITWISE type option. */
1299 struct {
1300 unsigned *const pvalue;
1301 const unsigned def;
1302 struct strvec *support_names, *pretty_names; /* untranslated */
1303 const struct copt_val_name * (*const name_accessor) (int value);
1304 } bitwise;
1305 /* OT_FONT type option. */
1306 struct {
1307 char *const pvalue;
1308 const size_t size;
1309 const char *const def;
1310 const char *const target;
1311 } font;
1312 /* OT_COLOR type option. */
1313 struct {
1314 struct ft_color *const pvalue;
1315 const struct ft_color def;
1316 } color;
1317 /* OT_VIDEO_MODE type option. */
1318 struct {
1319 struct video_mode *const pvalue;
1320 const struct video_mode def;
1321 } video_mode;
1325 #define CLIENT_OPTION(poption) ((struct client_option *) (poption))
1328 * Generate a client option of type OT_BOOLEAN.
1330 * oname: The option data. Note it is used as name to be loaded or saved.
1331 * So, you shouldn't change the name of this variable in any case.
1332 * odesc: A short description of the client option. Should be used with the
1333 * N_() macro.
1334 * ohelp: The help text for the client option. Should be used with the N_()
1335 * macro.
1336 * ocat: The client_option_class of this client option.
1337 * ospec: A gui_type enumerator which determin for what particular client
1338 * gui this option is for. Sets to GUI_STUB for common options.
1339 * odef: The default value of this client option (FALSE or TRUE).
1340 * ocb: A callback function of type void (*)(struct option *) called when
1341 * the option changed.
1343 #define GEN_BOOL_OPTION(oname, odesc, ohelp, ocat, ospec, odef, ocb) \
1345 .base_option = OPTION_BOOL_INIT(&client_optset_static, \
1346 client_option_common_vtable, \
1347 client_option_bool_vtable, ocb), \
1348 .name = #oname, \
1349 .description = odesc, \
1350 .help_text = ohelp, \
1351 .category = ocat, \
1352 .specific = ospec, \
1354 .boolean = { \
1355 .pvalue = &oname, \
1356 .def = odef, \
1358 }, \
1362 * Generate a client option of type OT_INTEGER.
1364 * oname: The option data. Note it is used as name to be loaded or saved.
1365 * So, you shouldn't change the name of this variable in any case.
1366 * odesc: A short description of the client option. Should be used with the
1367 * N_() macro.
1368 * ohelp: The help text for the client option. Should be used with the N_()
1369 * macro.
1370 * ocat: The client_option_class of this client option.
1371 * ospec: A gui_type enumerator which determin for what particular client
1372 * gui this option is for. Sets to GUI_STUB for common options.
1373 * odef: The default value of this client option.
1374 * omin: The minimal value of this client option.
1375 * omax: The maximal value of this client option.
1376 * ocb: A callback function of type void (*)(struct option *) called when
1377 * the option changed.
1379 #define GEN_INT_OPTION(oname, odesc, ohelp, ocat, ospec, odef, omin, omax, ocb) \
1381 .base_option = OPTION_INT_INIT(&client_optset_static, \
1382 client_option_common_vtable, \
1383 client_option_int_vtable, ocb), \
1384 .name = #oname, \
1385 .description = odesc, \
1386 .help_text = ohelp, \
1387 .category = ocat, \
1388 .specific = ospec, \
1390 .integer = { \
1391 .pvalue = &oname, \
1392 .def = odef, \
1393 .min = omin, \
1394 .max = omax \
1396 }, \
1400 * Generate a client option of type OT_STRING.
1402 * oname: The option data. Note it is used as name to be loaded or saved.
1403 * So, you shouldn't change the name of this variable in any case.
1404 * Be sure to pass the array variable and not a pointer to it because
1405 * the size is calculated with sizeof().
1406 * odesc: A short description of the client option. Should be used with the
1407 * N_() macro.
1408 * ohelp: The help text for the client option. Should be used with the N_()
1409 * macro.
1410 * ocat: The client_option_class of this client option.
1411 * ospec: A gui_type enumerator which determines for what particular client
1412 * gui this option is for. Set to GUI_STUB for common options.
1413 * odef: The default string for this client option.
1414 * ocb: A callback function of type void (*)(struct option *) called when
1415 * the option changed.
1417 #define GEN_STR_OPTION(oname, odesc, ohelp, ocat, ospec, odef, ocb) \
1419 .base_option = OPTION_STR_INIT(&client_optset_static, \
1420 client_option_common_vtable, \
1421 client_option_str_vtable, ocb), \
1422 .name = #oname, \
1423 .description = odesc, \
1424 .help_text = ohelp, \
1425 .category = ocat, \
1426 .specific = ospec, \
1428 .string = { \
1429 .pvalue = oname, \
1430 .size = sizeof(oname), \
1431 .def = odef, \
1432 .val_accessor = NULL \
1434 }, \
1438 * Generate a client option of type OT_STRING with a string accessor
1439 * function.
1441 * oname: The option data. Note it is used as name to be loaded or saved.
1442 * So, you shouldn't change the name of this variable in any case.
1443 * Be sure to pass the array variable and not a pointer to it because
1444 * the size is calculated with sizeof().
1445 * odesc: A short description of the client option. Should be used with the
1446 * N_() macro.
1447 * ohelp: The help text for the client option. Should be used with the N_()
1448 * macro.
1449 * ocat: The client_option_class of this client option.
1450 * ospec: A gui_type enumerator which determin for what particular client
1451 * gui this option is for. Sets to GUI_STUB for common options.
1452 * odef: The default string for this client option.
1453 * oacc: The string accessor where to find the allowed values of type
1454 * 'const struct strvec * (*) (void)'.
1455 * ocb: A callback function of type void (*)(struct option *) called when
1456 * the option changed.
1458 #define GEN_STR_LIST_OPTION(oname, odesc, ohelp, ocat, ospec, odef, oacc, ocb) \
1460 .base_option = OPTION_STR_INIT(&client_optset_static, \
1461 client_option_common_vtable, \
1462 client_option_str_vtable, ocb), \
1463 .name = #oname, \
1464 .description = odesc, \
1465 .help_text = ohelp, \
1466 .category = ocat, \
1467 .specific = ospec, \
1469 .string = { \
1470 .pvalue = oname, \
1471 .size = sizeof(oname), \
1472 .def = odef, \
1473 .val_accessor = oacc \
1475 }, \
1479 * Generate a client option of type OT_ENUM.
1481 * oname: The option data. Note it is used as name to be loaded or saved.
1482 * So, you shouldn't change the name of this variable in any case.
1483 * odesc: A short description of the client option. Should be used with the
1484 * N_() macro.
1485 * ohelp: The help text for the client option. Should be used with the N_()
1486 * macro.
1487 * ocat: The client_option_class of this client option.
1488 * ospec: A gui_type enumerator which determin for what particular client
1489 * gui this option is for. Sets to GUI_STUB for common options.
1490 * odef: The default value for this client option.
1491 * oacc: The name accessor of type 'const struct copt_val_name * (*) (int)'.
1492 * ocb: A callback function of type void (*) (struct option *) called when
1493 * the option changed.
1495 #define GEN_ENUM_OPTION(oname, odesc, ohelp, ocat, ospec, odef, oacc, ocb) \
1497 .base_option = OPTION_ENUM_INIT(&client_optset_static, \
1498 client_option_common_vtable, \
1499 client_option_enum_vtable, ocb), \
1500 .name = #oname, \
1501 .description = odesc, \
1502 .help_text = ohelp, \
1503 .category = ocat, \
1504 .specific = ospec, \
1506 .enumerator = { \
1507 .pvalue = (int *) &oname, \
1508 .def = odef, \
1509 .support_names = NULL, /* Set in options_init(). */ \
1510 .pretty_names = NULL, \
1511 .name_accessor = oacc \
1513 }, \
1517 * Generate a client option of type OT_BITWISE.
1519 * oname: The option data. Note it is used as name to be loaded or saved.
1520 * So, you shouldn't change the name of this variable in any case.
1521 * odesc: A short description of the client option. Should be used with the
1522 * N_() macro.
1523 * ohelp: The help text for the client option. Should be used with the N_()
1524 * macro.
1525 * ocat: The client_option_class of this client option.
1526 * ospec: A gui_type enumerator which determin for what particular client
1527 * gui this option is for. Sets to GUI_STUB for common options.
1528 * odef: The default value for this client option.
1529 * oacc: The name accessor of type 'const struct copt_val_name * (*) (int)'.
1530 * ocb: A callback function of type void (*) (struct option *) called when
1531 * the option changed.
1533 #define GEN_BITWISE_OPTION(oname, odesc, ohelp, ocat, ospec, odef, oacc, \
1534 ocb) \
1536 .base_option = OPTION_BITWISE_INIT(&client_optset_static, \
1537 client_option_common_vtable, \
1538 client_option_bitwise_vtable, ocb), \
1539 .name = #oname, \
1540 .description = odesc, \
1541 .help_text = ohelp, \
1542 .category = ocat, \
1543 .specific = ospec, \
1545 .bitwise = { \
1546 .pvalue = &oname, \
1547 .def = odef, \
1548 .support_names = NULL, /* Set in options_init(). */ \
1549 .pretty_names = NULL, \
1550 .name_accessor = oacc \
1552 }, \
1556 * Generate a client option of type OT_FONT.
1558 * oname: The option data. Note it is used as name to be loaded or saved.
1559 * So, you shouldn't change the name of this variable in any case.
1560 * Be sure to pass the array variable and not a pointer to it because
1561 * the size is calculated with sizeof().
1562 * otgt: The target widget style.
1563 * odesc: A short description of the client option. Should be used with the
1564 * N_() macro.
1565 * ohelp: The help text for the client option. Should be used with the N_()
1566 * macro.
1567 * ocat: The client_option_class of this client option.
1568 * ospec: A gui_type enumerator which determin for what particular client
1569 * gui this option is for. Sets to GUI_STUB for common options.
1570 * odef: The default string for this client option.
1571 * ocb: A callback function of type void (*)(struct option *) called when
1572 * the option changed.
1574 #define GEN_FONT_OPTION(oname, otgt, odesc, ohelp, ocat, ospec, odef, ocb) \
1576 .base_option = OPTION_FONT_INIT(&client_optset_static, \
1577 client_option_common_vtable, \
1578 client_option_font_vtable, ocb), \
1579 .name = #oname, \
1580 .description = odesc, \
1581 .help_text = ohelp, \
1582 .category = ocat, \
1583 .specific = ospec, \
1585 .font = { \
1586 .pvalue = oname, \
1587 .size = sizeof(oname), \
1588 .def = odef, \
1589 .target = otgt, \
1591 }, \
1595 * Generate a client option of type OT_COLOR.
1597 * oname: The option data. Note it is used as name to be loaded or saved.
1598 * So, you shouldn't change the name of this variable in any case.
1599 * odesc: A short description of the client option. Should be used with the
1600 * N_() macro.
1601 * ohelp: The help text for the client option. Should be used with the N_()
1602 * macro.
1603 * ocat: The client_option_class of this client option.
1604 * ospec: A gui_type enumerator which determin for what particular client
1605 * gui this option is for. Sets to GUI_STUB for common options.
1606 * odef_fg, odef_bg: The default values for this client option.
1607 * ocb: A callback function of type void (*)(struct option *) called when
1608 * the option changed.
1610 #define GEN_COLOR_OPTION(oname, odesc, ohelp, ocat, ospec, odef_fg, \
1611 odef_bg, ocb) \
1613 .base_option = OPTION_COLOR_INIT(&client_optset_static, \
1614 client_option_common_vtable, \
1615 client_option_color_vtable, ocb), \
1616 .name = #oname, \
1617 .description = odesc, \
1618 .help_text = ohelp, \
1619 .category = ocat, \
1620 .specific = ospec, \
1622 .color = { \
1623 .pvalue = &oname, \
1624 .def = FT_COLOR(odef_fg, odef_bg) \
1626 }, \
1630 * Generate a client option of type OT_VIDEO_MODE.
1632 * oname: The option data. Note it is used as name to be loaded or saved.
1633 * So, you shouldn't change the name of this variable in any case.
1634 * odesc: A short description of the client option. Should be used with the
1635 * N_() macro.
1636 * ohelp: The help text for the client option. Should be used with the N_()
1637 * macro.
1638 * ocat: The client_option_class of this client option.
1639 * ospec: A gui_type enumerator which determin for what particular client
1640 * gui this option is for. Sets to GUI_STUB for common options.
1641 * odef_width, odef_height: The default values for this client option.
1642 * ocb: A callback function of type void (*)(struct option *) called when
1643 * the option changed.
1645 #define GEN_VIDEO_OPTION(oname, odesc, ohelp, ocat, ospec, odef_width, \
1646 odef_height, ocb) \
1648 .base_option = OPTION_VIDEO_MODE_INIT(&client_optset_static, \
1649 client_option_common_vtable, \
1650 client_option_video_mode_vtable, \
1651 ocb), \
1652 .name = #oname, \
1653 .description = odesc, \
1654 .help_text = ohelp, \
1655 .category = ocat, \
1656 .specific = ospec, \
1658 .video_mode = { \
1659 .pvalue = &oname, \
1660 .def = VIDEO_MODE(odef_width, odef_height) \
1662 }, \
1665 /****************************************************************************
1666 Enumerator name accessors.
1667 ****************************************************************************/
1669 /****************************************************************************
1670 GTK message/chat layout setting names accessor.
1671 ****************************************************************************/
1672 static const struct copt_val_name
1673 *gui_gtk_message_chat_location_name(int value)
1675 /* Order must match enum GUI_GTK_MSGCHAT_* */
1676 static const struct copt_val_name names[] = {
1677 /* TRANS: enum value for 'gui_gtk2/gtk3_message_chat_location' */
1678 { "SPLIT", N_("Split") },
1679 /* TRANS: enum value for 'gui_gtk2/gtk3_message_chat_location' */
1680 { "SEPARATE", N_("Separate") },
1681 /* TRANS: enum value for 'gui_gtk2/gtk3_message_chat_location' */
1682 { "MERGED", N_("Merged") }
1685 return (0 <= value && value < ARRAY_SIZE(names)
1686 ? names + value : NULL);
1689 /****************************************************************************
1690 Popup tech help setting names accessor.
1691 ****************************************************************************/
1692 static const struct copt_val_name
1693 *gui_popup_tech_help_name(int value)
1695 /* Order must match enum GUI_POPUP_TECH_HELP_* */
1696 static const struct copt_val_name names[] = {
1697 /* TRANS: enum value for 'gui_popup_tech_help' */
1698 { "ENABLED", N_("Enabled") },
1699 /* TRANS: enum value for 'gui_popup_tech_help' */
1700 { "DISABLED", N_("Disabled") },
1701 /* TRANS: enum value for 'gui_popup_tech_help' */
1702 { "RULESET", N_("Ruleset") }
1705 return (0 <= value && value < ARRAY_SIZE(names)
1706 ? names + value : NULL);
1709 /* Some changed callbacks. */
1710 static void reqtree_show_icons_callback(struct option *poption);
1711 static void view_option_changed_callback(struct option *poption);
1712 static void voteinfo_bar_callback(struct option *poption);
1713 static void font_changed_callback(struct option *poption);
1714 static void mapimg_changed_callback(struct option *poption);
1716 static struct client_option client_options[] = {
1717 GEN_STR_OPTION(default_user_name,
1718 N_("Login name"),
1719 N_("This is the default login username that will be used "
1720 "in the connection dialogs or with the -a command-line "
1721 "parameter."),
1722 COC_NETWORK, GUI_STUB, NULL, NULL),
1723 GEN_STR_OPTION(default_server_host,
1724 N_("Server"),
1725 N_("This is the default server hostname that will be used "
1726 "in the connection dialogs or with the -a command-line "
1727 "parameter."),
1728 COC_NETWORK, GUI_STUB, "localhost", NULL),
1729 GEN_INT_OPTION(default_server_port,
1730 N_("Server port"),
1731 N_("This is the default server port that will be used "
1732 "in the connection dialogs or with the -a command-line "
1733 "parameter."),
1734 COC_NETWORK, GUI_STUB, DEFAULT_SOCK_PORT, 0, 65535, NULL),
1735 GEN_STR_OPTION(default_metaserver,
1736 N_("Metaserver"),
1737 N_("The metaserver is a host that the client contacts to "
1738 "find out about games on the internet. Don't change "
1739 "this from its default value unless you know what "
1740 "you're doing."),
1741 COC_NETWORK, GUI_STUB, DEFAULT_METASERVER_OPTION, NULL),
1742 GEN_STR_LIST_OPTION(default_sound_set_name,
1743 N_("Soundset"),
1744 N_("This is the soundset that will be used. Changing "
1745 "this is the same as using the -S command-line "
1746 "parameter."),
1747 COC_SOUND, GUI_STUB, "stdsounds", get_soundset_list, NULL),
1748 GEN_STR_LIST_OPTION(default_sound_plugin_name,
1749 N_("Sound plugin"),
1750 N_("If you have a problem with sound, try changing "
1751 "the sound plugin. The new plugin won't take "
1752 "effect until you restart Freeciv. Changing this "
1753 "is the same as using the -P command-line option."),
1754 COC_SOUND, GUI_STUB, NULL, get_soundplugin_list, NULL),
1755 GEN_STR_OPTION(default_chat_logfile,
1756 N_("The chat log file"),
1757 N_("The name of the chat log file."),
1758 COC_INTERFACE, GUI_STUB, GUI_DEFAULT_CHAT_LOGFILE, NULL),
1759 /* gui_gtk2/3_default_theme_name and gui_sdl_default_theme_name are
1760 * different settings to avoid client crash after loading the
1761 * style for the other gui. Keeps 3 different options! */
1762 GEN_STR_LIST_OPTION(gui_gtk2_default_theme_name, N_("Theme"),
1763 N_("By changing this option you change the "
1764 "active theme."),
1765 COC_GRAPHICS, GUI_GTK2, FC_GTK2_DEFAULT_THEME_NAME,
1766 get_themes_list, theme_reread_callback),
1767 GEN_STR_LIST_OPTION(gui_gtk3_default_theme_name, N_("Theme"),
1768 N_("By changing this option you change the "
1769 "active theme."),
1770 COC_GRAPHICS, GUI_GTK3, FC_GTK3_DEFAULT_THEME_NAME,
1771 get_themes_list, theme_reread_callback),
1772 GEN_STR_LIST_OPTION(gui_sdl_default_theme_name, N_("Theme"),
1773 N_("By changing this option you change the "
1774 "active theme."),
1775 COC_GRAPHICS, GUI_SDL, FC_SDL_DEFAULT_THEME_NAME,
1776 get_themes_list, theme_reread_callback),
1778 /* It's important to give empty string instead of NULL as as default
1779 * value. For NULL value it would default to assigning first value
1780 * from the tileset list returned by get_tileset_list() as default
1781 * tileset. We don't want default tileset assigned at all here, but
1782 * leave it to tilespec code that can handle tileset priority. */
1783 GEN_STR_LIST_OPTION(default_tileset_name, N_("Tileset"),
1784 N_("By changing this option you change the active "
1785 "tileset. This is the same as using the -t "
1786 "command-line parameter."),
1787 COC_GRAPHICS, GUI_STUB, "",
1788 get_tileset_list, tilespec_reread_callback),
1790 GEN_BOOL_OPTION(draw_city_outlines, N_("Draw city outlines"),
1791 N_("Setting this option will draw a line at the city "
1792 "workable limit."),
1793 COC_GRAPHICS, GUI_STUB, TRUE,
1794 view_option_changed_callback),
1795 GEN_BOOL_OPTION(draw_city_output, N_("Draw city output"),
1796 N_("Setting this option will draw city output for every "
1797 "citizen."),
1798 COC_GRAPHICS, GUI_STUB, FALSE,
1799 view_option_changed_callback),
1800 GEN_BOOL_OPTION(draw_map_grid, N_("Draw the map grid"),
1801 N_("Setting this option will draw a grid over the map."),
1802 COC_GRAPHICS, GUI_STUB, FALSE,
1803 view_option_changed_callback),
1804 GEN_BOOL_OPTION(draw_full_citybar, N_("Draw the city bar"),
1805 N_("Setting this option will display a 'city bar' "
1806 "containing useful information beneath each city. "
1807 "Disabling this option will display only the city's "
1808 "name and, optionally, production."),
1809 COC_GRAPHICS, GUI_STUB,
1810 TRUE, view_option_changed_callback),
1811 GEN_BOOL_OPTION(draw_city_names, N_("Draw the city names"),
1812 N_("Setting this option will draw the names of the cities "
1813 "on the map."),
1814 COC_GRAPHICS, GUI_STUB, TRUE,
1815 view_option_changed_callback),
1816 GEN_BOOL_OPTION(draw_city_growth, N_("Draw the city growth"),
1817 N_("Setting this option will draw in how many turns the "
1818 "cities will grow or shrink."),
1819 COC_GRAPHICS, GUI_STUB, TRUE,
1820 view_option_changed_callback),
1821 GEN_BOOL_OPTION(draw_city_productions, N_("Draw the city productions"),
1822 N_("Setting this option will draw what the cities are "
1823 "currently building on the map."),
1824 COC_GRAPHICS, GUI_STUB, TRUE,
1825 view_option_changed_callback),
1826 GEN_BOOL_OPTION(draw_city_buycost, N_("Draw the city buy costs"),
1827 N_("Setting this option will draw how much gold is "
1828 "needed to buy the production of the cities."),
1829 COC_GRAPHICS, GUI_STUB, FALSE,
1830 view_option_changed_callback),
1831 GEN_BOOL_OPTION(draw_city_trade_routes, N_("Draw the city trade routes"),
1832 N_("Setting this option will draw trade route lines "
1833 "between cities which have trade routes."),
1834 COC_GRAPHICS, GUI_STUB, FALSE,
1835 view_option_changed_callback),
1836 GEN_BOOL_OPTION(draw_terrain, N_("Draw the terrain"),
1837 N_("Setting this option will draw the terrain."),
1838 COC_GRAPHICS, GUI_STUB, TRUE,
1839 view_option_changed_callback),
1840 GEN_BOOL_OPTION(draw_coastline, N_("Draw the coast line"),
1841 N_("Setting this option will draw a line to separate the "
1842 "land from the ocean."),
1843 COC_GRAPHICS, GUI_STUB, FALSE,
1844 view_option_changed_callback),
1845 GEN_BOOL_OPTION(draw_roads_rails, N_("Draw the roads and the railroads"),
1846 N_("Setting this option will draw the roads and the "
1847 "railroads on the map."),
1848 COC_GRAPHICS, GUI_STUB, TRUE,
1849 view_option_changed_callback),
1850 GEN_BOOL_OPTION(draw_irrigation, N_("Draw the irrigation"),
1851 N_("Setting this option will draw the irrigation systems "
1852 "on the map."),
1853 COC_GRAPHICS, GUI_STUB, TRUE,
1854 view_option_changed_callback),
1855 GEN_BOOL_OPTION(draw_mines, N_("Draw the mines"),
1856 N_("Setting this option will draw the mines on the map."),
1857 COC_GRAPHICS, GUI_STUB, TRUE,
1858 view_option_changed_callback),
1859 GEN_BOOL_OPTION(draw_fortress_airbase, N_("Draw the bases"),
1860 N_("Setting this option will draw the bases on the map."),
1861 COC_GRAPHICS, GUI_STUB, TRUE,
1862 view_option_changed_callback),
1863 GEN_BOOL_OPTION(draw_specials, N_("Draw the specials"),
1864 N_("Setting this option will draw the specials on the "
1865 "map."),
1866 COC_GRAPHICS, GUI_STUB, TRUE,
1867 view_option_changed_callback),
1868 GEN_BOOL_OPTION(draw_pollution, N_("Draw the pollution/nuclear fallout"),
1869 N_("Setting this option will draw pollution and "
1870 "nuclear fallout on the map."),
1871 COC_GRAPHICS, GUI_STUB, TRUE,
1872 view_option_changed_callback),
1873 GEN_BOOL_OPTION(draw_cities, N_("Draw the cities"),
1874 N_("Setting this option will draw the cities on the map."),
1875 COC_GRAPHICS, GUI_STUB, TRUE,
1876 view_option_changed_callback),
1877 GEN_BOOL_OPTION(draw_units, N_("Draw the units"),
1878 N_("Setting this option will draw the units on the map."),
1879 COC_GRAPHICS, GUI_STUB, TRUE,
1880 view_option_changed_callback),
1881 GEN_BOOL_OPTION(solid_color_behind_units,
1882 N_("Solid unit background color"),
1883 N_("Setting this option will cause units on the map "
1884 "view to be drawn with a solid background color "
1885 "instead of the flag backdrop."),
1886 COC_GRAPHICS, GUI_STUB,
1887 FALSE, view_option_changed_callback),
1888 GEN_BOOL_OPTION(draw_unit_shields, N_("Draw shield graphics for units"),
1889 N_("Setting this option will draw a shield icon "
1890 "as the flags on units. If unset, the full flag will "
1891 "be drawn."),
1892 COC_GRAPHICS, GUI_STUB, TRUE, view_option_changed_callback),
1893 GEN_BOOL_OPTION(draw_focus_unit, N_("Draw the units in focus"),
1894 N_("Setting this option will cause the currently focused "
1895 "unit(s) to always be drawn, even if units are not "
1896 "otherwise being drawn (for instance if 'Draw the units' "
1897 "is unset)."),
1898 COC_GRAPHICS, GUI_STUB, FALSE,
1899 view_option_changed_callback),
1900 GEN_BOOL_OPTION(draw_fog_of_war, N_("Draw the fog of war"),
1901 N_("Setting this option will draw the fog of war."),
1902 COC_GRAPHICS, GUI_STUB, TRUE,
1903 view_option_changed_callback),
1904 GEN_BOOL_OPTION(draw_borders, N_("Draw the borders"),
1905 N_("Setting this option will draw the national borders."),
1906 COC_GRAPHICS, GUI_STUB, TRUE,
1907 view_option_changed_callback),
1908 GEN_BOOL_OPTION(draw_native, N_("Draw whether tiles are native to "
1909 "selected unit"),
1910 N_("Setting this option will highlight tiles that the "
1911 "currently selected unit cannot enter unaided due to "
1912 "non-native terrain. (If multiple units are selected, "
1913 "only tiles that all of them can enter are indicated.)"),
1914 COC_GRAPHICS, GUI_STUB, FALSE,
1915 view_option_changed_callback),
1916 GEN_BOOL_OPTION(player_dlg_show_dead_players,
1917 N_("Show dead players in Nations report"),
1918 N_("This option controls whether defeated nations are "
1919 "shown on the Nations report page."),
1920 COC_GRAPHICS, GUI_STUB, TRUE,
1921 view_option_changed_callback),
1922 GEN_BOOL_OPTION(sound_bell_at_new_turn, N_("Sound bell at new turn"),
1923 N_("Set this option to have a \"bell\" event be generated "
1924 "at the start of a new turn. You can control the "
1925 "behavior of the \"bell\" event by editing the message "
1926 "options."),
1927 COC_SOUND, GUI_STUB, FALSE, NULL),
1928 GEN_INT_OPTION(smooth_move_unit_msec,
1929 N_("Unit movement animation time (milliseconds)"),
1930 N_("This option controls how long unit \"animation\" takes "
1931 "when a unit moves on the map view. Set it to 0 to "
1932 "disable animation entirely."),
1933 COC_GRAPHICS, GUI_STUB, 30, 0, 2000, NULL),
1934 GEN_INT_OPTION(smooth_center_slide_msec,
1935 N_("Mapview recentering time (milliseconds)"),
1936 N_("When the map view is recentered, it will slide "
1937 "smoothly over the map to its new position. This "
1938 "option controls how long this slide lasts. Set it to "
1939 "0 to disable mapview sliding entirely."),
1940 COC_GRAPHICS, GUI_STUB, 200, 0, 5000, NULL),
1941 GEN_INT_OPTION(smooth_combat_step_msec,
1942 N_("Combat animation step time (milliseconds)"),
1943 N_("This option controls the speed of combat animation "
1944 "between units on the mapview. Set it to 0 to disable "
1945 "animation entirely."),
1946 COC_GRAPHICS, GUI_STUB, 10, 0, 100, NULL),
1947 GEN_BOOL_OPTION(reqtree_show_icons,
1948 N_("Show icons in the technology tree"),
1949 N_("Setting this option will display icons "
1950 "on the technology tree diagram. Turning "
1951 "this option off makes the technology tree "
1952 "more compact."),
1953 COC_GRAPHICS, GUI_STUB, TRUE, reqtree_show_icons_callback),
1954 GEN_BOOL_OPTION(reqtree_curved_lines,
1955 N_("Use curved lines in the technology tree"),
1956 N_("Setting this option make the technology tree "
1957 "diagram use curved lines to show technology "
1958 "relations. Turning this option off causes "
1959 "the lines to be drawn straight."),
1960 COC_GRAPHICS, GUI_STUB, FALSE,
1961 reqtree_show_icons_callback),
1962 GEN_COLOR_OPTION(highlight_our_names,
1963 N_("Color to highlight your player/user name"),
1964 N_("If set, your player and user name in the new chat "
1965 "messages will be highlighted using this color as "
1966 "background. If not set, it will just not highlight "
1967 "anything."),
1968 COC_GRAPHICS, GUI_STUB, "#000000", "#FFFF00", NULL),
1969 GEN_BOOL_OPTION(ai_manual_turn_done, N_("Manual Turn Done in AI mode"),
1970 N_("Disable this option if you do not want to "
1971 "press the Turn Done button manually when watching "
1972 "an AI player."),
1973 COC_INTERFACE, GUI_STUB, TRUE, NULL),
1974 GEN_BOOL_OPTION(auto_center_on_unit, N_("Auto center on units"),
1975 N_("Set this option to have the active unit centered "
1976 "automatically when the unit focus changes."),
1977 COC_INTERFACE, GUI_STUB, TRUE, NULL),
1978 GEN_BOOL_OPTION(auto_center_on_combat, N_("Auto center on combat"),
1979 N_("Set this option to have any combat be centered "
1980 "automatically. Disabling this will speed up the time "
1981 "between turns but may cause you to miss combat "
1982 "entirely."),
1983 COC_INTERFACE, GUI_STUB, FALSE, NULL),
1984 GEN_BOOL_OPTION(auto_center_each_turn, N_("Auto center on new turn"),
1985 N_("Set this option to have the client automatically "
1986 "recenter the map on a suitable location at the "
1987 "start of each turn."),
1988 COC_INTERFACE, GUI_STUB, TRUE, NULL),
1989 GEN_BOOL_OPTION(wakeup_focus, N_("Focus on awakened units"),
1990 N_("Set this option to have newly awoken units be "
1991 "focused automatically."),
1992 COC_INTERFACE, GUI_STUB, TRUE, NULL),
1993 GEN_BOOL_OPTION(keyboardless_goto, N_("Keyboardless goto"),
1994 N_("If this option is set then a goto may be initiated "
1995 "by left-clicking and then holding down the mouse "
1996 "button while dragging the mouse onto a different "
1997 "tile."),
1998 COC_INTERFACE, GUI_STUB, TRUE, NULL),
1999 GEN_BOOL_OPTION(goto_into_unknown, N_("Allow goto into the unknown"),
2000 N_("Setting this option will make the game consider "
2001 "moving into unknown tiles. If not, then goto routes "
2002 "will detour around or be blocked by unknown tiles."),
2003 COC_INTERFACE, GUI_STUB, TRUE, NULL),
2004 GEN_BOOL_OPTION(center_when_popup_city, N_("Center map when popup city"),
2005 N_("Setting this option makes the mapview center on a "
2006 "city when its city dialog is popped up."),
2007 COC_INTERFACE, GUI_STUB, TRUE, NULL),
2008 GEN_BOOL_OPTION(concise_city_production, N_("Concise city production"),
2009 N_("Set this option to make the city production (as shown "
2010 "in the city dialog) to be more compact."),
2011 COC_INTERFACE, GUI_STUB, FALSE, NULL),
2012 GEN_BOOL_OPTION(auto_turn_done, N_("End turn when done moving"),
2013 N_("Setting this option makes your turn end automatically "
2014 "when all your units are done moving."),
2015 COC_INTERFACE, GUI_STUB, FALSE, NULL),
2016 GEN_BOOL_OPTION(ask_city_name, N_("Prompt for city names"),
2017 N_("Disabling this option will make the names of newly "
2018 "founded cities be chosen automatically by the server."),
2019 COC_INTERFACE, GUI_STUB, TRUE, NULL),
2020 GEN_BOOL_OPTION(popup_new_cities, N_("Pop up city dialog for new cities"),
2021 N_("Setting this option will pop up a newly-founded "
2022 "city's city dialog automatically."),
2023 COC_INTERFACE, GUI_STUB, TRUE, NULL),
2024 GEN_BOOL_OPTION(popup_caravan_arrival, N_("Pop up caravan actions"),
2025 N_("If this option is enabled, when caravans or similar "
2026 "units arrive at a city where they can establish a "
2027 "trade route or help build a wonder, a window will "
2028 "pop up asking which action should be performed. "
2029 "Disabling this option means you will have to do the "
2030 "action manually by pressing either 'r' (for a trade "
2031 "route) or 'b' (for building a wonder) when the unit "
2032 "is in the city."),
2033 COC_INTERFACE, GUI_STUB, TRUE, NULL),
2034 GEN_BOOL_OPTION(enable_cursor_changes, N_("Enable cursor changing"),
2035 N_("This option controls whether the client should "
2036 "try to change the mouse cursor depending on what "
2037 "is being pointed at, as well as to indicate "
2038 "changes in the client or server state."),
2039 COC_INTERFACE, GUI_STUB, TRUE, NULL),
2040 GEN_BOOL_OPTION(separate_unit_selection, N_("Select cities before units"),
2041 N_("If this option is enabled, when both cities and "
2042 "units are present in the selection rectangle, only "
2043 "cities will be selected. See the help on Controls."),
2044 COC_INTERFACE, GUI_STUB, FALSE, NULL),
2045 GEN_BOOL_OPTION(unit_selection_clears_orders,
2046 N_("Clear unit orders on selection"),
2047 N_("Enabling this option will cause unit orders to be "
2048 "cleared as soon as one or more units are selected. If "
2049 "this option is disabled, busy units will not stop "
2050 "their current activity when selected. Giving them "
2051 "new orders will clear their current ones; pressing "
2052 "<space> once will clear their orders and leave them "
2053 "selected, and pressing <space> a second time will "
2054 "dismiss them."),
2055 COC_INTERFACE, GUI_STUB, TRUE, NULL),
2056 GEN_BOOL_OPTION(voteinfo_bar_use, N_("Enable vote bar"),
2057 N_("If this option is turned on, the vote bar will be "
2058 "displayed to show vote information."),
2059 COC_GRAPHICS, GUI_STUB, TRUE, voteinfo_bar_callback),
2060 GEN_BOOL_OPTION(voteinfo_bar_always_show,
2061 N_("Always display the vote bar"),
2062 N_("If this option is turned on, the vote bar will never "
2063 "be hidden, even if there is no running vote."),
2064 COC_GRAPHICS, GUI_STUB, FALSE, voteinfo_bar_callback),
2065 GEN_BOOL_OPTION(voteinfo_bar_hide_when_not_player,
2066 N_("Do not show vote bar if not a player"),
2067 N_("If this option is enabled, the client won't show the "
2068 "vote bar if you are not a player."),
2069 COC_GRAPHICS, GUI_STUB, FALSE, voteinfo_bar_callback),
2070 GEN_BOOL_OPTION(voteinfo_bar_new_at_front, N_("Set new votes at front"),
2071 N_("If this option is enabled, then new votes will go "
2072 "to the front of the vote list."),
2073 COC_GRAPHICS, GUI_STUB, FALSE, voteinfo_bar_callback),
2074 GEN_BOOL_OPTION(autoaccept_tileset_suggestion,
2075 N_("Autoaccept tileset suggestions"),
2076 N_("If this option is enabled, any tileset suggested by "
2077 "the ruleset is automatically used; otherwise you "
2078 "are prompted to change tileset."),
2079 COC_GRAPHICS, GUI_STUB, FALSE, NULL),
2080 GEN_BOOL_OPTION(autoaccept_soundset_suggestion,
2081 N_("Autoaccept soundset suggestions"),
2082 N_("If this option is enabled, soundset suggested by "
2083 "the ruleset is automatically taken in to use."),
2084 COC_SOUND, GUI_STUB, FALSE, NULL),
2086 GEN_BOOL_OPTION(overview.layers[OLAYER_BACKGROUND],
2087 N_("Background layer"),
2088 N_("The background layer of the overview shows just "
2089 "ocean and land."),
2090 COC_OVERVIEW, GUI_STUB, TRUE, NULL),
2091 GEN_BOOL_OPTION(overview.layers[OLAYER_RELIEF],
2092 N_("Terrain relief map layer"),
2093 N_("The relief layer shows all terrains on the map."),
2094 COC_OVERVIEW, GUI_STUB, FALSE, overview_redraw_callback),
2095 GEN_BOOL_OPTION(overview.layers[OLAYER_BORDERS],
2096 N_("Borders layer"),
2097 N_("The borders layer of the overview shows which tiles "
2098 "are owned by each player."),
2099 COC_OVERVIEW, GUI_STUB, FALSE, overview_redraw_callback),
2100 GEN_BOOL_OPTION(overview.layers[OLAYER_BORDERS_ON_OCEAN],
2101 N_("Borders layer on ocean tiles"),
2102 N_("The borders layer of the overview are drawn on "
2103 "ocean tiles as well (this may look ugly with many "
2104 "islands). This option is only of interest if you "
2105 "have set the option \"Borders layer\" already."),
2106 COC_OVERVIEW, GUI_STUB, TRUE, overview_redraw_callback),
2107 GEN_BOOL_OPTION(overview.layers[OLAYER_UNITS],
2108 N_("Units layer"),
2109 N_("Enabling this will draw units on the overview."),
2110 COC_OVERVIEW, GUI_STUB, TRUE, overview_redraw_callback),
2111 GEN_BOOL_OPTION(overview.layers[OLAYER_CITIES],
2112 N_("Cities layer"),
2113 N_("Enabling this will draw cities on the overview."),
2114 COC_OVERVIEW, GUI_STUB, TRUE, overview_redraw_callback),
2115 GEN_BOOL_OPTION(overview.fog,
2116 N_("Overview fog of war"),
2117 N_("Enabling this will show fog of war on the "
2118 "overview."),
2119 COC_OVERVIEW, GUI_STUB, TRUE, overview_redraw_callback),
2121 /* options for map images */
2122 GEN_STR_LIST_OPTION(mapimg_format,
2123 N_("Image format"),
2124 N_("The image toolkit and file format used for "
2125 "map images."),
2126 COC_MAPIMG, GUI_STUB, NULL, mapimg_get_format_list,
2127 NULL),
2128 GEN_INT_OPTION(mapimg_zoom,
2129 N_("Zoom factor for map images"),
2130 N_("The magnification used for map images."),
2131 COC_MAPIMG, GUI_STUB, 2, 1, 5, mapimg_changed_callback),
2132 GEN_BOOL_OPTION(mapimg_layer[MAPIMG_LAYER_AREA],
2133 N_("Show area within borders"),
2134 N_("If set, the territory of each nation is shown "
2135 "on the saved image."),
2136 COC_MAPIMG, GUI_STUB, FALSE, mapimg_changed_callback),
2137 GEN_BOOL_OPTION(mapimg_layer[MAPIMG_LAYER_BORDERS],
2138 N_("Show borders"),
2139 N_("If set, the border of each nation is shown on the "
2140 "saved image."),
2141 COC_MAPIMG, GUI_STUB, TRUE, mapimg_changed_callback),
2142 GEN_BOOL_OPTION(mapimg_layer[MAPIMG_LAYER_CITIES],
2143 N_("Show cities"),
2144 N_("If set, cities are shown on the saved image."),
2145 COC_MAPIMG, GUI_STUB, TRUE, mapimg_changed_callback),
2146 GEN_BOOL_OPTION(mapimg_layer[MAPIMG_LAYER_FOGOFWAR],
2147 N_("Show fog of war"),
2148 N_("If set, the extent of fog of war is shown on the "
2149 "saved image."),
2150 COC_MAPIMG, GUI_STUB, TRUE, mapimg_changed_callback),
2151 GEN_BOOL_OPTION(mapimg_layer[MAPIMG_LAYER_TERRAIN],
2152 N_("Show full terrain"),
2153 N_("If set, terrain relief is shown with different colors "
2154 "in the saved image; otherwise, only land and water are "
2155 "distinguished."),
2156 COC_MAPIMG, GUI_STUB, TRUE, mapimg_changed_callback),
2157 GEN_BOOL_OPTION(mapimg_layer[MAPIMG_LAYER_UNITS],
2158 N_("Show units"),
2159 N_("If set, units are shown in the saved image."),
2160 COC_MAPIMG, GUI_STUB, TRUE, mapimg_changed_callback),
2161 GEN_STR_OPTION(mapimg_filename,
2162 N_("Map image file name"),
2163 N_("The base part of the filename for saved map images. "
2164 "A string identifying the game turn and map options will "
2165 "be appended."),
2166 COC_MAPIMG, GUI_STUB, GUI_DEFAULT_MAPIMG_FILENAME, NULL),
2168 /* gui-gtk-2.0 client specific options. */
2169 GEN_BOOL_OPTION(gui_gtk2_map_scrollbars, N_("Show map scrollbars"),
2170 N_("Disable this option to hide the scrollbars on the "
2171 "map view."),
2172 COC_INTERFACE, GUI_GTK2, FALSE, NULL),
2173 GEN_BOOL_OPTION(gui_gtk2_dialogs_on_top, N_("Keep dialogs on top"),
2174 N_("If this option is set then dialog windows will always "
2175 "remain in front of the main Freeciv window. "
2176 "Disabling this has no effect in fullscreen mode."),
2177 COC_INTERFACE, GUI_GTK2, TRUE, NULL),
2178 GEN_BOOL_OPTION(gui_gtk2_show_task_icons, N_("Show worklist task icons"),
2179 N_("Disabling this will turn off the unit and building "
2180 "icons in the worklist dialog and the production "
2181 "tab of the city dialog."),
2182 COC_GRAPHICS, GUI_GTK2, TRUE, NULL),
2183 GEN_BOOL_OPTION(gui_gtk2_enable_tabs, N_("Enable status report tabs"),
2184 N_("If this option is enabled then report dialogs will "
2185 "be shown as separate tabs rather than in popup "
2186 "dialogs."),
2187 COC_INTERFACE, GUI_GTK2, TRUE, NULL),
2188 GEN_BOOL_OPTION(gui_gtk2_better_fog,
2189 N_("Better fog-of-war drawing"),
2190 N_("If this is enabled then a better method is used "
2191 "for drawing fog-of-war. It is not any slower but "
2192 "will consume about twice as much memory."),
2193 COC_GRAPHICS, GUI_GTK2,
2194 TRUE, view_option_changed_callback),
2195 GEN_BOOL_OPTION(gui_gtk2_show_chat_message_time,
2196 N_("Show time for each chat message"),
2197 N_("If this option is enabled then all chat messages "
2198 "will be prefixed by a time string of the form "
2199 "[hour:minute:second]."),
2200 COC_INTERFACE, GUI_GTK2, FALSE, NULL),
2201 GEN_BOOL_OPTION(gui_gtk2_new_messages_go_to_top,
2202 N_("New message events go to top of list"),
2203 N_("If this option is enabled, new events in the "
2204 "message window will appear at the top of the list, "
2205 "rather than being appended at the bottom."),
2206 COC_INTERFACE, GUI_GTK2, FALSE, NULL),
2207 GEN_BOOL_OPTION(gui_gtk2_show_message_window_buttons,
2208 N_("Show extra message window buttons"),
2209 N_("If this option is enabled, there will be two "
2210 "buttons displayed in the message window for "
2211 "inspecting a city and going to a location. If this "
2212 "option is disabled, these buttons will not appear "
2213 "(you can still double-click with the left mouse "
2214 "button or right-click on a row to inspect or goto "
2215 "respectively). This option will only take effect "
2216 "once the message window is closed and reopened."),
2217 COC_INTERFACE, GUI_GTK2, TRUE, NULL),
2218 GEN_BOOL_OPTION(gui_gtk2_metaserver_tab_first,
2219 N_("Metaserver tab first in network page"),
2220 N_("If this option is enabled, the metaserver tab will "
2221 "be the first notebook tab in the network page. This "
2222 "option requires a restart in order to take effect."),
2223 COC_NETWORK, GUI_GTK2, FALSE, NULL),
2224 GEN_BOOL_OPTION(gui_gtk2_allied_chat_only,
2225 N_("Plain chat messages are sent to allies only"),
2226 N_("If this option is enabled, then plain messages "
2227 "typed into the chat entry while the game is "
2228 "running will only be sent to your allies. "
2229 "Otherwise plain messages will be sent as "
2230 "public chat messages. To send a public chat "
2231 "message with this option enabled, prefix the "
2232 "message with a single colon ':'. This option "
2233 "can also be set using a toggle button beside "
2234 "the chat entry (only visible in multiplayer "
2235 "games)."),
2236 COC_INTERFACE, GUI_GTK2, FALSE, NULL),
2237 GEN_ENUM_OPTION(gui_gtk2_message_chat_location,
2238 N_("Messages and Chat reports location"),
2239 /* TRANS: The strings used in the UI for 'Split' etc are
2240 * tagged 'gui_gtk2/gtk3_message_chat_location' */
2241 N_("Controls where the Messages and Chat reports "
2242 "appear relative to the main view containing the map.\n"
2243 "'Split' allows all three to be seen simultaneously, "
2244 "which is best for multiplayer, but requires a large "
2245 "window to be usable.\n"
2246 "'Separate' puts Messages and Chat in a notebook "
2247 "separate from the main view, so that one of them "
2248 "can always be seen alongside the main view.\n"
2249 "'Merged' makes the Messages and Chat reports into "
2250 "tabs alongside the map and other reports; this "
2251 "allows a larger map view on small screens.\n"
2252 "This option requires a restart in order to take "
2253 "effect."), COC_INTERFACE, GUI_GTK2,
2254 GUI_GTK_MSGCHAT_MERGED /* Ignored! See options_load(). */,
2255 gui_gtk_message_chat_location_name, NULL),
2256 GEN_BOOL_OPTION(gui_gtk2_small_display_layout,
2257 N_("Arrange widgets for small displays"),
2258 N_("If this option is enabled, widgets in the main "
2259 "window will be arranged so that they take up the "
2260 "least amount of total screen space. Specifically, "
2261 "the left panel containing the overview, player "
2262 "status, and the unit information box will be "
2263 "extended over the entire left side of the window. "
2264 "This option requires a restart in order to take "
2265 "effect."), COC_INTERFACE, GUI_GTK2, TRUE, NULL),
2266 GEN_BOOL_OPTION(gui_gtk2_mouse_over_map_focus,
2267 N_("Mouse over the map widget selects it automatically"),
2268 N_("If this option is enabled, then the map will be "
2269 "focused when the mouse hovers over it."),
2270 COC_INTERFACE, GUI_GTK2, FALSE, NULL),
2271 GEN_BOOL_OPTION(gui_gtk2_chatline_autocompletion,
2272 N_("Player or user name autocompletion"),
2273 N_("If this option is turned on, the tabulation key "
2274 "will be used in the chatline to complete the word you "
2275 "are typing with the name of a player or a user."),
2276 COC_INTERFACE, GUI_GTK2, TRUE, NULL),
2277 GEN_INT_OPTION(gui_gtk2_citydlg_xsize,
2278 N_("Width of the city dialog"),
2279 N_("This value is only used if the width of the city "
2280 "dialog is saved."),
2281 COC_INTERFACE, GUI_GTK2, GUI_GTK2_CITYDLG_DEFAULT_XSIZE,
2282 GUI_GTK2_CITYDLG_MIN_XSIZE, GUI_GTK2_CITYDLG_MAX_XSIZE,
2283 NULL),
2284 GEN_INT_OPTION(gui_gtk2_citydlg_ysize,
2285 N_("Height of the city dialog"),
2286 N_("This value is only used if the height of the city "
2287 "dialog is saved."),
2288 COC_INTERFACE, GUI_GTK2, GUI_GTK2_CITYDLG_DEFAULT_YSIZE,
2289 GUI_GTK2_CITYDLG_MIN_YSIZE, GUI_GTK2_CITYDLG_MAX_YSIZE,
2290 NULL),
2291 GEN_ENUM_OPTION(gui_gtk2_popup_tech_help,
2292 N_("Popup tech help when gained"),
2293 N_("Controls if tech help should be opened when "
2294 "new tech has been gained.\n"
2295 "'Ruleset' means that behavior suggested by "
2296 "current ruleset is used."), COC_INTERFACE, GUI_GTK2,
2297 GUI_POPUP_TECH_HELP_RULESET,
2298 gui_popup_tech_help_name, NULL),
2299 GEN_FONT_OPTION(gui_gtk2_font_city_label, "city_label",
2300 N_("City Label"),
2301 N_("This font is used to display the city labels on city "
2302 "dialogs."),
2303 COC_FONT, GUI_GTK2,
2304 "Monospace 8", font_changed_callback),
2305 GEN_FONT_OPTION(gui_gtk2_font_notify_label, "notify_label",
2306 N_("Notify Label"),
2307 N_("This font is used to display server reports such "
2308 "as the demographic report or historian publications."),
2309 COC_FONT, GUI_GTK2,
2310 "Monospace Bold 9", font_changed_callback),
2311 GEN_FONT_OPTION(gui_gtk2_font_spaceship_label, "spaceship_label",
2312 N_("Spaceship Label"),
2313 N_("This font is used to display the spaceship widgets."),
2314 COC_FONT, GUI_GTK2,
2315 "Monospace 8", font_changed_callback),
2316 GEN_FONT_OPTION(gui_gtk2_font_help_label, "help_label",
2317 N_("Help Label"),
2318 N_("This font is used to display the help headers in the "
2319 "help window."),
2320 COC_FONT, GUI_GTK2,
2321 "Sans Bold 10", font_changed_callback),
2322 GEN_FONT_OPTION(gui_gtk2_font_help_link, "help_link",
2323 N_("Help Link"),
2324 N_("This font is used to display the help links in the "
2325 "help window."),
2326 COC_FONT, GUI_GTK2,
2327 "Sans 9", font_changed_callback),
2328 GEN_FONT_OPTION(gui_gtk2_font_help_text, "help_text",
2329 N_("Help Text"),
2330 N_("This font is used to display the help body text in "
2331 "the help window."),
2332 COC_FONT, GUI_GTK2,
2333 "Monospace 8", font_changed_callback),
2334 GEN_FONT_OPTION(gui_gtk2_font_chatline, "chatline",
2335 N_("Chatline Area"),
2336 N_("This font is used to display the text in the "
2337 "chatline area."),
2338 COC_FONT, GUI_GTK2,
2339 "Monospace 8", font_changed_callback),
2340 GEN_FONT_OPTION(gui_gtk2_font_beta_label, "beta_label",
2341 N_("Beta Label"),
2342 N_("This font is used to display the beta label."),
2343 COC_FONT, GUI_GTK2,
2344 "Sans Italic 10", font_changed_callback),
2345 GEN_FONT_OPTION(gui_gtk2_font_small, "small_font",
2346 N_("Small Font"),
2347 N_("This font is used for any small font request. For "
2348 "example, it is used for display the building lists "
2349 "in the city dialog, the Economy report or the Units "
2350 "report."),
2351 COC_FONT, GUI_GTK2,
2352 "Sans 9", NULL),
2353 GEN_FONT_OPTION(gui_gtk2_font_comment_label, "comment_label",
2354 N_("Comment Label"),
2355 N_("This font is used to display comment labels, such as "
2356 "in the governor page of the city dialogs."),
2357 COC_FONT, GUI_GTK2,
2358 "Sans Italic 9", font_changed_callback),
2359 GEN_FONT_OPTION(gui_gtk2_font_city_names, "city_names",
2360 N_("City Names"),
2361 N_("This font is used to the display the city names "
2362 "on the map."),
2363 COC_FONT, GUI_GTK2,
2364 "Sans Bold 10", NULL),
2365 GEN_FONT_OPTION(gui_gtk2_font_city_productions, "city_productions",
2366 N_("City Productions"),
2367 N_("This font is used to the display the city production "
2368 "names on the map."),
2369 COC_FONT, GUI_GTK2,
2370 "Serif 10", NULL),
2371 GEN_FONT_OPTION(gui_gtk2_font_reqtree_text, "reqtree_text",
2372 N_("Requirement Tree"),
2373 N_("This font is used to the display the requirement tree "
2374 "in the Research report."),
2375 COC_FONT, GUI_GTK2,
2376 "Serif 10", NULL),
2378 /* gui-gtk-3.0 client specific options. */
2379 GEN_BOOL_OPTION(gui_gtk3_map_scrollbars, N_("Show map scrollbars"),
2380 N_("Disable this option to hide the scrollbars on the "
2381 "map view."),
2382 COC_INTERFACE, GUI_GTK3, FALSE, NULL),
2383 GEN_BOOL_OPTION(gui_gtk3_dialogs_on_top, N_("Keep dialogs on top"),
2384 N_("If this option is set then dialog windows will always "
2385 "remain in front of the main Freeciv window. "
2386 "Disabling this has no effect in fullscreen mode."),
2387 COC_INTERFACE, GUI_GTK3, TRUE, NULL),
2388 GEN_BOOL_OPTION(gui_gtk3_show_task_icons, N_("Show worklist task icons"),
2389 N_("Disabling this will turn off the unit and building "
2390 "icons in the worklist dialog and the production "
2391 "tab of the city dialog."),
2392 COC_GRAPHICS, GUI_GTK3, TRUE, NULL),
2393 GEN_BOOL_OPTION(gui_gtk3_enable_tabs, N_("Enable status report tabs"),
2394 N_("If this option is enabled then report dialogs will "
2395 "be shown as separate tabs rather than in popup "
2396 "dialogs."),
2397 COC_INTERFACE, GUI_GTK3, TRUE, NULL),
2398 GEN_BOOL_OPTION(gui_gtk3_better_fog,
2399 N_("Better fog-of-war drawing"),
2400 N_("If this is enabled then a better method is used "
2401 "for drawing fog-of-war. It is not any slower but "
2402 "will consume about twice as much memory."),
2403 COC_GRAPHICS, GUI_GTK3,
2404 TRUE, view_option_changed_callback),
2405 GEN_BOOL_OPTION(gui_gtk3_show_chat_message_time,
2406 N_("Show time for each chat message"),
2407 N_("If this option is enabled then all chat messages "
2408 "will be prefixed by a time string of the form "
2409 "[hour:minute:second]."),
2410 COC_INTERFACE, GUI_GTK3, FALSE, NULL),
2411 GEN_BOOL_OPTION(gui_gtk3_new_messages_go_to_top,
2412 N_("New message events go to top of list"),
2413 N_("If this option is enabled, new events in the "
2414 "message window will appear at the top of the list, "
2415 "rather than being appended at the bottom."),
2416 COC_INTERFACE, GUI_GTK3, FALSE, NULL),
2417 GEN_BOOL_OPTION(gui_gtk3_show_message_window_buttons,
2418 N_("Show extra message window buttons"),
2419 N_("If this option is enabled, there will be two "
2420 "buttons displayed in the message window for "
2421 "inspecting a city and going to a location. If this "
2422 "option is disabled, these buttons will not appear "
2423 "(you can still double-click with the left mouse "
2424 "button or right-click on a row to inspect or goto "
2425 "respectively). This option will only take effect "
2426 "once the message window is closed and reopened."),
2427 COC_INTERFACE, GUI_GTK3, TRUE, NULL),
2428 GEN_BOOL_OPTION(gui_gtk3_metaserver_tab_first,
2429 N_("Metaserver tab first in network page"),
2430 N_("If this option is enabled, the metaserver tab will "
2431 "be the first notebook tab in the network page. This "
2432 "option requires a restart in order to take effect."),
2433 COC_NETWORK, GUI_GTK3, FALSE, NULL),
2434 GEN_BOOL_OPTION(gui_gtk3_allied_chat_only,
2435 N_("Plain chat messages are sent to allies only"),
2436 N_("If this option is enabled, then plain messages "
2437 "typed into the chat entry while the game is "
2438 "running will only be sent to your allies. "
2439 "Otherwise plain messages will be sent as "
2440 "public chat messages. To send a public chat "
2441 "message with this option enabled, prefix the "
2442 "message with a single colon ':'. This option "
2443 "can also be set using a toggle button beside "
2444 "the chat entry (only visible in multiplayer "
2445 "games)."),
2446 COC_INTERFACE, GUI_GTK3, FALSE, NULL),
2447 GEN_ENUM_OPTION(gui_gtk3_message_chat_location,
2448 N_("Messages and Chat reports location"),
2449 /* TRANS: The strings used in the UI for 'Split' etc are
2450 * tagged 'gui_gtk2/gtk3_message_chat_location' */
2451 N_("Controls where the Messages and Chat reports "
2452 "appear relative to the main view containing the map.\n"
2453 "'Split' allows all three to be seen simultaneously, "
2454 "which is best for multiplayer, but requires a large "
2455 "window to be usable.\n"
2456 "'Separate' puts Messages and Chat in a notebook "
2457 "separate from the main view, so that one of them "
2458 "can always be seen alongside the main view.\n"
2459 "'Merged' makes the Messages and Chat reports into "
2460 "tabs alongside the map and other reports; this "
2461 "allows a larger map view on small screens.\n"
2462 "This option requires a restart in order to take "
2463 "effect."), COC_INTERFACE, GUI_GTK3,
2464 GUI_GTK_MSGCHAT_MERGED /* Ignored! See options_load(). */,
2465 gui_gtk_message_chat_location_name, NULL),
2466 GEN_BOOL_OPTION(gui_gtk3_small_display_layout,
2467 N_("Arrange widgets for small displays"),
2468 N_("If this option is enabled, widgets in the main "
2469 "window will be arranged so that they take up the "
2470 "least amount of total screen space. Specifically, "
2471 "the left panel containing the overview, player "
2472 "status, and the unit information box will be "
2473 "extended over the entire left side of the window. "
2474 "This option requires a restart in order to take "
2475 "effect."), COC_INTERFACE, GUI_GTK3, TRUE, NULL),
2476 GEN_BOOL_OPTION(gui_gtk3_mouse_over_map_focus,
2477 N_("Mouse over the map widget selects it automatically"),
2478 N_("If this option is enabled, then the map will be "
2479 "focused when the mouse hovers over it."),
2480 COC_INTERFACE, GUI_GTK3, FALSE, NULL),
2481 GEN_BOOL_OPTION(gui_gtk3_chatline_autocompletion,
2482 N_("Player or user name autocompletion"),
2483 N_("If this option is turned on, the tabulation key "
2484 "will be used in the chatline to complete the word you "
2485 "are typing with the name of a player or a user."),
2486 COC_INTERFACE, GUI_GTK3, TRUE, NULL),
2487 GEN_INT_OPTION(gui_gtk3_citydlg_xsize,
2488 N_("Width of the city dialog"),
2489 N_("This value is only used if the width of the city "
2490 "dialog is saved."),
2491 COC_INTERFACE, GUI_GTK3, GUI_GTK3_CITYDLG_DEFAULT_XSIZE,
2492 GUI_GTK3_CITYDLG_MIN_XSIZE, GUI_GTK3_CITYDLG_MAX_XSIZE,
2493 NULL),
2494 GEN_INT_OPTION(gui_gtk3_citydlg_ysize,
2495 N_("Height of the city dialog"),
2496 N_("This value is only used if the height of the city "
2497 "dialog is saved."),
2498 COC_INTERFACE, GUI_GTK3, GUI_GTK3_CITYDLG_DEFAULT_YSIZE,
2499 GUI_GTK3_CITYDLG_MIN_YSIZE, GUI_GTK3_CITYDLG_MAX_YSIZE,
2500 NULL),
2501 GEN_ENUM_OPTION(gui_gtk3_popup_tech_help,
2502 N_("Popup tech help when gained"),
2503 N_("Controls if tech help should be opened when "
2504 "new tech has been gained.\n"
2505 "'Ruleset' means that behavior suggested by "
2506 "current ruleset is used."), COC_INTERFACE, GUI_GTK3,
2507 GUI_POPUP_TECH_HELP_RULESET,
2508 gui_popup_tech_help_name, NULL),
2509 GEN_FONT_OPTION(gui_gtk3_font_city_label, "city_label",
2510 N_("City Label"),
2511 N_("This font is used to display the city labels on city "
2512 "dialogs."),
2513 COC_FONT, GUI_GTK3,
2514 "Monospace 8", font_changed_callback),
2515 GEN_FONT_OPTION(gui_gtk3_font_notify_label, "notify_label",
2516 N_("Notify Label"),
2517 N_("This font is used to display server reports such "
2518 "as the demographic report or historian publications."),
2519 COC_FONT, GUI_GTK3,
2520 "Monospace Bold 9", font_changed_callback),
2521 GEN_FONT_OPTION(gui_gtk3_font_spaceship_label, "spaceship_label",
2522 N_("Spaceship Label"),
2523 N_("This font is used to display the spaceship widgets."),
2524 COC_FONT, GUI_GTK3,
2525 "Monospace 8", font_changed_callback),
2526 GEN_FONT_OPTION(gui_gtk3_font_help_label, "help_label",
2527 N_("Help Label"),
2528 N_("This font is used to display the help headers in the "
2529 "help window."),
2530 COC_FONT, GUI_GTK3,
2531 "Sans Bold 10", font_changed_callback),
2532 GEN_FONT_OPTION(gui_gtk3_font_help_link, "help_link",
2533 N_("Help Link"),
2534 N_("This font is used to display the help links in the "
2535 "help window."),
2536 COC_FONT, GUI_GTK3,
2537 "Sans 9", font_changed_callback),
2538 GEN_FONT_OPTION(gui_gtk3_font_help_text, "help_text",
2539 N_("Help Text"),
2540 N_("This font is used to display the help body text in "
2541 "the help window."),
2542 COC_FONT, GUI_GTK3,
2543 "Monospace 8", font_changed_callback),
2544 GEN_FONT_OPTION(gui_gtk3_font_chatline, "chatline",
2545 N_("Chatline Area"),
2546 N_("This font is used to display the text in the "
2547 "chatline area."),
2548 COC_FONT, GUI_GTK3,
2549 "Monospace 8", font_changed_callback),
2550 GEN_FONT_OPTION(gui_gtk3_font_beta_label, "beta_label",
2551 N_("Beta Label"),
2552 N_("This font is used to display the beta label."),
2553 COC_FONT, GUI_GTK3,
2554 "Sans Italic 10", font_changed_callback),
2555 GEN_FONT_OPTION(gui_gtk3_font_small, "small_font",
2556 N_("Small Font"),
2557 N_("This font is used for any small font request. For "
2558 "example, it is used for display the building lists "
2559 "in the city dialog, the Economy report or the Units "
2560 "report."),
2561 COC_FONT, GUI_GTK3,
2562 "Sans 9", NULL),
2563 GEN_FONT_OPTION(gui_gtk3_font_comment_label, "comment_label",
2564 N_("Comment Label"),
2565 N_("This font is used to display comment labels, such as "
2566 "in the governor page of the city dialogs."),
2567 COC_FONT, GUI_GTK3,
2568 "Sans Italic 9", font_changed_callback),
2569 GEN_FONT_OPTION(gui_gtk3_font_city_names, "city_names",
2570 N_("City Names"),
2571 N_("This font is used to the display the city names "
2572 "on the map."),
2573 COC_FONT, GUI_GTK3,
2574 "Sans Bold 10", NULL),
2575 GEN_FONT_OPTION(gui_gtk3_font_city_productions, "city_productions",
2576 N_("City Productions"),
2577 N_("This font is used to the display the city production "
2578 "names on the map."),
2579 COC_FONT, GUI_GTK3,
2580 "Serif 10", NULL),
2581 GEN_FONT_OPTION(gui_gtk3_font_reqtree_text, "reqtree_text",
2582 N_("Requirement Tree"),
2583 N_("This font is used to the display the requirement tree "
2584 "in the Research report."),
2585 COC_FONT, GUI_GTK3,
2586 "Serif 10", NULL),
2588 /* gui-sdl client specific options. */
2589 GEN_BOOL_OPTION(gui_sdl_fullscreen, N_("Fullscreen"),
2590 N_("If this option is set the client will use the "
2591 "whole screen area for drawing."),
2592 COC_INTERFACE, GUI_SDL, FALSE, NULL),
2593 GEN_VIDEO_OPTION(gui_sdl_screen, N_("Screen resolution"),
2594 N_("This option controls the resolution of the "
2595 "selected screen."),
2596 COC_INTERFACE, GUI_SDL, 640, 480, NULL),
2597 GEN_BOOL_OPTION(gui_sdl_do_cursor_animation, N_("Do cursor animation"),
2598 N_("If this option is disabled, the cursor will "
2599 "always be displayed as static."),
2600 COC_INTERFACE, GUI_SDL, TRUE, NULL),
2601 GEN_BOOL_OPTION(gui_sdl_use_color_cursors, N_("Use color cursors"),
2602 N_("If this option is disabled, the cursor will "
2603 "always be displayed in black and white."),
2604 COC_INTERFACE, GUI_SDL, TRUE, NULL),
2606 /* gui-qt client specific options. */
2607 GEN_FONT_OPTION(gui_qt_font_city_label, "city_label",
2608 N_("City Label"),
2609 N_("This font is used to display the city labels on city "
2610 "dialogs."),
2611 COC_FONT, GUI_QT,
2612 "Monospace,8,-1,5,50,0,0,0,0,0", font_changed_callback),
2613 GEN_FONT_OPTION(gui_qt_font_notify_label, "notify_label",
2614 N_("Notify Label"),
2615 N_("This font is used to display server reports such "
2616 "as the demographic report or historian publications."),
2617 COC_FONT, GUI_QT,
2618 "Monospace,9,-1,5,75,0,0,0,0,0", font_changed_callback),
2619 GEN_FONT_OPTION(gui_qt_font_spaceship_label, "spaceship_label",
2620 N_("Spaceship Label"),
2621 N_("This font is used to display the spaceship widgets."),
2622 COC_FONT, GUI_QT,
2623 "Monospace,8,-1,5,50,0,0,0,0,0", font_changed_callback),
2624 GEN_FONT_OPTION(gui_qt_font_help_label, "help_label",
2625 N_("Help Label"),
2626 N_("This font is used to display the help headers in the "
2627 "help window."),
2628 COC_FONT, GUI_QT,
2629 "Sans Serif,10,-1,5,75,0,0,0,0,0", font_changed_callback),
2630 GEN_FONT_OPTION(gui_qt_font_help_link, "help_link",
2631 N_("Help Link"),
2632 N_("This font is used to display the help links in the "
2633 "help window."),
2634 COC_FONT, GUI_QT,
2635 "Sans Serif,9,-1,5,50,0,0,0,0,0", font_changed_callback),
2636 GEN_FONT_OPTION(gui_qt_font_help_text, "help_text",
2637 N_("Help Text"),
2638 N_("This font is used to display the help body text in "
2639 "the help window."),
2640 COC_FONT, GUI_QT,
2641 "Monospace,8,-1,5,50,0,0,0,0,0", font_changed_callback),
2642 GEN_FONT_OPTION(gui_qt_font_chatline, "chatline",
2643 N_("Chatline Area"),
2644 N_("This font is used to display the text in the "
2645 "chatline area."),
2646 COC_FONT, GUI_QT,
2647 "Monospace,8,-1,5,50,0,0,0,0,0", font_changed_callback),
2648 GEN_FONT_OPTION(gui_qt_font_beta_label, "beta_label",
2649 N_("Beta Label"),
2650 N_("This font is used to display the beta label."),
2651 COC_FONT, GUI_QT,
2652 "Sans Serif,10,-1,5,50,1,0,0,0,0", font_changed_callback),
2653 GEN_FONT_OPTION(gui_qt_font_small, "small_font",
2654 N_("Small Font"),
2655 N_("This font is used for any small font request. For "
2656 "example, it is used for display the building lists "
2657 "in the city dialog, the Economy report or the Units "
2658 "report."),
2659 COC_FONT, GUI_QT,
2660 "Sans Serif,9,-1,5,50,0,0,0,0,0", NULL),
2661 GEN_FONT_OPTION(gui_qt_font_comment_label, "comment_label",
2662 N_("Comment Label"),
2663 N_("This font is used to display comment labels, such as "
2664 "in the governor page of the city dialogs."),
2665 COC_FONT, GUI_QT,
2666 "Sans Serif,9,-1,5,50,1,0,0,0,0", font_changed_callback),
2667 GEN_FONT_OPTION(gui_qt_font_city_names, "city_names",
2668 N_("City Names"),
2669 N_("This font is used to the display the city names "
2670 "on the map."),
2671 COC_FONT, GUI_QT,
2672 "Sans Serif,10,-1,5,75,0,0,0,0,0", NULL),
2673 GEN_FONT_OPTION(gui_qt_font_city_productions, "city_productions",
2674 N_("City Productions"),
2675 N_("This font is used to the display the city production "
2676 "names on the map."),
2677 COC_FONT, GUI_QT,
2678 "Sans Serif,10,-1,5,50,1,0,0,0,0", NULL),
2679 GEN_FONT_OPTION(gui_qt_font_reqtree_text, "reqtree_text",
2680 N_("Requirement Tree"),
2681 N_("This font is used to the display the requirement tree "
2682 "in the Research report."),
2683 COC_FONT, GUI_QT,
2684 "Sans Serif,10,-1,5,50,1,0,0,0,0", NULL)
2687 static const int client_options_num = ARRAY_SIZE(client_options);
2689 /* Iteration loop, including invalid options for the current gui type. */
2690 #define client_options_iterate_all(poption) \
2692 const struct client_option *const poption##_max = \
2693 client_options + client_options_num; \
2694 struct client_option *client_##poption = client_options; \
2695 struct option *poption; \
2696 for (; client_##poption < poption##_max; client_##poption++) { \
2697 poption = OPTION(client_##poption);
2699 #define client_options_iterate_all_end \
2704 /****************************************************************************
2705 Returns the next valid option pointer for the current gui type.
2706 ****************************************************************************/
2707 static struct client_option *
2708 client_option_next_valid(struct client_option *poption)
2710 const struct client_option *const max =
2711 client_options + client_options_num;
2712 const enum gui_type our_type = get_gui_type();
2714 while (poption < max
2715 && poption->specific != GUI_STUB
2716 && poption->specific != our_type) {
2717 poption++;
2720 return (poption < max ? poption : NULL);
2723 /****************************************************************************
2724 Returns the option corresponding to this id.
2725 ****************************************************************************/
2726 static struct option *client_optset_option_by_number(int id)
2728 if (0 > id || id > client_options_num) {
2729 return NULL;
2731 return OPTION(client_options + id);
2734 /****************************************************************************
2735 Returns the first valid option pointer for the current gui type.
2736 ****************************************************************************/
2737 static struct option *client_optset_option_first(void)
2739 return OPTION(client_option_next_valid(client_options));
2742 /****************************************************************************
2743 Returns the number of client option categories.
2744 ****************************************************************************/
2745 static int client_optset_category_number(void)
2747 return COC_MAX;
2750 /****************************************************************************
2751 Returns the name (translated) of the option class.
2752 ****************************************************************************/
2753 static const char *client_optset_category_name(int category)
2755 switch (category) {
2756 case COC_GRAPHICS:
2757 return _("Graphics");
2758 case COC_OVERVIEW:
2759 /* TRANS: Options section for overview map (mini-map) */
2760 return Q_("?map:Overview");
2761 case COC_SOUND:
2762 return _("Sound");
2763 case COC_INTERFACE:
2764 return _("Interface");
2765 case COC_MAPIMG:
2766 return _("Map Image");
2767 case COC_NETWORK:
2768 return _("Network");
2769 case COC_FONT:
2770 return _("Font");
2771 case COC_MAX:
2772 break;
2775 log_error("%s: invalid option category number %d.",
2776 __FUNCTION__, category);
2777 return NULL;
2780 /***************************************************************************
2781 Returns the number of this client option.
2782 ****************************************************************************/
2783 static int client_option_number(const struct option *poption)
2785 return CLIENT_OPTION(poption) - client_options;
2788 /****************************************************************************
2789 Returns the name of this client option.
2790 ****************************************************************************/
2791 static const char *client_option_name(const struct option *poption)
2793 return CLIENT_OPTION(poption)->name;
2796 /****************************************************************************
2797 Returns the description of this client option.
2798 ****************************************************************************/
2799 static const char *client_option_description(const struct option *poption)
2801 return _(CLIENT_OPTION(poption)->description);
2804 /****************************************************************************
2805 Returns the help text for this client option.
2806 ****************************************************************************/
2807 static const char *client_option_help_text(const struct option *poption)
2809 return _(CLIENT_OPTION(poption)->help_text);
2812 /****************************************************************************
2813 Returns the category of this client option.
2814 ****************************************************************************/
2815 static int client_option_category(const struct option *poption)
2817 return CLIENT_OPTION(poption)->category;
2820 /****************************************************************************
2821 Returns TRUE if this client option can be modified.
2822 ****************************************************************************/
2823 static bool client_option_is_changeable(const struct option *poption)
2825 return TRUE;
2828 /****************************************************************************
2829 Returns the next valid option pointer for the current gui type.
2830 ****************************************************************************/
2831 static struct option *client_option_next(const struct option *poption)
2833 return OPTION(client_option_next_valid(CLIENT_OPTION(poption) + 1));
2836 /****************************************************************************
2837 Returns the value of this client option of type OT_BOOLEAN.
2838 ****************************************************************************/
2839 static bool client_option_bool_get(const struct option *poption)
2841 return *(CLIENT_OPTION(poption)->boolean.pvalue);
2844 /****************************************************************************
2845 Returns the default value of this client option of type OT_BOOLEAN.
2846 ****************************************************************************/
2847 static bool client_option_bool_def(const struct option *poption)
2849 return CLIENT_OPTION(poption)->boolean.def;
2852 /****************************************************************************
2853 Set the value of this client option of type OT_BOOLEAN. Returns TRUE if
2854 the value changed.
2855 ****************************************************************************/
2856 static bool client_option_bool_set(struct option *poption, bool val)
2858 struct client_option *pcoption = CLIENT_OPTION(poption);
2860 if (*pcoption->boolean.pvalue == val) {
2861 return FALSE;
2864 *pcoption->boolean.pvalue = val;
2865 return TRUE;
2868 /****************************************************************************
2869 Returns the value of this client option of type OT_INTEGER.
2870 ****************************************************************************/
2871 static int client_option_int_get(const struct option *poption)
2873 return *(CLIENT_OPTION(poption)->integer.pvalue);
2876 /****************************************************************************
2877 Returns the default value of this client option of type OT_INTEGER.
2878 ****************************************************************************/
2879 static int client_option_int_def(const struct option *poption)
2881 return CLIENT_OPTION(poption)->integer.def;
2884 /****************************************************************************
2885 Returns the minimal value for this client option of type OT_INTEGER.
2886 ****************************************************************************/
2887 static int client_option_int_min(const struct option *poption)
2889 return CLIENT_OPTION(poption)->integer.min;
2892 /****************************************************************************
2893 Returns the maximal value for this client option of type OT_INTEGER.
2894 ****************************************************************************/
2895 static int client_option_int_max(const struct option *poption)
2897 return CLIENT_OPTION(poption)->integer.max;
2900 /****************************************************************************
2901 Set the value of this client option of type OT_INTEGER. Returns TRUE if
2902 the value changed.
2903 ****************************************************************************/
2904 static bool client_option_int_set(struct option *poption, int val)
2906 struct client_option *pcoption = CLIENT_OPTION(poption);
2908 if (val < pcoption->integer.min
2909 || val > pcoption->integer.max
2910 || *pcoption->integer.pvalue == val) {
2911 return FALSE;
2914 *pcoption->integer.pvalue = val;
2915 return TRUE;
2918 /****************************************************************************
2919 Returns the value of this client option of type OT_STRING.
2920 ****************************************************************************/
2921 static const char *client_option_str_get(const struct option *poption)
2923 return CLIENT_OPTION(poption)->string.pvalue;
2926 /****************************************************************************
2927 Returns the default value of this client option of type OT_STRING.
2928 ****************************************************************************/
2929 static const char *client_option_str_def(const struct option *poption)
2931 return CLIENT_OPTION(poption)->string.def;
2934 /****************************************************************************
2935 Returns the possible string values of this client option of type
2936 OT_STRING.
2937 ****************************************************************************/
2938 static const struct strvec *
2939 client_option_str_values(const struct option *poption)
2941 return (CLIENT_OPTION(poption)->string.val_accessor
2942 ? CLIENT_OPTION(poption)->string.val_accessor() : NULL);
2945 /****************************************************************************
2946 Set the value of this client option of type OT_STRING. Returns TRUE if
2947 the value changed.
2948 ****************************************************************************/
2949 static bool client_option_str_set(struct option *poption, const char *str)
2951 struct client_option *pcoption = CLIENT_OPTION(poption);
2953 if (strlen(str) >= pcoption->string.size
2954 || 0 == strcmp(pcoption->string.pvalue, str)) {
2955 return FALSE;
2958 fc_strlcpy(pcoption->string.pvalue, str, pcoption->string.size);
2959 return TRUE;
2962 /****************************************************************************
2963 Returns the current value of this client option of type OT_ENUM.
2964 ****************************************************************************/
2965 static int client_option_enum_get(const struct option *poption)
2967 return *(CLIENT_OPTION(poption)->enumerator.pvalue);
2970 /****************************************************************************
2971 Returns the default value of this client option of type OT_ENUM.
2972 ****************************************************************************/
2973 static int client_option_enum_def(const struct option *poption)
2975 return CLIENT_OPTION(poption)->enumerator.def;
2978 /****************************************************************************
2979 Returns the possible values of this client option of type OT_ENUM, as
2980 user-visible (translatable but not translated) strings.
2981 ****************************************************************************/
2982 static const struct strvec *
2983 client_option_enum_pretty_names(const struct option *poption)
2985 return CLIENT_OPTION(poption)->enumerator.pretty_names;
2988 /****************************************************************************
2989 Set the value of this client option of type OT_ENUM. Returns TRUE if
2990 the value changed.
2991 ****************************************************************************/
2992 static bool client_option_enum_set(struct option *poption, int val)
2994 struct client_option *pcoption = CLIENT_OPTION(poption);
2996 if (*pcoption->enumerator.pvalue == val
2997 || 0 > val
2998 || val >= strvec_size(pcoption->enumerator.support_names)) {
2999 return FALSE;
3002 *pcoption->enumerator.pvalue = val;
3003 return TRUE;
3006 /****************************************************************************
3007 Returns the "support" name of the value for this client option of type
3008 OT_ENUM (a string suitable for saving in a file).
3009 The prototype must match the 'secfile_enum_name_data_fn_t' type.
3010 ****************************************************************************/
3011 static const char *client_option_enum_secfile_str(secfile_data_t data,
3012 int val)
3014 const struct strvec *names = CLIENT_OPTION(data)->enumerator.support_names;
3016 return (0 <= val && val < strvec_size(names)
3017 ? strvec_get(names, val) : NULL);
3020 /****************************************************************************
3021 Returns the current value of this client option of type OT_BITWISE.
3022 ****************************************************************************/
3023 static unsigned client_option_bitwise_get(const struct option *poption)
3025 return *(CLIENT_OPTION(poption)->bitwise.pvalue);
3028 /****************************************************************************
3029 Returns the default value of this client option of type OT_BITWISE.
3030 ****************************************************************************/
3031 static unsigned client_option_bitwise_def(const struct option *poption)
3033 return CLIENT_OPTION(poption)->bitwise.def;
3036 /****************************************************************************
3037 Returns the possible values of this client option of type OT_BITWISE, as
3038 user-visible (translatable but not translated) strings.
3039 ****************************************************************************/
3040 static const struct strvec *
3041 client_option_bitwise_pretty_names(const struct option *poption)
3043 return CLIENT_OPTION(poption)->bitwise.pretty_names;
3046 /****************************************************************************
3047 Set the value of this client option of type OT_BITWISE. Returns TRUE if
3048 the value changed.
3049 ****************************************************************************/
3050 static bool client_option_bitwise_set(struct option *poption, unsigned val)
3052 struct client_option *pcoption = CLIENT_OPTION(poption);
3054 if (*pcoption->bitwise.pvalue == val) {
3055 return FALSE;
3058 *pcoption->bitwise.pvalue = val;
3059 return TRUE;
3062 /****************************************************************************
3063 Returns the "support" name of a single value for this client option of type
3064 OT_BITWISE (a string suitable for saving in a file).
3065 The prototype must match the 'secfile_enum_name_data_fn_t' type.
3066 ****************************************************************************/
3067 static const char *client_option_bitwise_secfile_str(secfile_data_t data,
3068 int val)
3070 const struct strvec *names = CLIENT_OPTION(data)->bitwise.support_names;
3072 return (0 <= val && val < strvec_size(names)
3073 ? strvec_get(names, val) : NULL);
3076 /****************************************************************************
3077 Returns the value of this client option of type OT_FONT.
3078 ****************************************************************************/
3079 static const char *client_option_font_get(const struct option *poption)
3081 return CLIENT_OPTION(poption)->font.pvalue;
3084 /****************************************************************************
3085 Returns the default value of this client option of type OT_FONT.
3086 ****************************************************************************/
3087 static const char *client_option_font_def(const struct option *poption)
3089 return CLIENT_OPTION(poption)->font.def;
3092 /****************************************************************************
3093 Returns the target style name of this client option of type OT_FONT.
3094 ****************************************************************************/
3095 static const char *client_option_font_target(const struct option *poption)
3097 return CLIENT_OPTION(poption)->font.target;
3100 /****************************************************************************
3101 Set the value of this client option of type OT_FONT. Returns TRUE if
3102 the value changed.
3103 ****************************************************************************/
3104 static bool client_option_font_set(struct option *poption, const char *font)
3106 struct client_option *pcoption = CLIENT_OPTION(poption);
3108 if (strlen(font) >= pcoption->font.size
3109 || 0 == strcmp(pcoption->font.pvalue, font)) {
3110 return FALSE;
3113 fc_strlcpy(pcoption->font.pvalue, font, pcoption->font.size);
3114 return TRUE;
3117 /****************************************************************************
3118 Returns the value of this client option of type OT_COLOR.
3119 ****************************************************************************/
3120 static struct ft_color client_option_color_get(const struct option *poption)
3122 return *CLIENT_OPTION(poption)->color.pvalue;
3125 /****************************************************************************
3126 Returns the default value of this client option of type OT_COLOR.
3127 ****************************************************************************/
3128 static struct ft_color client_option_color_def(const struct option *poption)
3130 return CLIENT_OPTION(poption)->color.def;
3133 /****************************************************************************
3134 Set the value of this client option of type OT_COLOR. Returns TRUE if
3135 the value changed.
3136 ****************************************************************************/
3137 static bool client_option_color_set(struct option *poption,
3138 struct ft_color color)
3140 struct ft_color *pcolor = CLIENT_OPTION(poption)->color.pvalue;
3141 bool changed = FALSE;
3143 #define color_set(color_tgt, color) \
3144 if (NULL == color_tgt) { \
3145 if (NULL != color) { \
3146 color_tgt = fc_strdup(color); \
3147 changed = TRUE; \
3149 } else { \
3150 if (NULL == color) { \
3151 free((void *) color_tgt); \
3152 changed = TRUE; \
3153 } else if (0 != strcmp(color_tgt, color)) { \
3154 free((void *) color_tgt); \
3155 color_tgt = fc_strdup(color); \
3156 changed = TRUE; \
3160 color_set(pcolor->foreground, color.foreground);
3161 color_set(pcolor->background, color.background);
3163 #undef color_set
3165 return changed;
3168 /****************************************************************************
3169 Returns the value of this client option of type OT_VIDEO_MODE.
3170 ****************************************************************************/
3171 static struct video_mode
3172 client_option_video_mode_get(const struct option *poption)
3174 return *CLIENT_OPTION(poption)->video_mode.pvalue;
3177 /****************************************************************************
3178 Returns the default value of this client option of type OT_VIDEO_MODE.
3179 ****************************************************************************/
3180 static struct video_mode
3181 client_option_video_mode_def(const struct option *poption)
3183 return CLIENT_OPTION(poption)->video_mode.def;
3186 /****************************************************************************
3187 Set the value of this client option of type OT_VIDEO_MODE. Returns TRUE
3188 if the value changed.
3189 ****************************************************************************/
3190 static bool client_option_video_mode_set(struct option *poption,
3191 struct video_mode mode)
3193 struct client_option *pcoption = CLIENT_OPTION(poption);
3195 if (0 == memcmp(&mode, pcoption->video_mode.pvalue,
3196 sizeof(struct video_mode))) {
3197 return FALSE;
3200 *pcoption->video_mode.pvalue = mode;
3201 return TRUE;
3204 /****************************************************************************
3205 Load the option from a file. Returns TRUE if the option changed.
3206 ****************************************************************************/
3207 static bool client_option_load(struct option *poption,
3208 struct section_file *sf)
3210 fc_assert_ret_val(NULL != poption, FALSE);
3211 fc_assert_ret_val(NULL != sf, FALSE);
3213 switch (option_type(poption)) {
3214 case OT_BOOLEAN:
3216 bool value;
3218 return (secfile_lookup_bool(sf, &value, "client.%s",
3219 option_name(poption))
3220 && option_bool_set(poption, value));
3222 case OT_INTEGER:
3224 int value;
3226 return (secfile_lookup_int(sf, &value, "client.%s",
3227 option_name(poption))
3228 && option_int_set(poption, value));
3230 case OT_STRING:
3232 const char *string;
3234 return ((string = secfile_lookup_str(sf, "client.%s",
3235 option_name(poption)))
3236 && option_str_set(poption, string));
3238 case OT_ENUM:
3240 int value;
3242 return (secfile_lookup_enum_data(sf, &value, FALSE,
3243 client_option_enum_secfile_str,
3244 poption, "client.%s",
3245 option_name(poption))
3246 && option_enum_set_int(poption, value));
3248 case OT_BITWISE:
3250 int value;
3252 return (secfile_lookup_enum_data(sf, &value, TRUE,
3253 client_option_bitwise_secfile_str,
3254 poption, "client.%s",
3255 option_name(poption))
3256 && option_bitwise_set(poption, value));
3258 case OT_FONT:
3260 const char *string;
3262 return ((string = secfile_lookup_str(sf, "client.%s",
3263 option_name(poption)))
3264 && option_font_set(poption, string));
3266 case OT_COLOR:
3268 struct ft_color color;
3270 return ((color.foreground =
3271 secfile_lookup_str(sf, "client.%s.foreground",
3272 option_name(poption)))
3273 && (color.background =
3274 secfile_lookup_str(sf, "client.%s.background",
3275 option_name(poption)))
3276 && option_color_set(poption, color));
3278 case OT_VIDEO_MODE:
3280 struct video_mode mode;
3282 return (secfile_lookup_int(sf, &mode.width, "client.%s.width",
3283 option_name(poption))
3284 && secfile_lookup_int(sf, &mode.height, "client.%s.height",
3285 option_name(poption))
3286 && option_video_mode_set(poption, mode));
3289 return FALSE;
3292 /****************************************************************************
3293 Save the option to a file.
3294 ****************************************************************************/
3295 static void client_option_save(struct option *poption,
3296 struct section_file *sf)
3298 fc_assert_ret(NULL != poption);
3299 fc_assert_ret(NULL != sf);
3301 switch (option_type(poption)) {
3302 case OT_BOOLEAN:
3303 secfile_insert_bool(sf, option_bool_get(poption),
3304 "client.%s", option_name(poption));
3305 break;
3306 case OT_INTEGER:
3307 secfile_insert_int(sf, option_int_get(poption),
3308 "client.%s", option_name(poption));
3309 break;
3310 case OT_STRING:
3311 secfile_insert_str(sf, option_str_get(poption),
3312 "client.%s", option_name(poption));
3313 break;
3314 case OT_ENUM:
3315 secfile_insert_enum_data(sf, option_enum_get_int(poption), FALSE,
3316 client_option_enum_secfile_str, poption,
3317 "client.%s", option_name(poption));
3318 break;
3319 case OT_BITWISE:
3320 secfile_insert_enum_data(sf, option_bitwise_get(poption), TRUE,
3321 client_option_bitwise_secfile_str, poption,
3322 "client.%s", option_name(poption));
3323 break;
3324 case OT_FONT:
3325 secfile_insert_str(sf, option_font_get(poption),
3326 "client.%s", option_name(poption));
3327 break;
3328 case OT_COLOR:
3330 struct ft_color color = option_color_get(poption);
3332 secfile_insert_str(sf, color.foreground, "client.%s.foreground",
3333 option_name(poption));
3334 secfile_insert_str(sf, color.background, "client.%s.background",
3335 option_name(poption));
3337 break;
3338 case OT_VIDEO_MODE:
3340 struct video_mode mode = option_video_mode_get(poption);
3342 secfile_insert_int(sf, mode.width, "client.%s.width",
3343 option_name(poption));
3344 secfile_insert_int(sf, mode.height, "client.%s.height",
3345 option_name(poption));
3347 break;
3352 /****************************************************************************
3353 Server options variables.
3354 ****************************************************************************/
3355 static char **server_options_categories = NULL;
3356 static struct server_option *server_options = NULL;
3358 static int server_options_categories_num = 0;
3359 static int server_options_num = 0;
3362 /****************************************************************************
3363 Server option set.
3364 ****************************************************************************/
3365 static struct option *server_optset_option_by_number(int id);
3366 static struct option *server_optset_option_first(void);
3367 static int server_optset_category_number(void);
3368 static const char *server_optset_category_name(int category);
3370 static struct option_set server_optset_static = {
3371 .option_by_number = server_optset_option_by_number,
3372 .option_first = server_optset_option_first,
3373 .category_number = server_optset_category_number,
3374 .category_name = server_optset_category_name
3376 const struct option_set *server_optset = &server_optset_static;
3379 /****************************************************************************
3380 Virtuals tables for the client options.
3381 ****************************************************************************/
3382 static int server_option_number(const struct option *poption);
3383 static const char *server_option_name(const struct option *poption);
3384 static const char *server_option_description(const struct option *poption);
3385 static const char *server_option_help_text(const struct option *poption);
3386 static int server_option_category(const struct option *poption);
3387 static bool server_option_is_changeable(const struct option *poption);
3388 static struct option *server_option_next(const struct option *poption);
3390 static const struct option_common_vtable server_option_common_vtable = {
3391 .number = server_option_number,
3392 .name = server_option_name,
3393 .description = server_option_description,
3394 .help_text = server_option_help_text,
3395 .category = server_option_category,
3396 .is_changeable = server_option_is_changeable,
3397 .next = server_option_next
3400 static bool server_option_bool_get(const struct option *poption);
3401 static bool server_option_bool_def(const struct option *poption);
3402 static bool server_option_bool_set(struct option *poption, bool val);
3404 static const struct option_bool_vtable server_option_bool_vtable = {
3405 .get = server_option_bool_get,
3406 .def = server_option_bool_def,
3407 .set = server_option_bool_set
3410 static int server_option_int_get(const struct option *poption);
3411 static int server_option_int_def(const struct option *poption);
3412 static int server_option_int_min(const struct option *poption);
3413 static int server_option_int_max(const struct option *poption);
3414 static bool server_option_int_set(struct option *poption, int val);
3416 static const struct option_int_vtable server_option_int_vtable = {
3417 .get = server_option_int_get,
3418 .def = server_option_int_def,
3419 .minimum = server_option_int_min,
3420 .maximum = server_option_int_max,
3421 .set = server_option_int_set
3424 static const char *server_option_str_get(const struct option *poption);
3425 static const char *server_option_str_def(const struct option *poption);
3426 static const struct strvec *
3427 server_option_str_values(const struct option *poption);
3428 static bool server_option_str_set(struct option *poption, const char *str);
3430 static const struct option_str_vtable server_option_str_vtable = {
3431 .get = server_option_str_get,
3432 .def = server_option_str_def,
3433 .values = server_option_str_values,
3434 .set = server_option_str_set
3437 static int server_option_enum_get(const struct option *poption);
3438 static int server_option_enum_def(const struct option *poption);
3439 static const struct strvec *
3440 server_option_enum_pretty(const struct option *poption);
3441 static bool server_option_enum_set(struct option *poption, int val);
3443 static const struct option_enum_vtable server_option_enum_vtable = {
3444 .get = server_option_enum_get,
3445 .def = server_option_enum_def,
3446 .values = server_option_enum_pretty,
3447 .set = server_option_enum_set,
3448 .cmp = strcmp
3451 static unsigned server_option_bitwise_get(const struct option *poption);
3452 static unsigned server_option_bitwise_def(const struct option *poption);
3453 static const struct strvec *
3454 server_option_bitwise_pretty(const struct option *poption);
3455 static bool server_option_bitwise_set(struct option *poption, unsigned val);
3457 static const struct option_bitwise_vtable server_option_bitwise_vtable = {
3458 .get = server_option_bitwise_get,
3459 .def = server_option_bitwise_def,
3460 .values = server_option_bitwise_pretty,
3461 .set = server_option_bitwise_set
3464 /****************************************************************************
3465 Derived class server option, inheriting from base class option.
3466 ****************************************************************************/
3467 struct server_option {
3468 struct option base_option; /* Base structure, must be the first! */
3470 char *name; /* Short name - used as an identifier */
3471 char *description; /* One-line description */
3472 char *help_text; /* Paragraph-length help text */
3473 unsigned char category;
3474 bool desired_sent;
3475 bool is_changeable;
3476 bool is_visible;
3478 union {
3479 /* OT_BOOLEAN type option. */
3480 struct {
3481 bool value;
3482 bool def;
3483 } boolean;
3484 /* OT_INTEGER type option. */
3485 struct {
3486 int value;
3487 int def, min, max;
3488 } integer;
3489 /* OT_STRING type option. */
3490 struct {
3491 char *value;
3492 char *def;
3493 } string;
3494 /* OT_ENUM type option. */
3495 struct {
3496 int value;
3497 int def;
3498 struct strvec *support_names;
3499 struct strvec *pretty_names; /* untranslated */
3500 } enumerator;
3501 /* OT_BITWISE type option. */
3502 struct {
3503 unsigned value;
3504 unsigned def;
3505 struct strvec *support_names;
3506 struct strvec *pretty_names; /* untranslated */
3507 } bitwise;
3511 #define SERVER_OPTION(poption) ((struct server_option *) (poption))
3513 static void desired_settable_option_send(struct option *poption);
3516 /****************************************************************************
3517 Initialize the server options (not received yet).
3518 ****************************************************************************/
3519 void server_options_init(void)
3521 fc_assert(NULL == server_options_categories);
3522 fc_assert(NULL == server_options);
3523 fc_assert(0 == server_options_categories_num);
3524 fc_assert(0 == server_options_num);
3527 /****************************************************************************
3528 Free one server option.
3529 ****************************************************************************/
3530 static void server_option_free(struct server_option *poption)
3532 switch (poption->base_option.type) {
3533 case OT_STRING:
3534 if (NULL != poption->string.value) {
3535 FC_FREE(poption->string.value);
3537 if (NULL != poption->string.def) {
3538 FC_FREE(poption->string.def);
3540 break;
3542 case OT_ENUM:
3543 if (NULL != poption->enumerator.support_names) {
3544 strvec_destroy(poption->enumerator.support_names);
3545 poption->enumerator.support_names = NULL;
3547 if (NULL != poption->enumerator.pretty_names) {
3548 strvec_destroy(poption->enumerator.pretty_names);
3549 poption->enumerator.pretty_names = NULL;
3551 break;
3553 case OT_BITWISE:
3554 if (NULL != poption->bitwise.support_names) {
3555 strvec_destroy(poption->bitwise.support_names);
3556 poption->bitwise.support_names = NULL;
3558 if (NULL != poption->bitwise.pretty_names) {
3559 strvec_destroy(poption->bitwise.pretty_names);
3560 poption->bitwise.pretty_names = NULL;
3562 break;
3564 case OT_BOOLEAN:
3565 case OT_INTEGER:
3566 case OT_FONT:
3567 case OT_COLOR:
3568 case OT_VIDEO_MODE:
3569 break;
3572 if (NULL != poption->name) {
3573 FC_FREE(poption->name);
3575 if (NULL != poption->description) {
3576 FC_FREE(poption->description);
3578 if (NULL != poption->help_text) {
3579 FC_FREE(poption->help_text);
3583 /****************************************************************************
3584 Free the server options, if already received.
3585 ****************************************************************************/
3586 void server_options_free(void)
3588 int i;
3590 /* Don't keep this dialog open. */
3591 option_dialog_popdown(server_optset);
3593 /* Free the options themselves. */
3594 if (NULL != server_options) {
3595 for (i = 0; i < server_options_num; i++) {
3596 server_option_free(server_options + i);
3598 FC_FREE(server_options);
3599 server_options_num = 0;
3602 /* Free the categories. */
3603 if (NULL != server_options_categories) {
3604 for (i = 0; i < server_options_categories_num; i++) {
3605 if (NULL != server_options_categories[i]) {
3606 FC_FREE(server_options_categories[i]);
3609 FC_FREE(server_options_categories);
3610 server_options_categories_num = 0;
3614 /****************************************************************************
3615 Allocate the server options and categories.
3616 ****************************************************************************/
3617 void handle_server_setting_control
3618 (const struct packet_server_setting_control *packet)
3620 int i;
3622 /* This packet should be received only once. */
3623 fc_assert_ret(NULL == server_options_categories);
3624 fc_assert_ret(NULL == server_options);
3625 fc_assert_ret(0 == server_options_categories_num);
3626 fc_assert_ret(0 == server_options_num);
3628 /* Allocate server option categories. */
3629 if (0 < packet->categories_num) {
3630 server_options_categories_num = packet->categories_num;
3631 server_options_categories =
3632 fc_calloc(server_options_categories_num,
3633 sizeof(*server_options_categories));
3635 for (i = 0; i < server_options_categories_num; i++) {
3636 /* NB: Translate now. */
3637 server_options_categories[i] = fc_strdup(_(packet->category_names[i]));
3641 /* Allocate server options. */
3642 if (0 < packet->settings_num) {
3643 server_options_num = packet->settings_num;
3644 server_options = fc_calloc(server_options_num, sizeof(*server_options));
3648 /****************************************************************************
3649 Receive a server setting info packet.
3650 ****************************************************************************/
3651 void handle_server_setting_const
3652 (const struct packet_server_setting_const *packet)
3654 struct option *poption = server_optset_option_by_number(packet->id);
3655 struct server_option *psoption = SERVER_OPTION(poption);
3657 fc_assert_ret(NULL != poption);
3659 fc_assert(NULL == psoption->name);
3660 psoption->name = fc_strdup(packet->name);
3661 fc_assert(NULL == psoption->description);
3662 /* NB: Translate now. */
3663 psoption->description = fc_strdup(_(packet->short_help));
3664 fc_assert(NULL == psoption->help_text);
3665 /* NB: Translate now. */
3666 psoption->help_text = fc_strdup(_(packet->extra_help));
3667 psoption->category = packet->category;
3670 /****************************************************************************
3671 Common part of handle_server_setting_*() functions. See below.
3672 ****************************************************************************/
3673 #define handle_server_setting_common(psoption, packet) \
3674 psoption->is_changeable = packet->is_changeable; \
3675 if (psoption->is_visible != packet->is_visible) { \
3676 if (psoption->is_visible) { \
3677 need_gui_remove = TRUE; \
3678 } else if (packet->is_visible) { \
3679 need_gui_add = TRUE; \
3681 psoption->is_visible = packet->is_visible; \
3684 if (!psoption->desired_sent \
3685 && psoption->is_visible \
3686 && psoption->is_changeable \
3687 && is_server_running() \
3688 && packet->initial_setting) { \
3689 /* Only send our private settings if we are running \
3690 * on a forked local server, i.e. started by the \
3691 * client with the "Start New Game" button. \
3692 * Do now override settings that are already saved to savegame \
3693 * and now loaded. */ \
3694 desired_settable_option_send(OPTION(poption)); \
3695 psoption->desired_sent = TRUE; \
3698 /* Update the GUI. */ \
3699 if (need_gui_remove) { \
3700 option_gui_remove(poption); \
3701 } else if (need_gui_add) { \
3702 option_gui_add(poption); \
3703 } else { \
3704 option_gui_update(poption); \
3707 /****************************************************************************
3708 Receive a boolean server setting info packet.
3709 ****************************************************************************/
3710 void handle_server_setting_bool
3711 (const struct packet_server_setting_bool *packet)
3713 struct option *poption = server_optset_option_by_number(packet->id);
3714 struct server_option *psoption = SERVER_OPTION(poption);
3715 bool need_gui_remove = FALSE;
3716 bool need_gui_add = FALSE;
3718 fc_assert_ret(NULL != poption);
3720 if (NULL == poption->common_vtable) {
3721 /* Not initialized yet. */
3722 poption->poptset = server_optset;
3723 poption->common_vtable = &server_option_common_vtable;
3724 poption->type = OT_BOOLEAN;
3725 poption->bool_vtable = &server_option_bool_vtable;
3727 fc_assert_ret_msg(OT_BOOLEAN == poption->type,
3728 "Server setting \"%s\" (nb %d) has type %s (%d), "
3729 "expected %s (%d)",
3730 option_name(poption), option_number(poption),
3731 option_type_name(poption->type), poption->type,
3732 option_type_name(OT_BOOLEAN), OT_BOOLEAN);
3734 if (packet->is_visible) {
3735 psoption->boolean.value = packet->val;
3736 psoption->boolean.def = packet->default_val;
3739 handle_server_setting_common(psoption, packet);
3742 /****************************************************************************
3743 Receive a integer server setting info packet.
3744 ****************************************************************************/
3745 void handle_server_setting_int
3746 (const struct packet_server_setting_int *packet)
3748 struct option *poption = server_optset_option_by_number(packet->id);
3749 struct server_option *psoption = SERVER_OPTION(poption);
3750 bool need_gui_remove = FALSE;
3751 bool need_gui_add = FALSE;
3753 fc_assert_ret(NULL != poption);
3755 if (NULL == poption->common_vtable) {
3756 /* Not initialized yet. */
3757 poption->poptset = server_optset;
3758 poption->common_vtable = &server_option_common_vtable;
3759 poption->type = OT_INTEGER;
3760 poption->int_vtable = &server_option_int_vtable;
3762 fc_assert_ret_msg(OT_INTEGER == poption->type,
3763 "Server setting \"%s\" (nb %d) has type %s (%d), "
3764 "expected %s (%d)",
3765 option_name(poption), option_number(poption),
3766 option_type_name(poption->type), poption->type,
3767 option_type_name(OT_INTEGER), OT_INTEGER);
3769 if (packet->is_visible) {
3770 psoption->integer.value = packet->val;
3771 psoption->integer.def = packet->default_val;
3772 psoption->integer.min = packet->min_val;
3773 psoption->integer.max = packet->max_val;
3776 handle_server_setting_common(psoption, packet);
3779 /****************************************************************************
3780 Receive a string server setting info packet.
3781 ****************************************************************************/
3782 void handle_server_setting_str
3783 (const struct packet_server_setting_str *packet)
3785 struct option *poption = server_optset_option_by_number(packet->id);
3786 struct server_option *psoption = SERVER_OPTION(poption);
3787 bool need_gui_remove = FALSE;
3788 bool need_gui_add = FALSE;
3790 fc_assert_ret(NULL != poption);
3792 if (NULL == poption->common_vtable) {
3793 /* Not initialized yet. */
3794 poption->poptset = server_optset;
3795 poption->common_vtable = &server_option_common_vtable;
3796 poption->type = OT_STRING;
3797 poption->str_vtable = &server_option_str_vtable;
3799 fc_assert_ret_msg(OT_STRING == poption->type,
3800 "Server setting \"%s\" (nb %d) has type %s (%d), "
3801 "expected %s (%d)",
3802 option_name(poption), option_number(poption),
3803 option_type_name(poption->type), poption->type,
3804 option_type_name(OT_STRING), OT_STRING);
3806 if (packet->is_visible) {
3807 if (NULL == psoption->string.value) {
3808 psoption->string.value = fc_strdup(packet->val);
3809 } else if (0 != strcmp(packet->val, psoption->string.value)) {
3810 free(psoption->string.value);
3811 psoption->string.value = fc_strdup(packet->val);
3813 if (NULL == psoption->string.def) {
3814 psoption->string.def = fc_strdup(packet->default_val);
3815 } else if (0 != strcmp(packet->default_val, psoption->string.def)) {
3816 free(psoption->string.def);
3817 psoption->string.def = fc_strdup(packet->default_val);
3821 handle_server_setting_common(psoption, packet);
3824 /****************************************************************************
3825 Receive an enumerator server setting info packet.
3826 ****************************************************************************/
3827 void handle_server_setting_enum
3828 (const struct packet_server_setting_enum *packet)
3830 struct option *poption = server_optset_option_by_number(packet->id);
3831 struct server_option *psoption = SERVER_OPTION(poption);
3832 bool need_gui_remove = FALSE;
3833 bool need_gui_add = FALSE;
3835 fc_assert_ret(NULL != poption);
3837 if (NULL == poption->common_vtable) {
3838 /* Not initialized yet. */
3839 poption->poptset = server_optset;
3840 poption->common_vtable = &server_option_common_vtable;
3841 poption->type = OT_ENUM;
3842 poption->enum_vtable = &server_option_enum_vtable;
3844 fc_assert_ret_msg(OT_ENUM == poption->type,
3845 "Server setting \"%s\" (nb %d) has type %s (%d), "
3846 "expected %s (%d)",
3847 option_name(poption), option_number(poption),
3848 option_type_name(poption->type), poption->type,
3849 option_type_name(OT_ENUM), OT_ENUM);
3851 if (packet->is_visible) {
3852 int i;
3854 psoption->enumerator.value = packet->val;
3855 psoption->enumerator.def = packet->default_val;
3857 if (NULL == psoption->enumerator.support_names) {
3858 /* First time we get this packet. */
3859 fc_assert(NULL == psoption->enumerator.pretty_names);
3860 psoption->enumerator.support_names = strvec_new();
3861 strvec_reserve(psoption->enumerator.support_names, packet->values_num);
3862 psoption->enumerator.pretty_names = strvec_new();
3863 strvec_reserve(psoption->enumerator.pretty_names, packet->values_num);
3864 for (i = 0; i < packet->values_num; i++) {
3865 strvec_set(psoption->enumerator.support_names, i,
3866 packet->support_names[i]);
3867 /* Store untranslated string from server. */
3868 strvec_set(psoption->enumerator.pretty_names, i,
3869 packet->pretty_names[i]);
3871 } else if (strvec_size(psoption->enumerator.support_names)
3872 != packet->values_num) {
3873 fc_assert(strvec_size(psoption->enumerator.support_names)
3874 == strvec_size(psoption->enumerator.pretty_names));
3875 /* The number of values have changed, we need to reset the list
3876 * of possible values. */
3877 strvec_reserve(psoption->enumerator.support_names, packet->values_num);
3878 strvec_reserve(psoption->enumerator.pretty_names, packet->values_num);
3879 for (i = 0; i < packet->values_num; i++) {
3880 strvec_set(psoption->enumerator.support_names, i,
3881 packet->support_names[i]);
3882 /* Store untranslated string from server. */
3883 strvec_set(psoption->enumerator.pretty_names, i,
3884 packet->pretty_names[i]);
3886 need_gui_remove = TRUE;
3887 need_gui_add = TRUE;
3888 } else {
3889 /* Check if a value changed, then we need to reset the list
3890 * of possible values. */
3891 const char *str;
3893 for (i = 0; i < packet->values_num; i++) {
3894 str = strvec_get(psoption->enumerator.pretty_names, i);
3895 if (NULL == str || 0 != strcmp(str, packet->pretty_names[i])) {
3896 /* Store untranslated string from server. */
3897 strvec_set(psoption->enumerator.pretty_names, i,
3898 packet->pretty_names[i]);
3899 need_gui_remove = TRUE;
3900 need_gui_add = TRUE;
3902 /* Support names are not visible, we don't need to check if it
3903 * has changed. */
3904 strvec_set(psoption->enumerator.support_names, i,
3905 packet->support_names[i]);
3910 handle_server_setting_common(psoption, packet);
3913 /****************************************************************************
3914 Receive a bitwise server setting info packet.
3915 ****************************************************************************/
3916 void handle_server_setting_bitwise
3917 (const struct packet_server_setting_bitwise *packet)
3919 struct option *poption = server_optset_option_by_number(packet->id);
3920 struct server_option *psoption = SERVER_OPTION(poption);
3921 bool need_gui_remove = FALSE;
3922 bool need_gui_add = FALSE;
3924 fc_assert_ret(NULL != poption);
3926 if (NULL == poption->common_vtable) {
3927 /* Not initialized yet. */
3928 poption->poptset = server_optset;
3929 poption->common_vtable = &server_option_common_vtable;
3930 poption->type = OT_BITWISE;
3931 poption->bitwise_vtable = &server_option_bitwise_vtable;
3933 fc_assert_ret_msg(OT_BITWISE == poption->type,
3934 "Server setting \"%s\" (nb %d) has type %s (%d), "
3935 "expected %s (%d)",
3936 option_name(poption), option_number(poption),
3937 option_type_name(poption->type), poption->type,
3938 option_type_name(OT_BITWISE), OT_BITWISE);
3940 if (packet->is_visible) {
3941 int i;
3943 psoption->bitwise.value = packet->val;
3944 psoption->bitwise.def = packet->default_val;
3946 if (NULL == psoption->bitwise.support_names) {
3947 /* First time we get this packet. */
3948 fc_assert(NULL == psoption->bitwise.pretty_names);
3949 psoption->bitwise.support_names = strvec_new();
3950 strvec_reserve(psoption->bitwise.support_names, packet->bits_num);
3951 psoption->bitwise.pretty_names = strvec_new();
3952 strvec_reserve(psoption->bitwise.pretty_names, packet->bits_num);
3953 for (i = 0; i < packet->bits_num; i++) {
3954 strvec_set(psoption->bitwise.support_names, i,
3955 packet->support_names[i]);
3956 /* Store untranslated string from server. */
3957 strvec_set(psoption->bitwise.pretty_names, i,
3958 packet->pretty_names[i]);
3960 } else if (strvec_size(psoption->bitwise.support_names)
3961 != packet->bits_num) {
3962 fc_assert(strvec_size(psoption->bitwise.support_names)
3963 == strvec_size(psoption->bitwise.pretty_names));
3964 /* The number of values have changed, we need to reset the list
3965 * of possible values. */
3966 strvec_reserve(psoption->bitwise.support_names, packet->bits_num);
3967 strvec_reserve(psoption->bitwise.pretty_names, packet->bits_num);
3968 for (i = 0; i < packet->bits_num; i++) {
3969 strvec_set(psoption->bitwise.support_names, i,
3970 packet->support_names[i]);
3971 /* Store untranslated string from server. */
3972 strvec_set(psoption->bitwise.pretty_names, i,
3973 packet->pretty_names[i]);
3975 need_gui_remove = TRUE;
3976 need_gui_add = TRUE;
3977 } else {
3978 /* Check if a value changed, then we need to reset the list
3979 * of possible values. */
3980 const char *str;
3982 for (i = 0; i < packet->bits_num; i++) {
3983 str = strvec_get(psoption->bitwise.pretty_names, i);
3984 if (NULL == str || 0 != strcmp(str, packet->pretty_names[i])) {
3985 /* Store untranslated string from server. */
3986 strvec_set(psoption->bitwise.pretty_names, i,
3987 packet->pretty_names[i]);
3988 need_gui_remove = TRUE;
3989 need_gui_add = TRUE;
3991 /* Support names are not visible, we don't need to check if it
3992 * has changed. */
3993 strvec_set(psoption->bitwise.support_names, i,
3994 packet->support_names[i]);
3999 handle_server_setting_common(psoption, packet);
4002 /****************************************************************************
4003 Returns the next valid option pointer for the current gui type.
4004 ****************************************************************************/
4005 static struct server_option *
4006 server_option_next_valid(struct server_option *poption)
4008 const struct server_option *const max =
4009 server_options + server_options_num;
4011 while (NULL != poption && poption < max && !poption->is_visible) {
4012 poption++;
4015 return (poption < max ? poption : NULL);
4018 /****************************************************************************
4019 Returns the server option associated to the number
4020 ****************************************************************************/
4021 struct option *server_optset_option_by_number(int id)
4023 if (0 > id || id > server_options_num) {
4024 return NULL;
4026 return OPTION(server_options + id);
4029 /****************************************************************************
4030 Returns the first valid (visible) option pointer.
4031 ****************************************************************************/
4032 struct option *server_optset_option_first(void)
4034 return OPTION(server_option_next_valid(server_options));
4037 /****************************************************************************
4038 Returns the number of server option categories.
4039 ****************************************************************************/
4040 int server_optset_category_number(void)
4042 return server_options_categories_num;
4045 /****************************************************************************
4046 Returns the name (translated) of the server option category.
4047 ****************************************************************************/
4048 const char *server_optset_category_name(int category)
4050 if (0 > category || category >= server_options_categories_num) {
4051 return NULL;
4054 return server_options_categories[category];
4057 /***************************************************************************
4058 Returns the number of this server option.
4059 ****************************************************************************/
4060 static int server_option_number(const struct option *poption)
4062 return SERVER_OPTION(poption) - server_options;
4065 /****************************************************************************
4066 Returns the name of this server option.
4067 ****************************************************************************/
4068 static const char *server_option_name(const struct option *poption)
4070 return SERVER_OPTION(poption)->name;
4073 /****************************************************************************
4074 Returns the (translated) description of this server option.
4075 ****************************************************************************/
4076 static const char *server_option_description(const struct option *poption)
4078 return SERVER_OPTION(poption)->description;
4081 /****************************************************************************
4082 Returns the (translated) help text for this server option.
4083 ****************************************************************************/
4084 static const char *server_option_help_text(const struct option *poption)
4086 return SERVER_OPTION(poption)->help_text;
4089 /****************************************************************************
4090 Returns the category of this server option.
4091 ****************************************************************************/
4092 static int server_option_category(const struct option *poption)
4094 return SERVER_OPTION(poption)->category;
4097 /****************************************************************************
4098 Returns TRUE if this client option can be modified.
4099 ****************************************************************************/
4100 static bool server_option_is_changeable(const struct option *poption)
4102 return SERVER_OPTION(poption)->is_changeable;
4105 /****************************************************************************
4106 Returns the next valid (visible) option pointer.
4107 ****************************************************************************/
4108 static struct option *server_option_next(const struct option *poption)
4110 return OPTION(server_option_next_valid(SERVER_OPTION(poption) + 1));
4113 /****************************************************************************
4114 Returns the value of this server option of type OT_BOOLEAN.
4115 ****************************************************************************/
4116 static bool server_option_bool_get(const struct option *poption)
4118 return SERVER_OPTION(poption)->boolean.value;
4121 /****************************************************************************
4122 Returns the default value of this server option of type OT_BOOLEAN.
4123 ****************************************************************************/
4124 static bool server_option_bool_def(const struct option *poption)
4126 return SERVER_OPTION(poption)->boolean.def;
4129 /****************************************************************************
4130 Set the value of this server option of type OT_BOOLEAN. Returns TRUE if
4131 the value changed.
4132 ****************************************************************************/
4133 static bool server_option_bool_set(struct option *poption, bool val)
4135 struct server_option *psoption = SERVER_OPTION(poption);
4137 if (psoption->boolean.value == val) {
4138 return FALSE;
4141 send_chat_printf("/set %s %s", psoption->name,
4142 val ? "enabled" : "disabled");
4143 return TRUE;
4146 /****************************************************************************
4147 Returns the value of this server option of type OT_INTEGER.
4148 ****************************************************************************/
4149 static int server_option_int_get(const struct option *poption)
4151 return SERVER_OPTION(poption)->integer.value;
4154 /****************************************************************************
4155 Returns the default value of this server option of type OT_INTEGER.
4156 ****************************************************************************/
4157 static int server_option_int_def(const struct option *poption)
4159 return SERVER_OPTION(poption)->integer.def;
4162 /****************************************************************************
4163 Returns the minimal value for this server option of type OT_INTEGER.
4164 ****************************************************************************/
4165 static int server_option_int_min(const struct option *poption)
4167 return SERVER_OPTION(poption)->integer.min;
4170 /****************************************************************************
4171 Returns the maximal value for this server option of type OT_INTEGER.
4172 ****************************************************************************/
4173 static int server_option_int_max(const struct option *poption)
4175 return SERVER_OPTION(poption)->integer.max;
4178 /****************************************************************************
4179 Set the value of this server option of type OT_INTEGER. Returns TRUE if
4180 the value changed.
4181 ****************************************************************************/
4182 static bool server_option_int_set(struct option *poption, int val)
4184 struct server_option *psoption = SERVER_OPTION(poption);
4186 if (val < psoption->integer.min
4187 || val > psoption->integer.max
4188 || psoption->integer.value == val) {
4189 return FALSE;
4192 send_chat_printf("/set %s %d", psoption->name, val);
4193 return TRUE;
4196 /****************************************************************************
4197 Returns the value of this server option of type OT_STRING.
4198 ****************************************************************************/
4199 static const char *server_option_str_get(const struct option *poption)
4201 return SERVER_OPTION(poption)->string.value;
4204 /****************************************************************************
4205 Returns the default value of this server option of type OT_STRING.
4206 ****************************************************************************/
4207 static const char *server_option_str_def(const struct option *poption)
4209 return SERVER_OPTION(poption)->string.def;
4212 /****************************************************************************
4213 Returns the possible string values of this server option of type
4214 OT_STRING.
4215 ****************************************************************************/
4216 static const struct strvec *
4217 server_option_str_values(const struct option *poption)
4219 return NULL;
4222 /****************************************************************************
4223 Set the value of this server option of type OT_STRING. Returns TRUE if
4224 the value changed.
4225 ****************************************************************************/
4226 static bool server_option_str_set(struct option *poption, const char *str)
4228 struct server_option *psoption = SERVER_OPTION(poption);
4230 if (0 == strcmp(psoption->string.value, str)) {
4231 return FALSE;
4234 send_chat_printf("/set %s %s", psoption->name, str);
4235 return TRUE;
4238 /****************************************************************************
4239 Returns the current value of this server option of type OT_ENUM.
4240 ****************************************************************************/
4241 static int server_option_enum_get(const struct option *poption)
4243 return SERVER_OPTION(poption)->enumerator.value;
4246 /****************************************************************************
4247 Returns the default value of this server option of type OT_ENUM.
4248 ****************************************************************************/
4249 static int server_option_enum_def(const struct option *poption)
4251 return SERVER_OPTION(poption)->enumerator.def;
4254 /****************************************************************************
4255 Returns the user-visible, translateable (but untranslated) "pretty" names
4256 of this server option of type OT_ENUM.
4257 ****************************************************************************/
4258 static const struct strvec *
4259 server_option_enum_pretty(const struct option *poption)
4261 return SERVER_OPTION(poption)->enumerator.pretty_names;
4264 /****************************************************************************
4265 Set the value of this server option of type OT_ENUM. Returns TRUE if
4266 the value changed.
4267 ****************************************************************************/
4268 static bool server_option_enum_set(struct option *poption, int val)
4270 struct server_option *psoption = SERVER_OPTION(poption);
4271 const char *name;
4273 if (val == psoption->enumerator.value
4274 || !(name = strvec_get(psoption->enumerator.support_names, val))) {
4275 return FALSE;
4278 send_chat_printf("/set %s \"%s\"", psoption->name, name);
4279 return TRUE;
4282 /****************************************************************************
4283 Returns the long support names of the values of the server option of type
4284 OT_ENUM.
4285 ****************************************************************************/
4286 static void server_option_enum_support_name(const struct option *poption,
4287 const char **pvalue,
4288 const char **pdefault)
4290 const struct server_option *psoption = SERVER_OPTION(poption);
4291 const struct strvec *values = psoption->enumerator.support_names;
4293 if (NULL != pvalue) {
4294 *pvalue = strvec_get(values, psoption->enumerator.value);
4296 if (NULL != pdefault) {
4297 *pdefault = strvec_get(values, psoption->enumerator.def);
4301 /****************************************************************************
4302 Returns the current value of this server option of type OT_BITWISE.
4303 ****************************************************************************/
4304 static unsigned server_option_bitwise_get(const struct option *poption)
4306 return SERVER_OPTION(poption)->bitwise.value;
4309 /****************************************************************************
4310 Returns the default value of this server option of type OT_BITWISE.
4311 ****************************************************************************/
4312 static unsigned server_option_bitwise_def(const struct option *poption)
4314 return SERVER_OPTION(poption)->bitwise.def;
4317 /****************************************************************************
4318 Returns the user-visible, translateable (but untranslated) "pretty" names
4319 of this server option of type OT_BITWISE.
4320 ****************************************************************************/
4321 static const struct strvec *
4322 server_option_bitwise_pretty(const struct option *poption)
4324 return SERVER_OPTION(poption)->bitwise.pretty_names;
4327 /****************************************************************************
4328 Compute the long support names of a value.
4329 ****************************************************************************/
4330 static void server_option_bitwise_support_base(const struct strvec *values,
4331 unsigned val,
4332 char *buf, size_t buf_len)
4334 int bit;
4336 buf[0] = '\0';
4337 for (bit = 0; bit < strvec_size(values); bit++) {
4338 if ((1 << bit) & val) {
4339 if ('\0' != buf[0]) {
4340 fc_strlcat(buf, "|", buf_len);
4342 fc_strlcat(buf, strvec_get(values, bit), buf_len);
4347 /****************************************************************************
4348 Set the value of this server option of type OT_BITWISE. Returns TRUE if
4349 the value changed.
4350 ****************************************************************************/
4351 static bool server_option_bitwise_set(struct option *poption, unsigned val)
4353 struct server_option *psoption = SERVER_OPTION(poption);
4354 char name[MAX_LEN_MSG];
4356 if (val == psoption->bitwise.value) {
4357 return FALSE;
4360 server_option_bitwise_support_base(psoption->bitwise.support_names, val,
4361 name, sizeof(name));
4362 send_chat_printf("/set %s \"%s\"", psoption->name, name);
4363 return TRUE;
4366 /****************************************************************************
4367 Compute the long support names of the values of the server option of type
4368 OT_BITWISE.
4369 ****************************************************************************/
4370 static void server_option_bitwise_support_name(const struct option *poption,
4371 char *val_buf, size_t val_len,
4372 char *def_buf, size_t def_len)
4374 const struct server_option *psoption = SERVER_OPTION(poption);
4375 const struct strvec *values = psoption->bitwise.support_names;
4377 if (NULL != val_buf && 0 < val_len) {
4378 server_option_bitwise_support_base(values, psoption->bitwise.value,
4379 val_buf, val_len);
4381 if (NULL != def_buf && 0 < def_len) {
4382 server_option_bitwise_support_base(values, psoption->bitwise.def,
4383 def_buf, def_len);
4388 /** Message Options: **/
4390 int messages_where[E_COUNT];
4393 /****************************************************************
4394 These could be a static table initialisation, except
4395 its easier to do it this way.
4396 *****************************************************************/
4397 static void message_options_init(void)
4399 int none[] = {
4400 E_IMP_BUY, E_IMP_SOLD, E_UNIT_BUY,
4401 E_UNIT_LOST_ATT, E_UNIT_WIN_ATT, E_GAME_START,
4402 E_NATION_SELECTED, E_CITY_BUILD, E_NEXT_YEAR,
4403 E_CITY_PRODUCTION_CHANGED,
4404 E_CITY_MAY_SOON_GROW, E_WORKLIST, E_AI_DEBUG
4406 int out_only[] = {
4407 E_CHAT_MSG, E_CHAT_ERROR, E_CONNECTION, E_LOG_ERROR, E_SETTING,
4408 E_VOTE_NEW, E_VOTE_RESOLVED, E_VOTE_ABORTED
4410 int all[] = {
4411 E_LOG_FATAL, E_SCRIPT
4413 int i;
4415 for (i = 0; i <= event_type_max(); i++) {
4416 /* Include possible undefined values. */
4417 messages_where[i] = MW_MESSAGES;
4419 for (i = 0; i < ARRAY_SIZE(none); i++) {
4420 messages_where[none[i]] = 0;
4422 for (i = 0; i < ARRAY_SIZE(out_only); i++) {
4423 messages_where[out_only[i]] = MW_OUTPUT;
4425 for (i = 0; i < ARRAY_SIZE(all); i++) {
4426 messages_where[all[i]] = MW_MESSAGES | MW_POPUP;
4429 events_init();
4432 /****************************************************************
4433 Free resources allocated for message options system
4434 *****************************************************************/
4435 static void message_options_free(void)
4437 events_free();
4440 /****************************************************************
4441 Load the message options; use the function defined by
4442 specnum.h (see also events.h).
4443 *****************************************************************/
4444 static void message_options_load(struct section_file *file,
4445 const char *prefix)
4447 enum event_type event;
4448 int i, num_events;
4449 const char *p;
4451 if (!secfile_lookup_int(file, &num_events, "messages.count")) {
4452 /* version < 2.2 */
4453 /* Order of the events in 2.1. */
4454 const enum event_type old_events[] = {
4455 E_CITY_CANTBUILD, E_CITY_LOST, E_CITY_LOVE, E_CITY_DISORDER,
4456 E_CITY_FAMINE, E_CITY_FAMINE_FEARED, E_CITY_GROWTH,
4457 E_CITY_MAY_SOON_GROW, E_CITY_AQUEDUCT, E_CITY_AQ_BUILDING,
4458 E_CITY_NORMAL, E_CITY_NUKED, E_CITY_CMA_RELEASE, E_CITY_GRAN_THROTTLE,
4459 E_CITY_TRANSFER, E_CITY_BUILD, E_CITY_PRODUCTION_CHANGED,
4460 E_WORKLIST, E_UPRISING, E_CIVIL_WAR, E_ANARCHY, E_FIRST_CONTACT,
4461 E_NEW_GOVERNMENT, E_LOW_ON_FUNDS, E_POLLUTION, E_REVOLT_DONE,
4462 E_REVOLT_START, E_SPACESHIP, E_MY_DIPLOMAT_BRIBE,
4463 E_DIPLOMATIC_INCIDENT, E_MY_DIPLOMAT_ESCAPE, E_MY_DIPLOMAT_EMBASSY,
4464 E_MY_DIPLOMAT_FAILED, E_MY_DIPLOMAT_INCITE, E_MY_DIPLOMAT_POISON,
4465 E_MY_DIPLOMAT_SABOTAGE, E_MY_DIPLOMAT_THEFT, E_ENEMY_DIPLOMAT_BRIBE,
4466 E_ENEMY_DIPLOMAT_EMBASSY, E_ENEMY_DIPLOMAT_FAILED,
4467 E_ENEMY_DIPLOMAT_INCITE, E_ENEMY_DIPLOMAT_POISON,
4468 E_ENEMY_DIPLOMAT_SABOTAGE, E_ENEMY_DIPLOMAT_THEFT,
4469 E_CARAVAN_ACTION, E_SCRIPT, E_BROADCAST_REPORT, E_GAME_END,
4470 E_GAME_START, E_NATION_SELECTED, E_DESTROYED, E_REPORT, E_TURN_BELL,
4471 E_NEXT_YEAR, E_GLOBAL_ECO, E_NUKE, E_HUT_BARB, E_HUT_CITY, E_HUT_GOLD,
4472 E_HUT_BARB_KILLED, E_HUT_MERC, E_HUT_SETTLER, E_HUT_TECH,
4473 E_HUT_BARB_CITY_NEAR, E_IMP_BUY, E_IMP_BUILD, E_IMP_AUCTIONED,
4474 E_IMP_AUTO, E_IMP_SOLD, E_TECH_GAIN, E_TECH_LEARNED, E_TREATY_ALLIANCE,
4475 E_TREATY_BROKEN, E_TREATY_CEASEFIRE, E_TREATY_PEACE,
4476 E_TREATY_SHARED_VISION, E_UNIT_LOST_ATT, E_UNIT_WIN_ATT, E_UNIT_BUY,
4477 E_UNIT_BUILT, E_UNIT_LOST_DEF, E_UNIT_WIN, E_UNIT_BECAME_VET,
4478 E_UNIT_UPGRADED, E_UNIT_RELOCATED, E_UNIT_ORDERS, E_WONDER_BUILD,
4479 E_WONDER_OBSOLETE, E_WONDER_STARTED, E_WONDER_STOPPED,
4480 E_WONDER_WILL_BE_BUILT, E_DIPLOMACY, E_TREATY_EMBASSY,
4481 E_BAD_COMMAND, E_SETTING, E_CHAT_MSG, E_MESSAGE_WALL, E_CHAT_ERROR,
4482 E_CONNECTION, E_AI_DEBUG
4484 const size_t old_events_num = ARRAY_SIZE(old_events);
4486 for (i = 0; i < old_events_num; i++) {
4487 messages_where[old_events[i]] =
4488 secfile_lookup_int_default(file, messages_where[old_events[i]],
4489 "%s.message_where_%02d", prefix, i);
4491 return;
4494 for (i = 0; i < num_events; i++) {
4495 p = secfile_lookup_str(file, "messages.event%d.name", i);
4496 if (NULL == p) {
4497 log_error("Corruption in file %s: %s",
4498 secfile_name(file), secfile_error());
4499 continue;
4501 event = event_type_by_name(p, strcmp);
4502 if (!event_type_is_valid(event)) {
4503 log_error("Event not supported: %s", p);
4504 continue;
4507 if (!secfile_lookup_int(file, &messages_where[event],
4508 "messages.event%d.where", i)) {
4509 log_error("Corruption in file %s: %s",
4510 secfile_name(file), secfile_error());
4515 /****************************************************************
4516 Save the message options; use the function defined by
4517 specnum.h (see also events.h).
4518 *****************************************************************/
4519 static void message_options_save(struct section_file *file,
4520 const char *prefix)
4522 enum event_type event;
4523 int i = 0;
4525 for (event = event_type_begin(); event != event_type_end();
4526 event = event_type_next(event)) {
4527 secfile_insert_str(file, event_type_name(event),
4528 "messages.event%d.name", i);
4529 secfile_insert_int(file, messages_where[i],
4530 "messages.event%d.where", i);
4531 i++;
4534 secfile_insert_int(file, i, "messages.count");
4538 /****************************************************************
4539 Does heavy lifting for looking up a preset.
4540 *****************************************************************/
4541 static void load_cma_preset(struct section_file *file, int i)
4543 struct cm_parameter parameter;
4544 const char *name =
4545 secfile_lookup_str_default(file, "preset",
4546 "cma.preset%d.name", i);
4548 output_type_iterate(o) {
4549 parameter.minimal_surplus[o] =
4550 secfile_lookup_int_default(file, 0, "cma.preset%d.minsurp%d", i, o);
4551 parameter.factor[o] =
4552 secfile_lookup_int_default(file, 0, "cma.preset%d.factor%d", i, o);
4553 } output_type_iterate_end;
4554 parameter.require_happy =
4555 secfile_lookup_bool_default(file, FALSE, "cma.preset%d.reqhappy", i);
4556 parameter.happy_factor =
4557 secfile_lookup_int_default(file, 0, "cma.preset%d.happyfactor", i);
4558 parameter.allow_disorder = FALSE;
4559 parameter.allow_specialists = TRUE;
4561 cmafec_preset_add(name, &parameter);
4564 /****************************************************************
4565 Does heavy lifting for inserting a preset.
4566 *****************************************************************/
4567 static void save_cma_preset(struct section_file *file, int i)
4569 const struct cm_parameter *const pparam = cmafec_preset_get_parameter(i);
4570 char *name = cmafec_preset_get_descr(i);
4572 secfile_insert_str(file, name, "cma.preset%d.name", i);
4574 output_type_iterate(o) {
4575 secfile_insert_int(file, pparam->minimal_surplus[o],
4576 "cma.preset%d.minsurp%d", i, o);
4577 secfile_insert_int(file, pparam->factor[o],
4578 "cma.preset%d.factor%d", i, o);
4579 } output_type_iterate_end;
4580 secfile_insert_bool(file, pparam->require_happy,
4581 "cma.preset%d.reqhappy", i);
4582 secfile_insert_int(file, pparam->happy_factor,
4583 "cma.preset%d.happyfactor", i);
4586 /****************************************************************
4587 Insert all cma presets.
4588 *****************************************************************/
4589 static void save_cma_presets(struct section_file *file)
4591 int i;
4593 secfile_insert_int_comment(file, cmafec_preset_num(),
4594 _("If you add a preset by hand,"
4595 " also update \"number_of_presets\""),
4596 "cma.number_of_presets");
4597 for (i = 0; i < cmafec_preset_num(); i++) {
4598 save_cma_preset(file, i);
4603 /* Old rc file name. */
4604 #define OLD_OPTION_FILE_NAME ".civclientrc"
4605 /* New rc file name. */
4606 #define NEW_OPTION_FILE_NAME ".freeciv-client-rc-%d.%d"
4607 #define MAJOR_NEW_OPTION_FILE_NAME MAJOR_VERSION
4608 #if IS_DEVEL_VERSION && ! IS_FREEZE_VERSION
4609 #define MINOR_NEW_OPTION_FILE_NAME (MINOR_VERSION + 1)
4610 #else
4611 #define MINOR_NEW_OPTION_FILE_NAME MINOR_VERSION
4612 #endif /* IS_DEVEL_VERSION */
4613 /* The first version the new option name appeared (2.2). */
4614 #define FIRST_MAJOR_NEW_OPTION_FILE_NAME 2
4615 #define FIRST_MINOR_NEW_OPTION_FILE_NAME 2
4616 /* The first version the new boolean values appeared (2.3). */
4617 #define FIRST_MAJOR_NEW_BOOLEAN 2
4618 #define FIRST_MINOR_NEW_BOOLEAN 3
4619 /****************************************************************
4620 Returns pointer to static memory containing name of the current
4621 option file. Usually used for saving.
4622 Ie, based on FREECIV_OPT env var, and home dir. (or a
4623 OPTION_FILE_NAME define defined in fc_config.h)
4624 Or NULL if problem.
4625 *****************************************************************/
4626 static const char *get_current_option_file_name(void)
4628 static char name_buffer[256];
4629 const char *name;
4631 name = getenv("FREECIV_OPT");
4633 if (name) {
4634 sz_strlcpy(name_buffer, name);
4635 } else {
4636 #ifdef OPTION_FILE_NAME
4637 fc_strlcpy(name_buffer, OPTION_FILE_NAME, sizeof(name_buffer));
4638 #else
4639 name = user_home_dir();
4640 if (!name) {
4641 log_error(_("Cannot find your home directory"));
4642 return NULL;
4644 fc_snprintf(name_buffer, sizeof(name_buffer),
4645 "%s/" NEW_OPTION_FILE_NAME, name,
4646 MAJOR_NEW_OPTION_FILE_NAME, MINOR_NEW_OPTION_FILE_NAME);
4647 #endif /* OPTION_FILE_NAME */
4649 log_verbose("settings file is %s", name_buffer);
4650 return name_buffer;
4653 /****************************************************************************
4654 Check the last option file we saved. Usually used to load. Ie, based on
4655 FREECIV_OPT env var, and home dir. (or a OPTION_FILE_NAME define defined
4656 in fc_config.h), or NULL if not found.
4658 Set in allow_digital_boolean if we should look for old boolean values
4659 (saved as 0 and 1), so if the rc file version is older than 2.3.0.
4660 ****************************************************************************/
4661 static const char *get_last_option_file_name(bool *allow_digital_boolean)
4663 static char name_buffer[256];
4664 const char *name;
4666 *allow_digital_boolean = FALSE;
4667 name = getenv("FREECIV_OPT");
4668 if (name) {
4669 sz_strlcpy(name_buffer, name);
4670 } else {
4671 #ifdef OPTION_FILE_NAME
4672 fc_strlcpy(name_buffer, OPTION_FILE_NAME, sizeof(name_buffer));
4673 #else
4674 int major, minor;
4675 struct stat buf;
4677 name = user_home_dir();
4678 if (!name) {
4679 log_error(_("Cannot find your home directory"));
4680 return NULL;
4682 for (major = MAJOR_NEW_OPTION_FILE_NAME,
4683 minor = MINOR_NEW_OPTION_FILE_NAME;
4684 major >= FIRST_MAJOR_NEW_OPTION_FILE_NAME; major--) {
4685 for (; (major == FIRST_MAJOR_NEW_OPTION_FILE_NAME
4686 ? minor >= FIRST_MINOR_NEW_OPTION_FILE_NAME
4687 : minor >= 0); minor--) {
4688 fc_snprintf(name_buffer, sizeof(name_buffer),
4689 "%s/" NEW_OPTION_FILE_NAME, name, major, minor);
4690 if (0 == fc_stat(name_buffer, &buf)) {
4691 if (MAJOR_NEW_OPTION_FILE_NAME != major
4692 || MINOR_NEW_OPTION_FILE_NAME != minor) {
4693 log_normal(_("Didn't find '%s' option file, "
4694 "loading from '%s' instead."),
4695 get_current_option_file_name() + strlen(name) + 1,
4696 name_buffer + strlen(name) + 1);
4698 if (FIRST_MAJOR_NEW_BOOLEAN > major
4699 || (FIRST_MAJOR_NEW_BOOLEAN == major
4700 && FIRST_MINOR_NEW_BOOLEAN > minor)) {
4701 *allow_digital_boolean = TRUE;
4703 return name_buffer;
4706 minor = 99; /* Looks enough big. */
4708 /* Try with the old one. */
4709 fc_snprintf(name_buffer, sizeof(name_buffer),
4710 "%s/" OLD_OPTION_FILE_NAME, name);
4711 if (0 == fc_stat(name_buffer, &buf)) {
4712 log_normal(_("Didn't find '%s' option file, "
4713 "loading from '%s' instead."),
4714 get_current_option_file_name() + strlen(name) + 1,
4715 OLD_OPTION_FILE_NAME);
4716 *allow_digital_boolean = TRUE;
4717 return name_buffer;
4718 } else {
4719 return NULL;
4721 #endif /* OPTION_FILE_NAME */
4723 log_verbose("settings file is %s", name_buffer);
4724 return name_buffer;
4726 #undef OLD_OPTION_FILE_NAME
4727 #undef NEW_OPTION_FILE_NAME
4728 #undef FIRST_MAJOR_NEW_OPTION_FILE_NAME
4729 #undef FIRST_MINOR_NEW_OPTION_FILE_NAME
4730 #undef FIRST_MAJOR_NEW_BOOLEAN
4731 #undef FIRST_MINOR_NEW_BOOLEAN
4734 /****************************************************************************
4735 Desired settable options.
4736 ****************************************************************************/
4737 #define SPECHASH_TAG settable_options
4738 #define SPECHASH_KEY_TYPE char *
4739 #define SPECHASH_DATA_TYPE char *
4740 #define SPECHASH_KEY_VAL genhash_str_val_func
4741 #define SPECHASH_KEY_COMP genhash_str_comp_func
4742 #define SPECHASH_KEY_COPY genhash_str_copy_func
4743 #define SPECHASH_KEY_FREE genhash_str_free_func
4744 #define SPECHASH_DATA_COPY genhash_str_copy_func
4745 #define SPECHASH_DATA_FREE genhash_str_free_func
4746 #include "spechash.h"
4747 #define settable_options_hash_iterate(hash, name, value) \
4748 TYPED_HASH_ITERATE(const char *, const char *, hash, name, value)
4749 #define settable_options_hash_iterate_end HASH_ITERATE_END
4751 static struct settable_options_hash *settable_options_hash = NULL;
4753 /**************************************************************************
4754 Load the server options.
4755 **************************************************************************/
4756 static void settable_options_load(struct section_file *sf)
4758 char buf[64];
4759 const struct section *psection;
4760 const struct entry_list *entries;
4761 const char *string;
4762 bool bval;
4763 int ival;
4765 fc_assert_ret(NULL != settable_options_hash);
4767 settable_options_hash_clear(settable_options_hash);
4769 psection = secfile_section_by_name(sf, "server");
4770 if (NULL == psection) {
4771 /* Does not exist! */
4772 return;
4775 entries = section_entries(psection);
4776 entry_list_iterate(entries, pentry) {
4777 string = NULL;
4778 switch (entry_type(pentry)) {
4779 case ENTRY_BOOL:
4780 if (entry_bool_get(pentry, &bval)) {
4781 fc_strlcpy(buf, bval ? "enabled" : "disabled", sizeof(buf));
4782 string = buf;
4784 break;
4786 case ENTRY_INT:
4787 if (entry_int_get(pentry, &ival)) {
4788 fc_snprintf(buf, sizeof(buf), "%d", ival);
4789 string = buf;
4791 break;
4793 case ENTRY_STR:
4794 (void) entry_str_get(pentry, &string);
4795 break;
4798 if (NULL == string) {
4799 log_error("Entry type variant of \"%s.%s\" is not supported.",
4800 section_name(psection), entry_name(pentry));
4801 continue;
4804 settable_options_hash_insert(settable_options_hash, entry_name(pentry),
4805 string);
4806 } entry_list_iterate_end;
4809 /****************************************************************
4810 Save the desired server options.
4811 *****************************************************************/
4812 static void settable_options_save(struct section_file *sf)
4814 fc_assert_ret(NULL != settable_options_hash);
4816 settable_options_hash_iterate(settable_options_hash, name, value) {
4817 if (!fc_strcasecmp(name, "gameseed") || !fc_strcasecmp(name, "mapseed")) {
4818 /* Do not save mapseed or gameseed. */
4819 continue;
4821 secfile_insert_str(sf, value, "server.%s", name);
4822 } settable_options_hash_iterate_end;
4825 /****************************************************************************
4826 Update the desired settable options hash table from the current
4827 setting configuration.
4828 ****************************************************************************/
4829 void desired_settable_options_update(void)
4831 char val_buf[1024], def_buf[1024];
4832 const char *value, *def_val;
4834 fc_assert_ret(NULL != settable_options_hash);
4836 options_iterate(server_optset, poption) {
4837 value = NULL;
4838 def_val = NULL;
4839 switch (option_type(poption)) {
4840 case OT_BOOLEAN:
4841 fc_strlcpy(val_buf, option_bool_get(poption) ? "enabled" : "disabled",
4842 sizeof(val_buf));
4843 value = val_buf;
4844 fc_strlcpy(def_buf, option_bool_def(poption) ? "enabled" : "disabled",
4845 sizeof(def_buf));
4846 def_val = def_buf;
4847 break;
4848 case OT_INTEGER:
4849 fc_snprintf(val_buf, sizeof(val_buf), "%d", option_int_get(poption));
4850 value = val_buf;
4851 fc_snprintf(def_buf, sizeof(def_buf), "%d", option_int_def(poption));
4852 def_val = def_buf;
4853 break;
4854 case OT_STRING:
4855 value = option_str_get(poption);
4856 def_val = option_str_def(poption);
4857 break;
4858 case OT_ENUM:
4859 server_option_enum_support_name(poption, &value, &def_val);
4860 break;
4861 case OT_BITWISE:
4862 server_option_bitwise_support_name(poption, val_buf, sizeof(val_buf),
4863 def_buf, sizeof(def_buf));
4864 value = val_buf;
4865 def_val = def_buf;
4866 break;
4867 case OT_FONT:
4868 case OT_COLOR:
4869 case OT_VIDEO_MODE:
4870 break;
4873 if (NULL == value || NULL == def_val) {
4874 log_error("Option type %s (%d) not supported for '%s'.",
4875 option_type_name(option_type(poption)), option_type(poption),
4876 option_name(poption));
4877 continue;
4880 if (0 == strcmp(value, def_val)) {
4881 /* Not set, using default... */
4882 settable_options_hash_remove(settable_options_hash,
4883 option_name(poption));
4884 } else {
4885 /* Really desired. */
4886 settable_options_hash_replace(settable_options_hash,
4887 option_name(poption), value);
4889 } options_iterate_end;
4892 /****************************************************************
4893 Update a desired settable option in the hash table from a value
4894 which can be different of the current consiguration.
4895 *****************************************************************/
4896 void desired_settable_option_update(const char *op_name,
4897 const char *op_value,
4898 bool allow_replace)
4900 fc_assert_ret(NULL != settable_options_hash);
4902 if (allow_replace) {
4903 settable_options_hash_replace(settable_options_hash, op_name, op_value);
4904 } else {
4905 settable_options_hash_insert(settable_options_hash, op_name, op_value);
4909 /****************************************************************************
4910 Convert old integer to new values (Freeciv 2.2.x to Freeciv 2.3.x).
4911 Very ugly hack. TODO: Remove this later.
4912 ****************************************************************************/
4913 static bool settable_option_upgrade_value(const struct option *poption,
4914 int old_value,
4915 char *buf, size_t buf_len)
4917 const char *name = option_name(poption);
4919 #define SETTING_CASE(ARG_name, ...) \
4920 if (0 == strcmp(ARG_name, name)) { \
4921 static const char *values[] = { __VA_ARGS__ }; \
4922 if (0 <= old_value && old_value < ARRAY_SIZE(values) \
4923 && NULL != values[old_value]) { \
4924 fc_strlcpy(buf, values[old_value], buf_len); \
4925 return TRUE; \
4926 } else { \
4927 return FALSE; \
4931 SETTING_CASE("topology", "", "WRAPX", "WRAPY", "WRAPX|WRAPY", "ISO",
4932 "WRAPX|ISO", "WRAPY|ISO", "WRAPX|WRAPY|ISO", "HEX",
4933 "WRAPX|HEX", "WRAPY|HEX", "WRAPX|WRAPY|HEX", "ISO|HEX",
4934 "WRAPX|ISO|HEX", "WRAPY|ISO|HEX", "WRAPX|WRAPY|ISO|HEX");
4935 SETTING_CASE("generator", NULL, "RANDOM", "FRACTAL", "ISLAND");
4936 SETTING_CASE("startpos", "DEFAULT", "SINGLE", "2or3", "ALL", "VARIABLE");
4937 SETTING_CASE("borders", "DISABLED", "ENABLED", "SEE_INSIDE", "EXPAND");
4938 SETTING_CASE("diplomacy", "ALL", "HUMAN", "AI", "TEAM", "DISABLED");
4939 SETTING_CASE("citynames", "NO_RESTRICTIONS", "PLAYER_UNIQUE",
4940 "GLOBAL_UNIQUE", "NO_STEALING");
4941 SETTING_CASE("barbarians", "DISABLED", "HUTS_ONLY", "NORMAL", "FREQUENT",
4942 "HORDES");
4943 SETTING_CASE("phasemode", "ALL", "PLAYER", "TEAM");
4944 SETTING_CASE("compresstype", "PLAIN", "LIBZ", "BZIP2");
4946 #undef SETTING_CASE
4947 return FALSE;
4950 /****************************************************************************
4951 Send the desired server options to the server.
4952 ****************************************************************************/
4953 static void desired_settable_option_send(struct option *poption)
4955 char *desired;
4956 int value;
4958 fc_assert_ret(NULL != settable_options_hash);
4960 if (!settable_options_hash_lookup(settable_options_hash,
4961 option_name(poption), &desired)) {
4962 /* No change explicitly desired. */
4963 return;
4966 switch (option_type(poption)) {
4967 case OT_BOOLEAN:
4968 if ((0 == fc_strcasecmp("enabled", desired)
4969 || (str_to_int(desired, &value) && 1 == value))
4970 && !option_bool_get(poption)) {
4971 send_chat_printf("/set %s enabled", option_name(poption));
4972 } else if ((0 == fc_strcasecmp("disabled", desired)
4973 || (str_to_int(desired, &value) && 0 == value))
4974 && option_bool_get(poption)) {
4975 send_chat_printf("/set %s disabled", option_name(poption));
4977 return;
4978 case OT_INTEGER:
4979 if (str_to_int(desired, &value) && value != option_int_get(poption)) {
4980 send_chat_printf("/set %s %d", option_name(poption), value);
4982 return;
4983 case OT_STRING:
4984 if (0 != strcmp(desired, option_str_get(poption))) {
4985 send_chat_printf("/set %s \"%s\"", option_name(poption), desired);
4987 return;
4988 case OT_ENUM:
4990 char desired_buf[256];
4991 const char *value_str;
4993 /* Handle old values. */
4994 if (str_to_int(desired, &value)
4995 && settable_option_upgrade_value(poption, value, desired_buf,
4996 sizeof(desired_buf))) {
4997 desired = desired_buf;
5000 server_option_enum_support_name(poption, &value_str, NULL);
5001 if (0 != strcmp(desired, value_str)) {
5002 send_chat_printf("/set %s \"%s\"", option_name(poption), desired);
5005 return;
5006 case OT_BITWISE:
5008 char desired_buf[256], value_buf[256];
5010 /* Handle old values. */
5011 if (str_to_int(desired, &value)
5012 && settable_option_upgrade_value(poption, value, desired_buf,
5013 sizeof(desired_buf))) {
5014 desired = desired_buf;
5017 server_option_bitwise_support_name(poption, value_buf,
5018 sizeof(value_buf), NULL, 0);
5019 if (0 != strcmp(desired, value_buf)) {
5020 send_chat_printf("/set %s \"%s\"", option_name(poption), desired);
5023 return;
5024 case OT_FONT:
5025 case OT_COLOR:
5026 case OT_VIDEO_MODE:
5027 break;
5030 log_error("Option type %s (%d) not supported for '%s'.",
5031 option_type_name(option_type(poption)), option_type(poption),
5032 option_name(poption));
5036 /****************************************************************************
5037 City and player report dialog options.
5038 ****************************************************************************/
5039 #define SPECHASH_TAG dialog_options
5040 #define SPECHASH_KEY_TYPE char *
5041 #define SPECHASH_DATA_TYPE bool
5042 #define SPECHASH_KEY_VAL genhash_str_val_func
5043 #define SPECHASH_KEY_COMP genhash_str_comp_func
5044 #define SPECHASH_KEY_COPY genhash_str_copy_func
5045 #define SPECHASH_KEY_FREE genhash_str_free_func
5046 #define SPECHASH_DATA_TO_PTR FC_INT_TO_PTR
5047 #define SPECHASH_PTR_TO_DATA FC_PTR_TO_INT
5048 #include "spechash.h"
5049 #define dialog_options_hash_iterate(hash, column, visible) \
5050 TYPED_HASH_ITERATE(const char *, intptr_t, hash, column, visible)
5051 #define dialog_options_hash_iterate_end HASH_ITERATE_END
5053 static struct dialog_options_hash *dialog_options_hash = NULL;
5055 /****************************************************************************
5056 Load the city and player report dialog options.
5057 ****************************************************************************/
5058 static void options_dialogs_load(struct section_file *sf)
5060 const struct entry_list *entries;
5061 const char *prefixes[] = { "player_dlg_", "city_report_", NULL };
5062 const char **prefix;
5063 bool visible;
5065 fc_assert_ret(NULL != dialog_options_hash);
5067 entries = section_entries(secfile_section_by_name(sf, "client"));
5069 if (NULL != entries) {
5070 entry_list_iterate(entries, pentry) {
5071 for (prefix = prefixes; NULL != *prefix; prefix++) {
5072 if (0 == strncmp(*prefix, entry_name(pentry), strlen(*prefix))
5073 && secfile_lookup_bool(sf, &visible, "client.%s",
5074 entry_name(pentry))) {
5075 dialog_options_hash_replace(dialog_options_hash,
5076 entry_name(pentry), visible);
5077 break;
5080 } entry_list_iterate_end;
5084 /****************************************************************************
5085 Save the city and player report dialog options.
5086 ****************************************************************************/
5087 static void options_dialogs_save(struct section_file *sf)
5089 fc_assert_ret(NULL != dialog_options_hash);
5091 options_dialogs_update();
5092 dialog_options_hash_iterate(dialog_options_hash, column, visible) {
5093 secfile_insert_bool(sf, visible, "client.%s", column);
5094 } dialog_options_hash_iterate_end;
5097 /****************************************************************
5098 This set the city and player report dialog options to the
5099 current ones. It's called when the client goes to
5100 C_S_DISCONNECTED state.
5101 *****************************************************************/
5102 void options_dialogs_update(void)
5104 char buf[64];
5105 int i;
5107 fc_assert_ret(NULL != dialog_options_hash);
5109 /* Player report dialog options. */
5110 for (i = 1; i < num_player_dlg_columns; i++) {
5111 fc_snprintf(buf, sizeof(buf), "player_dlg_%s",
5112 player_dlg_columns[i].tagname);
5113 dialog_options_hash_replace(dialog_options_hash, buf,
5114 player_dlg_columns[i].show);
5117 /* City report dialog options. */
5118 for (i = 0; i < num_city_report_spec(); i++) {
5119 fc_snprintf(buf, sizeof(buf), "city_report_%s",
5120 city_report_spec_tagname(i));
5121 dialog_options_hash_replace(dialog_options_hash, buf,
5122 *city_report_spec_show_ptr(i));
5126 /****************************************************************
5127 This set the city and player report dialog options. It's called
5128 when the client goes to C_S_RUNNING state.
5129 *****************************************************************/
5130 void options_dialogs_set(void)
5132 char buf[64];
5133 bool visible;
5134 int i;
5136 fc_assert_ret(NULL != dialog_options_hash);
5138 /* Player report dialog options. */
5139 for (i = 1; i < num_player_dlg_columns; i++) {
5140 fc_snprintf(buf, sizeof(buf), "player_dlg_%s",
5141 player_dlg_columns[i].tagname);
5142 if (dialog_options_hash_lookup(dialog_options_hash, buf, &visible)) {
5143 player_dlg_columns[i].show = visible;
5147 /* City report dialog options. */
5148 for (i = 0; i < num_city_report_spec(); i++) {
5149 fc_snprintf(buf, sizeof(buf), "city_report_%s",
5150 city_report_spec_tagname(i));
5151 if (dialog_options_hash_lookup(dialog_options_hash, buf, &visible)) {
5152 *city_report_spec_show_ptr(i) = visible;
5158 /****************************************************************
5159 Load from the rc file any options that are not ruleset specific.
5160 It is called after ui_init(), yet before ui_main().
5161 Unfortunately, this means that some clients cannot display.
5162 Instead, use log_*().
5163 *****************************************************************/
5164 void options_load(void)
5166 struct section_file *sf;
5167 bool allow_digital_boolean;
5168 int i, num;
5169 const char *name;
5170 const char * const prefix = "client";
5172 name = get_last_option_file_name(&allow_digital_boolean);
5173 if (!name) {
5174 log_normal(_("Didn't find the option file."));
5175 options_fully_initialized = TRUE;
5176 create_default_cma_presets();
5177 return;
5179 if (!(sf = secfile_load(name, TRUE))) {
5180 log_debug("Error loading option file '%s':\n%s", name, secfile_error());
5181 /* try to create the rc file */
5182 sf = secfile_new(TRUE);
5183 secfile_insert_str(sf, VERSION_STRING, "client.version");
5185 create_default_cma_presets();
5186 save_cma_presets(sf);
5188 /* FIXME: need better messages */
5189 if (!secfile_save(sf, name, 0, FZ_PLAIN)) {
5190 log_error(_("Save failed, cannot write to file %s"), name);
5191 } else {
5192 log_normal(_("Saved settings to file %s"), name);
5194 secfile_destroy(sf);
5195 options_fully_initialized = TRUE;
5196 return;
5198 secfile_allow_digital_boolean(sf, allow_digital_boolean);
5200 /* a "secret" option for the lazy. TODO: make this saveable */
5201 sz_strlcpy(password,
5202 secfile_lookup_str_default(sf, "", "%s.password", prefix));
5204 save_options_on_exit =
5205 secfile_lookup_bool_default(sf, save_options_on_exit,
5206 "%s.save_options_on_exit", prefix);
5207 fullscreen_mode =
5208 secfile_lookup_bool_default(sf, fullscreen_mode,
5209 "%s.fullscreen_mode", prefix);
5211 /* Settings migrations */
5212 gui_gtk3_migrated_from_gtk2 =
5213 secfile_lookup_bool_default(sf, gui_gtk3_migrated_from_gtk2,
5214 "%s.migration_gtk3_from_gtk2", prefix);
5216 /* Backwards compatibility for removed options replaced by entirely "new"
5217 * options. The equivalent "new" option will override these, if set. */
5219 /* Removed in 2.3 */
5220 /* Note: this overrides the previously specified default for
5221 * gui_gtk2_message_chat_location */
5222 /* gtk3 client never had the old form of this option. The overridden
5223 * gui_gtk2_ value will be propagated to gui_gtk3_ later by
5224 * migrate_options_from_gtk2() if necessary. */
5225 if (secfile_lookup_bool_default(sf, FALSE,
5226 "%s.gui_gtk2_merge_notebooks", prefix)) {
5227 gui_gtk2_message_chat_location = GUI_GTK_MSGCHAT_MERGED;
5228 } else if (secfile_lookup_bool_default(sf, FALSE,
5229 "%s.gui_gtk2_split_bottom_notebook",
5230 prefix)) {
5231 gui_gtk2_message_chat_location = GUI_GTK_MSGCHAT_SPLIT;
5232 } else {
5233 gui_gtk2_message_chat_location = GUI_GTK_MSGCHAT_SEPARATE;
5236 /* Load all the regular options */
5237 client_options_iterate_all(poption) {
5238 client_option_load(poption, sf);
5239 } client_options_iterate_all_end;
5241 /* More backwards compatibility, for removed options that had been
5242 * folded into then-existing options. Here, the backwards-compatibility
5243 * behaviour overrides the "destination" option. */
5245 /* Removed in 2.4 */
5246 if (!secfile_lookup_bool_default(sf, TRUE,
5247 "%s.do_combat_animation", prefix)) {
5248 smooth_combat_step_msec = 0;
5251 message_options_load(sf, prefix);
5252 options_dialogs_load(sf);
5254 /* Load cma presets. If cma.number_of_presets doesn't exist, don't load
5255 * any, the order here should be reversed to keep the order the same */
5256 if (secfile_lookup_int(sf, &num, "cma.number_of_presets")) {
5257 for (i = num - 1; i >= 0; i--) {
5258 load_cma_preset(sf, i);
5260 } else {
5261 create_default_cma_presets();
5264 settable_options_load(sf);
5265 global_worklists_load(sf);
5267 secfile_destroy(sf);
5268 options_fully_initialized = TRUE;
5271 /**************************************************************************
5272 Save all options.
5273 **************************************************************************/
5274 void options_save(void)
5276 struct section_file *sf;
5277 const char *name = get_current_option_file_name();
5279 if (!name) {
5280 output_window_append(ftc_client,
5281 _("Save failed, cannot find a filename."));
5282 return;
5285 sf = secfile_new(TRUE);
5286 secfile_insert_str(sf, VERSION_STRING, "client.version");
5288 secfile_insert_bool(sf, save_options_on_exit, "client.save_options_on_exit");
5289 secfile_insert_bool(sf, fullscreen_mode, "client.fullscreen_mode");
5291 /* Migrations */
5292 secfile_insert_bool(sf, gui_gtk3_migrated_from_gtk2,
5293 "client.migration_gtk3_from_gtk2");
5295 client_options_iterate_all(poption) {
5296 client_option_save(poption, sf);
5297 } client_options_iterate_all_end;
5299 message_options_save(sf, "client");
5300 options_dialogs_save(sf);
5302 /* server settings */
5303 save_cma_presets(sf);
5304 settable_options_save(sf);
5306 /* insert global worklists */
5307 global_worklists_save(sf);
5309 /* save to disk */
5310 if (!secfile_save(sf, name, 0, FZ_PLAIN)) {
5311 output_window_printf(ftc_client,
5312 _("Save failed, cannot write to file %s"), name);
5313 } else {
5314 output_window_printf(ftc_client, _("Saved settings to file %s"), name);
5316 secfile_destroy(sf);
5320 /**************************************************************************
5321 Initialize lists of names for a client option.
5322 **************************************************************************/
5323 static void options_init_names(const struct copt_val_name *(*acc)(int),
5324 struct strvec **support, struct strvec **pretty)
5326 int val;
5327 const struct copt_val_name *name;
5328 fc_assert_ret(NULL != acc);
5329 *support = strvec_new();
5330 *pretty = strvec_new();
5331 for (val=0; (name = acc(val)); val++) {
5332 strvec_append(*support, name->support);
5333 strvec_append(*pretty, name->pretty);
5337 /**************************************************************************
5338 Initialize the option module.
5339 **************************************************************************/
5340 void options_init(void)
5342 message_options_init();
5343 gui_options_extra_init();
5344 global_worklists_init();
5346 settable_options_hash = settable_options_hash_new();
5347 dialog_options_hash = dialog_options_hash_new();
5349 client_options_iterate_all(poption) {
5350 struct client_option *pcoption = CLIENT_OPTION(poption);
5352 switch (option_type(poption)) {
5353 case OT_INTEGER:
5354 if (option_int_def(poption) < option_int_min(poption)
5355 || option_int_def(poption) > option_int_max(poption)) {
5356 int new_default = MAX(MIN(option_int_def(poption),
5357 option_int_max(poption)),
5358 option_int_min(poption));
5360 log_error("option %s has default value of %d, which is "
5361 "out of its range [%d; %d], changing to %d.",
5362 option_name(poption), option_int_def(poption),
5363 option_int_min(poption), option_int_max(poption),
5364 new_default);
5365 *((int *) &(pcoption->integer.def)) = new_default;
5367 break;
5369 case OT_STRING:
5370 if (default_user_name == option_str_get(poption)) {
5371 /* Hack to get a default value. */
5372 *((const char **) &(pcoption->string.def)) =
5373 fc_strdup(default_user_name);
5376 if (NULL == option_str_def(poption)) {
5377 const struct strvec *values = option_str_values(poption);
5379 if (NULL == values || strvec_size(values) == 0) {
5380 log_error("Invalid NULL default string for option %s.",
5381 option_name(poption));
5382 } else {
5383 *((const char **) &(pcoption->string.def)) =
5384 strvec_get(values, 0);
5387 break;
5389 case OT_ENUM:
5390 fc_assert(NULL == pcoption->enumerator.support_names);
5391 fc_assert(NULL == pcoption->enumerator.pretty_names);
5392 options_init_names(pcoption->enumerator.name_accessor,
5393 &pcoption->enumerator.support_names,
5394 &pcoption->enumerator.pretty_names);
5395 fc_assert(NULL != pcoption->enumerator.support_names);
5396 fc_assert(NULL != pcoption->enumerator.pretty_names);
5397 break;
5399 case OT_BITWISE:
5400 fc_assert(NULL == pcoption->bitwise.support_names);
5401 fc_assert(NULL == pcoption->bitwise.pretty_names);
5402 options_init_names(pcoption->bitwise.name_accessor,
5403 &pcoption->bitwise.support_names,
5404 &pcoption->bitwise.pretty_names);
5405 fc_assert(NULL != pcoption->bitwise.support_names);
5406 fc_assert(NULL != pcoption->bitwise.pretty_names);
5407 break;
5409 case OT_COLOR:
5411 /* Duplicate the string pointers. */
5412 struct ft_color *pcolor = pcoption->color.pvalue;
5414 if (NULL != pcolor->foreground) {
5415 pcolor->foreground = fc_strdup(pcolor->foreground);
5417 if (NULL != pcolor->background) {
5418 pcolor->background = fc_strdup(pcolor->background);
5422 case OT_BOOLEAN:
5423 case OT_FONT:
5424 case OT_VIDEO_MODE:
5425 break;
5428 /* Set to default. */
5429 option_reset(poption);
5430 } client_options_iterate_all_end;
5433 /**************************************************************************
5434 Free the option module.
5435 **************************************************************************/
5436 void options_free(void)
5438 client_options_iterate_all(poption) {
5439 struct client_option *pcoption = CLIENT_OPTION(poption);
5441 switch (option_type(poption)) {
5442 case OT_ENUM:
5443 fc_assert_action(NULL != pcoption->enumerator.support_names, break);
5444 strvec_destroy(pcoption->enumerator.support_names);
5445 pcoption->enumerator.support_names = NULL;
5446 fc_assert_action(NULL != pcoption->enumerator.pretty_names, break);
5447 strvec_destroy(pcoption->enumerator.pretty_names);
5448 pcoption->enumerator.pretty_names = NULL;
5449 break;
5451 case OT_BITWISE:
5452 fc_assert_action(NULL != pcoption->bitwise.support_names, break);
5453 strvec_destroy(pcoption->bitwise.support_names);
5454 pcoption->bitwise.support_names = NULL;
5455 fc_assert_action(NULL != pcoption->bitwise.pretty_names, break);
5456 strvec_destroy(pcoption->bitwise.pretty_names);
5457 pcoption->bitwise.pretty_names = NULL;
5458 break;
5460 case OT_BOOLEAN:
5461 case OT_INTEGER:
5462 case OT_STRING:
5463 case OT_FONT:
5464 case OT_COLOR:
5465 case OT_VIDEO_MODE:
5466 break;
5468 } client_options_iterate_all_end;
5470 if (NULL != settable_options_hash) {
5471 settable_options_hash_destroy(settable_options_hash);
5472 settable_options_hash = NULL;
5475 if (NULL != dialog_options_hash) {
5476 dialog_options_hash_destroy(dialog_options_hash);
5477 dialog_options_hash = NULL;
5480 message_options_free();
5481 global_worklists_free();
5484 /****************************************************************************
5485 Callback when the reqtree show icons option is changed. The tree is
5486 recalculated.
5487 ****************************************************************************/
5488 static void reqtree_show_icons_callback(struct option *poption)
5490 science_report_dialog_redraw();
5493 /****************************************************************************
5494 Callback for when any view option is changed.
5495 ****************************************************************************/
5496 static void view_option_changed_callback(struct option *poption)
5498 menus_init();
5499 update_map_canvas_visible();
5502 /****************************************************************************
5503 Callback for when any voeinfo bar option is changed.
5504 ****************************************************************************/
5505 static void voteinfo_bar_callback(struct option *poption)
5507 voteinfo_gui_update();
5510 /****************************************************************************
5511 Callback for font options.
5512 ****************************************************************************/
5513 static void font_changed_callback(struct option *poption)
5515 fc_assert_ret(OT_FONT == option_type(OPTION(poption)));
5516 gui_update_font(option_font_target(poption), option_font_get(poption));
5519 /****************************************************************************
5520 Callback for mapimg options.
5521 ****************************************************************************/
5522 static void mapimg_changed_callback(struct option *poption)
5524 if (!mapimg_client_define()) {
5525 log_normal("Error setting the value for %s (%s). Restoring the default "
5526 "value.", option_name(poption), mapimg_error());
5528 /* Reset the value to the default value. */
5529 fc_assert_ret(TRUE == option_reset(poption));
5530 fc_assert_ret(TRUE == mapimg_client_define());