Crossfire Client, Trunk
main.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2013 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include "client.h"
20 
21 #include <errno.h>
22 #include <gtk/gtk.h>
23 #include <stdbool.h>
24 
25 #ifndef WIN32
26 #include <signal.h>
27 #endif
28 
29 #ifdef HAVE_CAPSICUM
30 #include <sys/capsicum.h>
31 #endif
32 
33 #include "client-vala.h"
34 #include "image.h"
35 #include "main.h"
36 #include "mapdata.h"
37 #include "metaserver.h"
38 #include "script.h"
39 #include "sound.h"
40 #include "gtk2proto.h"
41 
42 /* Sets up the basic colors. */
43 static const char *const colorname[NUM_COLORS] = {
44  "Black", /* 0 */
45  "White", /* 1 */
46  "Navy", /* 2 */
47  "Red", /* 3 */
48  "Orange", /* 4 */
49  "DodgerBlue", /* 5 */
50  "DarkOrange2", /* 6 */
51  "SeaGreen", /* 7 */
52  "DarkSeaGreen", /* 8 *//* Used for window background color */
53  "Grey50", /* 9 */
54  "Sienna", /* 10 */
55  "Gold", /* 11 */
56  "Khaki" /* 12 */
57 };
58 
59 static gboolean updatekeycodes = FALSE;
60 
61 /* TODO: Move these declarations to actual header files. */
62 extern bool time_map_redraw;
63 extern bool profile_latency;
64 extern int MINLOG;
66 
67 static bool playing = FALSE; // Set to true when main window is up, gates self-generated ticks
68 
69 static char *connect_server = NULL;
70 
71 static gboolean script_launch(const gchar *option_name, const gchar *value, gpointer data, GError **error);
72 
74 static GOptionEntry options[] = {
75  { "server", 's', 0, G_OPTION_ARG_STRING, &connect_server,
76  "Connect to the given server", "SERVER[:PORT]" },
77  { "cache", 0, 0, G_OPTION_ARG_NONE, &want_config[CONFIG_CACHE],
78  "Cache images", NULL },
79  { "prefetch", 0, 0, G_OPTION_ARG_NONE, &want_config[CONFIG_DOWNLOAD],
80  "Download images before playing", NULL },
81  { "faceset", 0, 0, G_OPTION_ARG_STRING, &face_info.want_faceset,
82  "Use the given faceset (if available)", "FACESET" },
83 
84  { "updatekeycodes", 0, 0, G_OPTION_ARG_NONE, &updatekeycodes,
85  "Update the saved bindings for this keyboard", NULL },
86 
87  { "loginmethod", 0, 0, G_OPTION_ARG_INT, &wantloginmethod,
88  "Login method to request from server", NULL },
89  { "profile-latency", 0, 0, G_OPTION_ARG_NONE, &profile_latency,
90  "Log command acknowledgement latency to stdout", NULL },
91  { "profile-redraw", 0, 0, G_OPTION_ARG_NONE, &time_map_redraw,
92  "Print map redraw times to stdout", NULL },
93  { "verbose", 'v', 0, G_OPTION_ARG_INT, &MINLOG,
94  "Set verbosity (0 is the most verbose)", "LEVEL" },
95  { "debug-protocol", 0, 0, G_OPTION_ARG_NONE, &debug_protocol,
96  "Print commands to and from the server", NULL },
97  { "script", 0, 0, G_OPTION_ARG_CALLBACK, &script_launch,
98  "Launch client script at start (can be used multiple times)", "SCRIPT_NAME" },
99  { NULL }
100 };
101 
103 
105 
106 GtkBuilder *dialog_xml, *window_xml;
108 GtkNotebook *main_notebook;
109 
110 GtkCheckButton *sandbox_enable;
111 
112 extern time_t last_command_sent;
113 extern bool is_afk;
114 
115 #ifdef WIN32 /* Win32 scripting support */
116 static int do_scriptout() {
117  script_process(NULL);
118  return (TRUE);
119 }
120 #endif /* WIN32 */
121 
122 static gboolean script_launch(const gchar *option_name, const gchar *value, gpointer data, GError **error)
123 {
124  (void)option_name; // always "--script"
125  (void)data; // Not used
126  (void)error; // Not used
127  script_init(value);
128  return TRUE;
129 }
130 
135 static gboolean redraw(gpointer data) {
136  // Add a check for client_is_connected so that forced socket termination
137  // does not erroneously attempt to redraw the map after it has been destroyed.
138  if (client_is_connected()) {
139  if (have_new_image) {
140  if (cpl.container) {
142  }
143  cpl.ob->inv_updated = 1;
144  have_new_image = 0;
145  }
146  draw_map();
147  draw_lists();
148  }
149  return FALSE;
150 }
151 
152 static void on_auto_afk_response(GtkDialog *self, gint response_id, gpointer user_data) {
153  // It is possible for is_afk to be false because dialog is non-modal.
154  switch (response_id) {
155  case 1:
156  gtk_widget_destroy(GTK_WIDGET(self));
157  break;
158  case 2:
159  if (is_afk) {
160  send_command("afk", 0, true);
161  }
163  config_check();
164  save_defaults();
165  gtk_widget_destroy(GTK_WIDGET(self));
166  break;
167  default:
168  // includes closing the pop-up
169  if (is_afk) {
170  send_command("afk", 0, true);
171  }
172  gtk_widget_destroy(GTK_WIDGET(self));
173  break;
174  }
175 }
176 
177 static void auto_afk() {
178  send_command("afk", 0, true);
179  GtkWidget *dialog = gtk_dialog_new_with_buttons("Auto-AFK", GTK_WINDOW(window_root), GTK_DIALOG_DESTROY_WITH_PARENT,
180  "Return to game", 0, "Return to game, but stay AFK", 1, "Return to game, disable auto-AFK", 2, NULL);
181  GtkWidget *label, *content_area;
182  content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
183  label = gtk_label_new("You have been automatically marked as being away.");
184  gtk_container_add(GTK_CONTAINER(content_area), label);
185  g_signal_connect_swapped(dialog, "response", G_CALLBACK(on_auto_afk_response), dialog);
186  gtk_widget_show_all(dialog);
187 }
188 
192 void client_tick(guint32 tick) {
193  if (cpl.showmagic) {
194  if (gtk_notebook_get_current_page(GTK_NOTEBOOK(map_notebook)) !=
195  MAGIC_MAP_PAGE) {
196  // Stop flashing when the user switches back to the map window.
197  cpl.showmagic = 0;
198  } else {
200  cpl.showmagic ^= 2;
201  }
202  }
203  if (cpl.spells_updated) {
205  }
206 
208  inventory_tick();
210 }
214 void on_window_destroy_event(GtkWidget *object, gpointer user_data) {
215  script_killall();
216  LOG(LOG_DEBUG, "main.c::client_exit", "Exiting with return value 0.");
217  exit(0);
218 }
219 
223 static gboolean do_network(GObject *stream, gpointer data) {
224  struct timeval timeout = {0, 0};
225  fd_set tmp_read;
226  int pollret;
227 
228  if (!client_is_connected()) {
229  // It would be better to call gtk_main_quit() after client_disconnect(). But that function
230  // is in common, so we just check here.
231  gtk_main_quit();
232  return FALSE;
233  }
234 
235  client_run();
236 
237  FD_ZERO(&tmp_read);
238  int maxfd;
239  script_fdset(&maxfd, &tmp_read);
240  pollret = select(maxfd, &tmp_read, NULL, NULL, &timeout);
241  if (pollret < 0) {
242 #ifndef WIN32
243  // FIXME: For whatever reason, we get errors claiming "no error" here in Windows
244  LOG(LOG_ERROR, "do_network", "script select() failed: %s", strerror(errno));
245 #endif
246  } else if (pollret > 0) {
247  script_process(&tmp_read);
248  }
249 
250  return TRUE;
251 }
252 
253 static gboolean self_tick(gpointer data) {
254  if (playing) {
255  g_idle_add(redraw, NULL);
256 
257  if (!is_afk && use_config[CONFIG_AUTO_AFK] != 0 && time(NULL) > (last_command_sent + use_config[CONFIG_AUTO_AFK])) {
258  auto_afk();
259  }
261  client_tick(0);
262  }
263  return TRUE;
264  }
265  return FALSE;
266 }
267 
271 static void event_loop() {
272 #ifdef WIN32
273  g_timeout_add(250, G_SOURCE_FUNC(do_scriptout), NULL);
274 #endif
275 
276  // Set up network callback
277  GSource *net_source = client_get_source();
278  g_assert(net_source != NULL); // crashes if input stream is not a pollable input stream
279  g_source_set_callback(net_source, (GSourceFunc)do_network, NULL, NULL);
280  g_source_attach(net_source, NULL);
281 
282  gtk_main();
283 }
284 
296 static void parse_args(int argc, char *argv[]) {
297  GOptionContext *context = g_option_context_new("- Crossfire GTKv2 Client");
298  GError *error = NULL;
299 
300  g_option_context_add_main_entries(context, options, NULL);
301  g_option_context_add_group(context, gtk_get_option_group(TRUE));
302 
303  if (!g_option_context_parse(context, &argc, &argv, &error)) {
304  g_print("%s\n", error->message);
305  g_error_free(error);
306  exit(EXIT_FAILURE);
307  }
308 
309  g_option_context_free(context);
310 
311  /*
312  * Move this after the parsing of command line options, since that can
313  * change the default log level.
314  */
315  LOG(LOG_DEBUG, "Client Version", VERSION_INFO);
316  if (MINLOG <= 0) {
317  g_setenv("CF_SOUND_DEBUG", "yes", false);
318  }
319 }
320 
326 void error_dialog(char *error, char *message) {
327  LOG(LOG_ERROR, error, message);
328  GtkWidget *dialog = gtk_message_dialog_new(
329  NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
330  GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", error);
331  gtk_window_set_title(GTK_WINDOW(dialog), "Crossfire Client");
332  gtk_message_dialog_format_secondary_markup(
333  GTK_MESSAGE_DIALOG(dialog), "%s", message);
334  gtk_dialog_run(GTK_DIALOG(dialog));
335  gtk_widget_destroy(dialog);
336 }
337 
350 void my_log_handler(const gchar *log_domain, GLogLevelFlags log_level,
351  const gchar *message, gpointer user_data) {
352  g_usleep(1 * 1e6);
353 }
354 
355 static void init_sockets() {
356 #ifndef WIN32
357  signal(SIGPIPE, SIG_IGN);
358 #endif
359 }
360 
364 static char *init_ui_layout(const char *name) {
365  guint retval = gtk_builder_add_from_file(window_xml, name, NULL);
366  if (retval > 0 && strlen(name) > 0) {
367  if (window_xml_file != name) { // FIXME: caught by Valgrind
368  strncpy(window_xml_file, name, sizeof(window_xml_file));
369  }
370  return window_xml_file;
371  } else {
372  return NULL;
373  }
374 }
375 
376 static void init_ui() {
377  GError *error = NULL;
378  GdkGeometry geometry;
379  int i;
380 
381  /* Load dialog windows using GtkBuilder. */
382  dialog_xml = gtk_builder_new();
383  if (!gtk_builder_add_from_file(dialog_xml, DIALOG_FILENAME, &error)) {
384  error_dialog("Couldn't load UI dialogs.", error->message);
385  g_error_free(error);
386  exit(EXIT_FAILURE);
387  }
388  LOG(LOG_DEBUG, "init_ui", "loaded dialog_xml '%s'", DIALOG_FILENAME);
389 
390  /* Load main window using GtkBuilder. */
391  window_xml = gtk_builder_new();
392  if (init_ui_layout(window_xml_file) == NULL) {
393  LOG(LOG_DEBUG, "init_ui_layout", "Could not initialize '%s', using default layout", window_xml_file);
394  if (init_ui_layout(DEFAULT_UI) == NULL) {
395  g_error("Could not load default layout!");
396  }
397  }
398  LOG(LOG_DEBUG, "init_ui", "loaded window_xml '%s'", window_xml_file);
399 
400  connect_window = GTK_WIDGET(gtk_builder_get_object(dialog_xml, "connect_window"));
401  gtk_window_set_transient_for(GTK_WINDOW(connect_window),
402  GTK_WINDOW(window_root));
403  g_signal_connect(connect_window, "destroy",
404  G_CALLBACK(on_window_destroy_event), NULL);
405  main_notebook =
406  GTK_NOTEBOOK(gtk_builder_get_object(dialog_xml, "main_notebook"));
407 
408  /* Begin connecting signals for the root window. */
409  window_root = GTK_WIDGET(gtk_builder_get_object(window_xml, "window_root"));
410  if (window_root == NULL) {
411  error_dialog("Could not load main window",
412  "Check that your layout files are not corrupt.");
413  exit(EXIT_FAILURE);
414  }
415 
416  /* Request the window to receive focus in and out events */
417  gtk_widget_add_events((gpointer) window_root, GDK_FOCUS_CHANGE_MASK);
418  g_signal_connect((gpointer) window_root, "focus-out-event",
419  G_CALLBACK(focusoutfunc), NULL);
420 
421  g_signal_connect_swapped((gpointer) window_root, "key_press_event",
422  G_CALLBACK(keyfunc), GTK_WIDGET(window_root));
423  g_signal_connect_swapped((gpointer) window_root, "key_release_event",
424  G_CALLBACK(keyrelfunc), GTK_WIDGET(window_root));
425  g_signal_connect((gpointer) window_root, "destroy",
426  G_CALLBACK(on_window_destroy_event), NULL);
427 
428  /* Purely arbitrary min window size */
429  geometry.min_width=640;
430  geometry.min_height=480;
431 
432  gtk_window_set_geometry_hints(GTK_WINDOW(window_root), window_root,
433  &geometry, GDK_HINT_MIN_SIZE);
434 
435  magic_map = GTK_WIDGET(gtk_builder_get_object(window_xml,
436  "drawingarea_magic_map"));
437 
438  g_signal_connect((gpointer) magic_map, "expose_event",
439  G_CALLBACK(on_drawingarea_magic_map_expose_event), NULL);
440 
441  /* Set up colors before doing the other initialization functions */
442  for (i = 0; i < NUM_COLORS; i++) {
443  if (!gdk_color_parse(colorname[i], &root_color[i])) {
444  fprintf(stderr, "gdk_color_parse failed (%s)\n", colorname[i]);
445  }
446  if (!gdk_colormap_alloc_color(gtk_widget_get_colormap(window_root),
447  &root_color[i], FALSE, FALSE)) {
448  fprintf(stderr, "gdk_color_alloc failed\n");
449  }
450  }
451 
452  LOG(LOG_DEBUG, "init_ui", "sub init");
462  sandbox_enable = GTK_CHECK_BUTTON(gtk_builder_get_object(dialog_xml, "sandbox_enable"));
463 #ifdef HAVE_CAPSICUM
464  gtk_widget_set_sensitive(GTK_WIDGET(sandbox_enable), true);
465 #else
466  gtk_widget_set_sensitive(GTK_WIDGET(sandbox_enable), false);
467 #endif
468 
469  LOG(LOG_DEBUG, "init_ui", "window positions");
471 
472  LOG(LOG_DEBUG, "init_ui", "init themes");
473  init_theme();
474  LOG(LOG_DEBUG, "init_ui", "load themes");
475  load_theme(TRUE);
476  LOG(LOG_DEBUG, "init_ui", "menu items");
477  init_menu_items();
478 }
479 
485  if (!playing) {
486  // Prevent double-time if show_main_client() is called multiple times (it's possible)
487  g_timeout_add(1000/8, G_SOURCE_FUNC(self_tick), NULL);
488  }
489  playing = TRUE;
491  gtk_widget_show(window_root);
494 
495  // Reset auto-AFK data.
496  is_afk = false;
497  last_command_sent = time(NULL);
498 }
499 
505  playing = FALSE;
506  gtk_widget_hide(window_root);
508  /*
509  * We know the following is the private map structure in item.c. But
510  * we don't have direct access to it, so we still use locate.
511  */
513 
514  cf_play_music("NONE");
515  gtk_widget_show(connect_window);
516 }
517 
521 int main(int argc, char *argv[]) {
522  global_time = g_timer_new();
523 #ifdef ENABLE_NLS
524  bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
525  bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
526  textdomain(GETTEXT_PACKAGE);
527 #endif
528 
529  // Initialize GTK and client library.
530  gtk_init(&argc, &argv);
531  parse_args(argc, argv);
532  client_init();
533 
534  // Set defaults, load configuration, and parse arguments.
535  config_load();
536  config_check();
537  char *layout = g_path_get_basename(window_xml_file);
538  snprintf(VERSION_INFO, MAX_BUF,
539  "GTKv2 Client " FULL_VERSION " (%s)", layout);
540  g_free(layout);
541 
542  // Initialize UI, sockets, and sound server.
543  LOG(LOG_DEBUG, "main", "init UI");
544  init_ui();
545  LOG(LOG_DEBUG, "main", "init sockets");
546  init_sockets();
547 
548  LOG(LOG_DEBUG, "main", "init sound");
549  if (!want_config[CONFIG_SOUND] || !init_sounds()) {
550  use_config[CONFIG_SOUND] = FALSE;
551  } else {
552  use_config[CONFIG_SOUND] = TRUE;
553  }
554 
555  /* Load cached pixmaps. */
556  LOG(LOG_DEBUG, "main", "init image cache");
558 
559  LOG(LOG_DEBUG, "main", "init done");
560  bool sandbox_enabled = false;
561 
562  while (true) {
563  gtk_widget_show(connect_window);
564  if (connect_server == NULL) {
566  gtk_main();
567  } else {
569  if (csocket.fd == NULL) {
570  LOG(LOG_ERROR, "main", "Unable to connect to %s!", connect_server);
571  break;
572  }
574  }
575 
577  sandbox_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sandbox_enable));
578  if (sandbox_enabled) {
579  // preload some themes from the main window
580  gtk_widget_show(window_root);
582  for (int i = 0; i < 100; i++) {
583  gtk_main_iteration();
584  }
585  gtk_widget_hide(window_root);
586 
587 #ifdef HAVE_CAPSICUM
588  if (cap_enter() != 0) {
589  error_dialog("Failed to enter sandbox", "Sandboxing was enabled, but the running kernel does not support sandboxing.");
590  break;
591  }
592  LOG(LOG_INFO, "main", "Entering sandbox");
593 #endif
594  }
595 
597  if (serverloginmethod) {
599  } else {
601  }
602 
603  /* The event_loop will block until connection to the server is lost. */
604  event_loop();
605  } else {
606  LOG(LOG_ERROR, "main", "Failed to negotiate connection with server");
607  }
608 
610 
611  /*
612  * Need to reset the images so they match up properly and prevent
613  * memory leaks.
614  */
616  client_reset();
617 
618  if (connect_server != NULL || sandbox_enabled) {
619  break;
620  }
621  }
622 }
623 
635 void get_window_coord(GtkWidget *win, int *x, int *y, int *wx, int *wy,
636  int *w, int *h) {
637  /* Position of a window relative to its parent window. */
638  gdk_window_get_geometry(gtk_widget_get_window(win), x, y, w, h, NULL);
639  /* Position of the window in root window coordinates. */
640  gdk_window_get_origin(gtk_widget_get_window(win), wx, wy);
641  *wx -= *x;
642  *wy -= *y;
643 }
last_command_sent
time_t last_command_sent
Time when last command was sent.
Definition: player.c:49
LOG_INFO
@ LOG_INFO
Minor, non-harmful issues.
Definition: client.h:436
updatekeycodes
static gboolean updatekeycodes
Definition: main.c:59
redraw
static gboolean redraw(gpointer data)
Redraw the map.
Definition: main.c:135
init_menu_items
void init_menu_items()
Initialize menu bar items and connect their signals to their handlers.
Definition: menubar.c:89
init_theme
void init_theme()
Definition: config.c:95
Playing
@ Playing
Definition: client.h:144
script_killall
void script_killall(void)
Definition: script.c:541
keyfunc
void keyfunc(GtkWidget *widget, GdkEventKey *event, GtkWidget *window)
GTK Callback function used to handle client key press events.
Definition: keys.c:1573
metaserver.h
DIALOG_FILENAME
#define DIALOG_FILENAME
Definition: main.h:37
CONFIG_SERVER_TICKS
#define CONFIG_SERVER_TICKS
Definition: client.h:217
load_window_positions
void load_window_positions(GtkWidget *window_root)
Resize the client window and its panels using saved window positions.
Definition: config.c:864
Player_Struct::input_state
Input_State input_state
What the input state is.
Definition: client.h:341
ClientSocket::fd
GSocketConnection * fd
Definition: client.h:124
parse_args
static void parse_args(int argc, char *argv[])
parse_args: Parses command line options, and does variable initialization.
Definition: main.c:296
client_reset
void client_reset()
Clear client variables between connections to different servers.
Definition: init.c:247
CONFIG_DOWNLOAD
#define CONFIG_DOWNLOAD
Definition: client.h:182
show_main_client
void show_main_client()
Show main client window.
Definition: main.c:484
DEFAULT_UI
#define DEFAULT_UI
Definition: main.h:36
map_pre_sandbox_init
void map_pre_sandbox_init(void)
Called before entering the sandbox to cache things like fonts.
Definition: map.c:87
FULL_VERSION
#define FULL_VERSION
Definition: version.h:1
main_notebook
GtkNotebook * main_notebook
Definition: main.c:108
remove_item_inventory
void remove_item_inventory(item *op)
Definition: item.c:344
client_tick
void client_tick(guint32 tick)
Called whenever the server sends a tick command.
Definition: main.c:192
map_init
void map_init(GtkWidget *window_root)
This initializes the stuff we need for the map.
Definition: map.c:108
hide_all_login_windows
void hide_all_login_windows(void)
Hides all the login related windows.
Definition: account.c:96
face_info
Face_Information face_info
Definition: image.c:169
playing
static bool playing
Definition: main.c:67
msgctrl_init
void msgctrl_init(GtkWidget *window_root)
Initialize the message control panel by populating it with descriptions of each message type along wi...
Definition: info.c:1348
save_defaults
void save_defaults(void)
This function saves user settings chosen using the configuration popup dialog.
Definition: config.c:517
options
static GOptionEntry options[]
Command line options, descriptions, and parameters.
Definition: main.c:74
script_process
void script_process(fd_set *set)
Definition: script.c:573
map_notebook
GtkWidget * map_notebook
Definition: map.c:37
client_is_connected
bool client_is_connected()
Definition: client.c:320
have_new_image
int have_new_image
Definition: image.c:37
client_connect
void client_connect(const char hostname[static 1])
Definition: client.c:289
sandbox_enable
GtkCheckButton * sandbox_enable
Definition: main.c:110
MAGIC_MAP_PAGE
#define MAGIC_MAP_PAGE
Notebook page of the magic map.
Definition: main.h:42
VERSION_INFO
char VERSION_INFO[MAX_BUF]
Definition: client.c:48
wantloginmethod
int wantloginmethod
Definition: client.c:60
event_loop
static void event_loop()
Set up, enter, and exit event loop.
Definition: main.c:271
mapdata.h
on_auto_afk_response
static void on_auto_afk_response(GtkDialog *self, gint response_id, gpointer user_data)
Definition: main.c:152
client_get_source
GSource * client_get_source()
Return a source triggered when input from the server is available.
Definition: client.c:324
CONFIG_CACHE
#define CONFIG_CACHE
Definition: client.h:186
Player_Struct::container
item * container
open container
Definition: client.h:339
pickup_init
void pickup_init(GtkWidget *window_root)
Maps the menuitem lists into pickup values.
Definition: pickup.c:401
MAX_BUF
#define MAX_BUF
Definition: client.h:40
info_init
void info_init(GtkWidget *window_root)
Initialize the information panels in the client.
Definition: info.c:632
reset_image_data
void reset_image_data(void)
Connecting to different servers, try to clear out any old images.
Definition: image.c:276
init_ui_layout
static char * init_ui_layout(const char *name)
Load the UI from the given path.
Definition: main.c:364
focusoutfunc
void focusoutfunc(GtkWidget *widget, GdkEventKey *event, GtkWidget *window)
When the main window looses its focus, act as if all keys have been released.
Definition: keys.c:1532
MINLOG
int MINLOG
Log level, or the threshold below which messages are suppressed.
Definition: misc.c:34
client_negotiate
bool client_negotiate(int sound)
This function negotiates the characteriistics of a connection to the server.
Definition: client.c:329
Player_Struct::ob
item * ob
Player object.
Definition: client.h:336
hide_main_client
void hide_main_client()
Called if event_loop() exits, or whenever the character selection window comes up (before logging in,...
Definition: main.c:504
clear_stat_mapping
void clear_stat_mapping(void)
Definition: stats.c:771
init_image_cache_data
void init_image_cache_data(void)
Initializes the data for image caching Create question mark to display in each supported rendering mo...
Definition: image.c:376
gtk2proto.h
client_run
void client_run()
Read available packets from the server and handle commands until there are no more,...
Definition: client.c:201
draw_lists
void draw_lists(void)
Redraws inventory and look windows when necessary.
Definition: inventory.c:1151
Face_Information_struct::want_faceset
char * want_faceset
Definition: client.h:409
root_color
GdkColor root_color[NUM_COLORS]
Definition: main.c:104
LOG
void LOG(LogLevel level, const char *origin, const char *format,...)
Log messages of a certain importance to stderr.
Definition: misc.c:111
inventory_init
void inventory_init(GtkWidget *window_root)
Set up the inventory viewer.
Definition: inventory.c:517
load_theme
void load_theme(int reload)
Definition: config.c:157
window_xml_file
char window_xml_file[MAX_BUF]
Path to the current UI file.
Definition: main.c:102
want_config
gint16 want_config[CONFIG_NUMS]
Definition: init.c:44
csocket
ClientSocket csocket
Definition: client.c:69
metaserver_show_prompt
void metaserver_show_prompt(void)
Constructs the metaserver dialog and handles metaserver selection.
Definition: metaserver.c:215
image.h
metaserver_ui_init
void metaserver_ui_init()
Initialize the metaserver user interface.
Definition: metaserver.c:75
init_sockets
static void init_sockets()
Definition: main.c:355
my_log_handler
void my_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
This goes with the g_log_set_handler below in main().
Definition: main.c:350
magic_map_flash_pos
void magic_map_flash_pos(void)
Flash the player's position on the magic map.
Definition: magicmap.c:77
init_ui
static void init_ui()
Definition: main.c:376
CONFIG_AUTO_AFK
#define CONFIG_AUTO_AFK
Definition: client.h:214
keys_init
void keys_init(GtkWidget *window_root)
One-time initialization of windows and signals for the keybindings dialog.
Definition: keys.c:650
error_dialog
void error_dialog(char *error, char *message)
Display an error message dialog.
Definition: main.c:326
main
int main(int argc, char *argv[])
Main client entry point.
Definition: main.c:521
keyrelfunc
void keyrelfunc(GtkWidget *widget, GdkEventKey *event, GtkWidget *window)
GTK callback function used to handle client key release events.
Definition: keys.c:1558
dialog_xml
GtkBuilder * dialog_xml
Definition: main.c:106
Player_Struct::showmagic
guint8 showmagic
If 0, show the normal map, otherwise show the magic map.
Definition: client.h:364
is_afk
bool is_afk
Best guess whether or not we are currently AFK or not.
Definition: player.c:46
send_command
int send_command(const char *command, int repeat, int must_send)
Definition: player.c:231
init_create_character_window
void init_create_character_window()
Initializes the create character window.
Definition: create_char.c:791
on_drawingarea_magic_map_expose_event
gboolean on_drawingarea_magic_map_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
LOG_ERROR
@ LOG_ERROR
Warning that something definitely didn't work.
Definition: client.h:438
CONFIG_SOUND
#define CONFIG_SOUND
Definition: client.h:194
update_spell_information
void update_spell_information(void)
When spell information updates, the treeview is cleared and re-populated.
Definition: spells.c:190
locate_item
item * locate_item(gint32 tag)
Definition: item.c:278
main.h
cpl
Client_Player cpl
Player object.
Definition: client.c:68
time_map_redraw
bool time_map_redraw
Definition: config.c:53
connect_server
static char * connect_server
Definition: main.c:69
inventory_tick
void inventory_tick(void)
This is called periodically from main.c - basically a timeout, used to animate the inventory.
Definition: inventory.c:1290
global_time
GTimer * global_time
Definition: misc.c:31
do_network
static gboolean do_network(GObject *stream, gpointer data)
Callback from the event loop triggered when server input is available.
Definition: main.c:223
config_init
void config_init(GtkWidget *window_root)
Definition: config.c:548
item_struct::inv_updated
guint16 inv_updated
Definition: item.h:77
magic_map
GtkWidget * magic_map
Definition: main.c:107
debug_protocol
bool debug_protocol
Definition: main.c:65
script.h
self_tick
static gboolean self_tick(gpointer data)
Definition: main.c:253
account_show_login
void account_show_login()
Definition: account.c:1302
use_config
gint16 use_config[CONFIG_NUMS]
Definition: client.h:244
colorname
static const char *const colorname[NUM_COLORS]
Definition: main.c:43
info_buffer_tick
void info_buffer_tick(void)
Output count/sync buffer maintainer adds buffer time and output messages.
Definition: info.c:1069
client_init
void client_init()
Called ONCE during client startup to initialize configuration and other variables to reasonable defau...
Definition: init.c:192
script_fdset
void script_fdset(int *maxfd, fd_set *set)
Definition: script.c:558
window_root
GtkWidget * window_root
In main.c.
Definition: main.c:107
init_sounds
int init_sounds(void)
Definition: sound.c:26
get_window_coord
void get_window_coord(GtkWidget *win, int *x, int *y, int *wx, int *wy, int *w, int *h)
Gets the coordinates of a specified window.
Definition: main.c:635
maxfd
int maxfd
Definition: client.c:57
auto_afk
static void auto_afk()
Definition: main.c:177
script_init
void script_init(const char *cparams)
Definition: script.c:205
on_window_destroy_event
void on_window_destroy_event(GtkWidget *object, gpointer user_data)
Handles client shutdown.
Definition: main.c:214
NUM_COLORS
#define NUM_COLORS
Definition: main.h:22
mapdata_animation
void mapdata_animation(void)
Definition: mapdata.c:1400
script_launch
static gboolean script_launch(const gchar *option_name, const gchar *value, gpointer data, GError **error)
Definition: main.c:122
serverloginmethod
int serverloginmethod
Definition: client.c:61
profile_latency
bool profile_latency
Definition: player.c:36
sound.h
draw_map
void draw_map(void)
Draw the map window using the appropriate backend.
Definition: map.c:545
Player_Struct::spells_updated
guint32 spells_updated
Whether or not spells updated.
Definition: client.h:353
connect_window
GtkWidget * connect_window
Definition: main.c:107
LOG_DEBUG
@ LOG_DEBUG
Useful debugging information.
Definition: client.h:435
config_load
void config_load()
Load settings from the user's configuration file into want_config.
Definition: config.c:446
client.h
stats_init
void stats_init(GtkWidget *window_root)
Associate the XML-defined widgets with pointers by name reference.
Definition: stats.c:147
cf_play_music
void cf_play_music(const char *music_name)
Play a music file.
Definition: cfsndserv.c:213
config_check
void config_check(void)
Check that want_config is valid, copy the new configuration to use_config, and apply the new configur...
Definition: config.c:334
window_xml
GtkBuilder * window_xml
Definition: main.c:106