Logo Search packages:      
Sourcecode: xconq version File versions  Download package

xconq.c

/* The main program of the X11 interface to Xconq.
   Copyright (C) 1987-1989, 1991-2000 Stanley T. Shebs.

Xconq is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.  See the file COPYING.  */

#include "conq.h"
#include "kpublic.h"
#include "cmdline.h"

#include "tcltk/tkconq.h"
extern int use_stdio;

#include <unistd.h>

/* Local function declarations. */

static void accept_all_remotes(void);
static int handle_x_error(Display *dpy, XErrorEvent *evt);
static int handle_xio_error(Display *dpy);

/* The main program. */

int
main(int argc, char *argv[])
{
    extern uid_t games_uid;

    use_stdio = TRUE;
    /* Dummy reference to get libraries pulled in */
    if (argc == -1)
      cmd_error(NULL, NULL);
    /* Shift to being the user that started the game. */
    games_uid = geteuid();
    setuid(getuid());
    init_library_path(NULL);
    /* Fiddle with game module structures. */
    clear_game_modules();
#ifdef DEBUGGING
    init_debug_to_stdout();
#endif /* DEBUGGING */
    /* Set up empty data structures. */
    init_data_structures();

    parse_command_line(argc, argv, general_options);
    parse_command_line(argc, argv, variant_options);
    parse_command_line(argc, argv, player_options);
    /* Complain about anything that's left. */
    parse_command_line(argc, argv, leftover_options);

    if (argc > 1) {
      /* We're probably typing in a command line, use stdout. */
      printf("\n              Welcome to X11 Xconq version %s\n\n",
             version_string());
      printf("%s", license_string());
      print_any_news();
    } else {
      /* Total GUI-ness this way. */
      option_popup_new_game_dialog = TRUE;
    }

    initial_ui_init();

    if (option_popup_new_game_dialog) {
      /* Do all game setup via the GUI. */
      popup_game_dialog();
    } else if (option_game_to_join != NULL) {
      /* Joining a game, using the command line. */
      /* (should detect attempts to ask for options that will
         be ignored) */
          /* (should be able to ask for position among sides) */
      if (!try_join_game(option_game_to_join)) {
          fprintf(stderr, "Unable to connect to game at \"%s\"\n",
                option_game_to_join);
          exit(1);
      }
      printf("Connected to game host\n");
      /* Keep talking to the host until the game is all set up. */
      while (current_stage != game_ready_stage) {
          receive_data(0);
      }
      launch_game();
    } else {
      /* Hosting a game from the command line, or else playing solo. */
      if (option_game_to_host != NULL) {
          /* Collect the programs that will participate in game
             setup (more may come later, after the game has
             started, if the game module allows it). */
          host_the_game(option_game_to_host);
          accept_all_remotes();
      }
      start_game_load_stage();
      load_all_modules();
      check_game_validity();
      if (my_rid > 0 && my_rid == master_rid) {
          broadcast_game_module();
      }
      interpret_variants();
      set_variants_from_options();
      start_player_pre_setup_stage();
      set_players_from_options();
      start_player_setup_stage();
      launch_game();
    }
    if (!option_popup_new_game_dialog)
      print_instructions();
    /* At this point we know we can use popups instead of stdio for
       warnings and messages and such. */
    use_stdio = FALSE;
    /* Go into the main play loop. */
    ui_mainloop();

    /* Humor the compiler. */
    return 0;
}

/* The default (human) player is the current user on the current display. */

Player *
add_default_player(void)
{
    Player *player = add_player();
    
    player->name = getenv("USER");
    player->configname = getenv("XCONQCONFIG");
    player->displayname = getenv("DISPLAY");
    return player;
}

void
make_default_player_spec(void)
{
    if (default_player_spec == NULL)
      default_player_spec = xmalloc(BUFSIZE);
    default_player_spec[0] = '\0';
    if (!empty_string(getenv("USER"))) {
      strcpy(default_player_spec, getenv("USER"));
      strcat(default_player_spec, "@");
    }
    if (!empty_string(raw_default_player_spec)
      && raw_default_player_spec[0] == '@') {
      strcat(default_player_spec, raw_default_player_spec);
    } else if (!empty_string(getenv("DISPLAY"))) {
      strcat(default_player_spec, getenv("DISPLAY"));
    }
}

/* Wait for all the players to join, set up each one as it comes in. */

static void
accept_all_remotes(void)
{
    int lastcount;
    extern int option_num_to_wait_for;

    /* (should error?) */
    if (option_num_to_wait_for <= 0)
      return;
    numremotewaiting = option_num_to_wait_for;
    printf("Now waiting for %d to join\n", numremotewaiting);
    while (numremotes < (option_num_to_wait_for + 1)) {
      lastcount = numremotes;
      receive_data(0);
      if (numremotes != lastcount) {
          numremotewaiting = (option_num_to_wait_for - (numremotes - 1));
          printf("Now waiting for %d to join\n", numremotewaiting);
      }
    }
}

void
init_x_signal_handlers(void)
{
    XSetErrorHandler(handle_x_error);
    XSetIOErrorHandler(handle_xio_error);
}

/* Handlers for X catastrophes attempt to do a save first. */

static int
handle_x_error (Display *dpy, XErrorEvent *evt)
{
    static int num_errors = 0;
    char buf[BUFSIZE];

    XGetErrorText(dpy, evt->error_code, buf, BUFSIZE);
    fprintf(stderr, "\nX error on display %s: %s\n", DisplayString(dpy), buf);
    if (++num_errors >= 10) {
        printf("\nX error: trying emergency save!\n");
      /* Note that if the save fails too, we're totally hosed. */
      /* (should use configurable name here) */
        write_entire_game_state("ack!.xconq");
      abort();
    }
    return 0;
}

static int
handle_xio_error (Display *dpy)
{
    fprintf(stderr, "\nX IO error on display %s: trying emergency save!\n",
         DisplayString(dpy));
    write_entire_game_state("ack!.xconq");
    abort();
    return 0;
}

Generated by  Doxygen 1.6.0   Back to index