Logo Search packages:      
Sourcecode: vertex version File versions

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>

#ifdef HAVE_IMLIB
# include <Imlib.h>
#endif      /* HAVE_IMLIB */

#include <GL/gl.h>
#include <GL/glu.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <gtkgl/gtkglarea.h>

#include "../include/string.h"
#include "../include/disk.h"

#include "guiutils.h"
#include "cdialog.h"
#include "csd.h"
#include "fsd.h"
#include "clipboard.h"
#include "pdialog.h"
#include "fprompt.h"
#include "fb.h"
#include "progressdialog.h"

#include "msglist.h"

#include "editor.h"
#include "editorfio.h"
#include "editorviewcb.h"
#include "vmainstall.h"
#include "vmacfg.h"
#include "vmacfgfio.h"
#include "vmacfglist.h"
#include "vmastyles.h"
#include "vmapixmaps.h"
#include "vmapresetmodels.h"
#include "prefwin.h"
#include "scratchpad.h"
#include "scratchpadfio.h"
#include "aboutdialog.h"
#include "splash.h"
#include "vpiinternalfio.h"
#include "vma.h"
#include "vmautils.h"
#include "config.h"
#include "messages.h"

#ifdef MEMWATCH
# include "memwatch.h"
#endif


gbool initialized_gtk;
gbool need_close_all_windows;
guint vma_manage_toid = (guint)(-1);
VMA_OPTIONS_LIST_DECL
vma_dname_struct dname;
vma_fname_struct fname;
vma_ftype_struct ftype;
vma_styles_list_struct styles_list;

#ifdef HAVE_IMLIB
/* Image library handle. */
void *imlib_handle;
#endif      /* HAVE_IMLIB */


static void VMACreateFileTypes(vma_ftype_struct *buf);
static void VMADestroyFileTypes(vma_ftype_struct *buf);


/*
 *    Creates a file extension types list on the given buffer.
 */
static void VMACreateFileTypes(vma_ftype_struct *buf)
{
      gint n;
      const gchar *name;
      const gchar *ext;
      fb_type_struct ***list;
      gint *list_total;
      fb_type_struct *type_ptr;

      const gchar *string_list_select_directory[] = FILE_EXT_TYPE_LIST_SELECT_DIRECTORY;
      const gchar *string_list_load_model[] = FILE_EXT_TYPE_LIST_LOAD_MODEL;
      const gchar *string_list_save_model[] = FILE_EXT_TYPE_LIST_SAVE_MODEL;
      const gchar *string_list_load_texture[] = FILE_EXT_TYPE_LIST_LOAD_TEXTURE;
      const gchar *string_list_view_background_image[] =
            FILE_EXT_TYPE_LIST_VIEW_BACKGROUND_IMAGE;

      const gchar **string_list;


      if(buf == NULL)
          return;

      memset(buf, 0x00, sizeof(vma_ftype_struct));

/* Adds the string_list of file extension types to the fb_type_struct
 * list pointed to by list and total by list_total.
 *
 * Uses variables n, string_list, list, and list_total.
 */
#define DO_ADD_STRING_LIST    \
{ \
 while((*string_list) != NULL) \
 { \
  ext = (*string_list); \
  string_list++; \
 \
  name = (((*string_list) == NULL) ? "" : (*string_list)); \
  string_list += 3; \
 \
  n = (*list_total); \
  (*list_total) = n + 1; \
  (*list) = (fb_type_struct **)g_realloc( \
   *list, \
   (*list_total) * sizeof(fb_type_struct *) \
  ); \
  if((*list) == NULL) \
  { \
   (*list_total) = 0; \
  } \
  else \
  { \
   type_ptr = (fb_type_struct *)g_malloc0(sizeof(fb_type_struct)); \
   if(type_ptr != NULL) \
   { \
    type_ptr->name = g_strdup(name); \
    type_ptr->ext = g_strdup(ext); \
   } \
   (*list)[n] = type_ptr; \
  } \
 } \
}

      string_list = string_list_select_directory;
      list = &buf->select_directory;
      list_total = &buf->select_directory_total;
      DO_ADD_STRING_LIST

      string_list = string_list_load_model;
      list = &buf->load_model;
      list_total = &buf->load_model_total;
      DO_ADD_STRING_LIST

      string_list = string_list_save_model;
        list = &buf->save_model;
        list_total = &buf->save_model_total;
      DO_ADD_STRING_LIST

      string_list = string_list_load_texture;
        list = &buf->load_texture;
        list_total = &buf->load_texture_total;
      DO_ADD_STRING_LIST

        string_list = string_list_view_background_image;
        list = &buf->view_background_image;
        list_total = &buf->view_background_image_total;
        DO_ADD_STRING_LIST


#undef DO_ADD_STRING_LIST
}

/*
 *    Destroys the given file extension types list.
 */
static void VMADestroyFileTypes(vma_ftype_struct *buf)
{
        fb_type_struct ***list;
        gint *list_total;


      if(buf == NULL)
          return;

#define DO_REMOVE_ALL   \
{ \
 FileBrowserDeleteTypeList(*list, *list_total); \
 (*list) = NULL; \
 (*list_total) = 0; \
}

        list = &buf->load_model;
        list_total = &buf->load_model_total;
      DO_REMOVE_ALL

        list = &buf->save_model;
        list_total = &buf->save_model_total;
        DO_REMOVE_ALL

        list = &buf->load_texture;
        list_total = &buf->load_texture_total;
        DO_REMOVE_ALL

      list = &buf->view_background_image;
        list_total = &buf->view_background_image_total;
        DO_REMOVE_ALL

#undef DO_REMOVE_ALL
}



int main(int argc, char *argv[])
{
      gint i, status;
      gchar *strptr, *strptr2;
      int32_t val_32;
      const gchar *cstrptr, *parm;
      gbool load_plugins_on_startup = TRUE;
      gbool show_splash_on_startup = TRUE;
      const gchar *filename = NULL; /* Model file to load on startup. */
      const gchar *msglist_std[] = VMA_MSGLIST_STD_MESSAGE_LIST;
      struct stat stat_buf;
      vma_core_struct *core_ptr;


#ifdef MEMWATCH
      /* Memwatch initialization. */
      /* Collect stats on a line number basis */
      mwStatistics(2);

      TRACE("MW tracking initialized\n");

/*    mwSetAriFunc(mwAriHandler); */

      mwNoMansLand(MW_NML_ALL);

#endif      /* MEMWATCH */


      /* Allocate core structure. */
      core_ptr = (vma_core_struct *)g_malloc0(sizeof(vma_core_struct));
      if(core_ptr == NULL)
      {
          fprintf(
            stderr,
            "Memory allocation error.\n"
          );
          return(3);
      }


      /* Reset time zone. */
      tzset();

      /* Reset values on core structure. */
      core_ptr->editor = NULL;
      core_ptr->total_editors = 0;

      core_ptr->pref_win = NULL;

      core_ptr->print_win = NULL;
      core_ptr->print_job = NULL;
      core_ptr->total_print_jobs = 0;

      core_ptr->scratch_pad = NULL;
      core_ptr->about_dialog = NULL;
      core_ptr->todwin = NULL;
      core_ptr->splash_win = NULL;

      core_ptr->plugin = NULL;
      core_ptr->total_plugins = 0;

      core_ptr->backup_toid = (guint)-1;
      core_ptr->plugin_manage_toid = (guint)-1;
/*    core_ptr->plugin_manage_idleid = (guint)-1; */


      /* Global program data directory. */
      strptr = dname.data_global;
      cstrptr = (const gchar *)VMADefaultDataGlobalDir();
      strncpy(strptr, cstrptr, PATH_MAX);
        strptr[PATH_MAX - 1] = '\0';

      /* User's home directory. */
      strptr = dname.home;
      cstrptr = (const gchar *)getenv("HOME");
      strncpy(strptr, (cstrptr == NULL) ? "/" : cstrptr, PATH_MAX);
        strptr[PATH_MAX - 1] = '\0';

      /* Local program data directory. */
        strptr = dname.data_local;
        cstrptr = (const gchar *)PrefixPaths(dname.home, VMA_DEF_DATA_LOCAL_DIR);
        strncpy(strptr, (cstrptr == NULL) ? "/" : cstrptr, PATH_MAX);
      strptr[PATH_MAX - 1] = '\0';

      /* Preferences file. */
      strptr = fname.preferences;
      cstrptr = (const gchar *)PrefixPaths(dname.data_local, VMA_DEF_PREFERENCES_FILE);
      strncpy(strptr, (cstrptr == NULL) ? "/" : cstrptr, PATH_MAX);
        strptr[PATH_MAX + NAME_MAX - 1] = '\0';

      /* Reset last models dir to value of home dir. */
        strptr = dname.fb_last_models;
        strncpy(strptr, dname.home, PATH_MAX);
        strptr[PATH_MAX - 1] = '\0';

      /* Reset last textures dir to value of home dir. */
        strptr = dname.fb_last_textures;
        strncpy(strptr, dname.home, PATH_MAX);
        strptr[PATH_MAX - 1] = '\0';

      /* Reset last view background image dir to value of home dir. */
      strptr = dname.fb_last_view_background_image;
      strncpy(strptr, dname.home, PATH_MAX);
        strptr[PATH_MAX - 1] = '\0';

      /* Reset scratchpad file. */
      strptr = fname.scratchpad;
      cstrptr = (const gchar *)PrefixPaths(
          dname.data_local, VMA_DEF_SCRATCHPAD_FILE
      );
      strncpy(
          strptr,
          (cstrptr == NULL) ? VMA_DEF_SCRATCHPAD_FILE : cstrptr,
          PATH_MAX + NAME_MAX
      );
        strptr[PATH_MAX + NAME_MAX - 1] = '\0';

        /* Reset plugins file. */
        strptr = fname.plugins;
        cstrptr = (const gchar *)PrefixPaths(
            dname.data_local, VMA_DEF_PLUGINS_FILE
        );
        strncpy(
            strptr,
            (cstrptr == NULL) ? VMA_DEF_PLUGINS_FILE : cstrptr,
            PATH_MAX + NAME_MAX
        );
        strptr[PATH_MAX + NAME_MAX - 1] = '\0';

      /* Reset local and global preset models directories. */
      strptr = dname.preset_models_global;
      cstrptr = (const gchar *)PrefixPaths(
          dname.data_global, VMA_DEF_PRESET_MODELS_DIR
      );
      strncpy(
          strptr,
          (cstrptr == NULL) ? dname.data_global : cstrptr,
          PATH_MAX
      );
      strptr[PATH_MAX - 1] = '\0';

        strptr = dname.preset_models_local;
        cstrptr = (const gchar *)PrefixPaths(
            dname.data_local, VMA_DEF_PRESET_MODELS_DIR 
        );
        strncpy(
            strptr,
            (cstrptr == NULL) ? dname.data_local : cstrptr,
            PATH_MAX
        );
        strptr[PATH_MAX - 1] = '\0';

        /* Reset local and global preset primitives directories. */
        strptr = dname.preset_primitives_global;
        cstrptr = (const gchar *)PrefixPaths(
            dname.data_global, VMA_DEF_PRESET_PRIMITIVES_DIR 
        );
        strncpy(
            strptr,
            (cstrptr == NULL) ? dname.data_global : cstrptr,
            PATH_MAX
        );
        strptr[PATH_MAX - 1] = '\0';

        strptr = dname.preset_primitives_local; 
        cstrptr = (const gchar *)PrefixPaths(
            dname.data_local, VMA_DEF_PRESET_PRIMITIVES_DIR
        );
        strncpy(
            strptr,
            (cstrptr == NULL) ? dname.data_local : cstrptr,
            PATH_MAX
        );
        strptr[PATH_MAX - 1] = '\0';

        /* Plug-ins directories. */
        strptr = dname.plugins_global;
        cstrptr = (const gchar *)PrefixPaths(
            dname.data_global, VMA_DEF_PLUGINS_DIR
        );
        strncpy(
            strptr,
            (cstrptr == NULL) ? dname.data_global : cstrptr,
            PATH_MAX
        );
        strptr[PATH_MAX - 1] = '\0';

        strptr = dname.plugins_local;
        cstrptr = (const gchar *)PrefixPaths(
            dname.data_local, VMA_DEF_PLUGINS_DIR
        );
        strncpy(
            strptr,
            (cstrptr == NULL) ? dname.data_local : cstrptr,
            PATH_MAX
        );
        strptr[PATH_MAX - 1] = '\0';


      /* Reset global initialized GTK marker. */
      initialized_gtk = FALSE;

      /* Reset global need close all windows. */
      need_close_all_windows = FALSE;

      /* Reset global manage timeout callback function id. */
      vma_manage_toid = (guint)(-1);

      /* Parse arguments. */
      for(i = 1; i < argc; i++)
      {
          parm = (const gchar *)argv[i];
          if(parm == NULL)
            continue;

          /* Help. */
          if(strcasepfx(parm, "--h") ||
             strcasepfx(parm, "-h") ||
               strcasepfx(parm, "--?") ||
               strcasepfx(parm, "-?") ||
               strcasepfx(parm, "/?") ||
               strcasepfx(parm, "?")
          )
          {
            printf(
                "%s",
                MsgListMatchCaseMessage(
                  msglist_std, VMA_MSGNAME_STD_HELP
                )
            );
            g_free(core_ptr);
            return(0);
          }
            /* Version. */
            else if(strcasepfx(parm, "--version") ||
                    strcasepfx(parm, "-version")
            )
            {
            const gchar *copyright_str = MsgListMatchCaseMessage(
                msglist_std, VMA_MSGNAME_STD_COPYRIGHT
            );
            printf("%s %s\n%s\n",
                PROG_NAME, PROG_VERSION, copyright_str
            );
                g_free(core_ptr);
                return(0);
            }

          /* Preferences file. */
          else if(!strcasecmp(parm, "--rcfile") ||
                    !strcasecmp(parm, "-rcfile") ||
                    !strcasecmp(parm, "--configuration_file") ||
                    !strcasecmp(parm, "-configuration_file") ||
                    !strcasecmp(parm, "--configurationfile") ||
                    !strcasecmp(parm, "-configurationfile") ||
                    !strcasecmp(parm, "--config_file") ||
                    !strcasecmp(parm, "-config_file") ||
                    !strcasecmp(parm, "--configfile") ||
                    !strcasecmp(parm, "-configfile") ||
                    !strcasecmp(parm, "--configuration") ||
                    !strcasecmp(parm, "-configuration") ||
                    !strcasecmp(parm, "--config") ||
                    !strcasecmp(parm, "-config") ||
                    !strcasecmp(parm, "--f") ||
                    !strcasecmp(parm, "-f")
          )
          {
            i++;
            if(i < argc)
            {
                parm = (const gchar *)argv[i];
                strptr = g_strdup(parm);
                if(strptr != NULL)
                {
                  strptr2 = PathSubHome(strptr);
                  g_free(strptr);
                  strptr = ((strptr2 == NULL) ? NULL : g_strdup(strptr2));
                }
                if(strptr != NULL)
                {
                  /* Get new preferences file path. */
                  if(!ISPATHABSOLUTE(strptr))
                    {
                      strptr2 = PrefixPaths(dname.home, strptr);
                      if(strptr2 != NULL)
                        strncpy(
                            fname.preferences, strptr2,
                            PATH_MAX + NAME_MAX
                        );
                  }
                  else
                  {
                            strncpy(
                                fname.preferences, strptr,
                                PATH_MAX + NAME_MAX
                            );
                  }
                    fname.preferences[PATH_MAX + NAME_MAX - 1] = '\0';

                  g_free(strptr);
                  strptr = NULL;
                }

                /* Check if new specified preferences file exists. */
                if(stat(fname.preferences, &stat_buf))
                    {
/* Let loading of preferences determine this
                  fprintf(stderr,
                      "%s: No such file.\n",
                      fname.preferences
                  );
                        g_free(core_ptr);
                  return(1);
 */
                }
                else
                {
                  if(!S_ISREG(stat_buf.st_mode))
                  {
                            fprintf(stderr,
                                "%s: Not a file.\n",
                                fname.preferences
                            );
                            g_free(core_ptr);
                            return(1);
                  }

                }
            }
            else
            {
                fprintf(stderr, "%s: Requires argument.\n",
                  argv[i - 1]
                );
                    g_free(core_ptr);
                return(1);
            }
          }
          /* Disable plug-ins on startup. */
          else if(strcasepfx(parm, "--disable_plugins") ||
                    strcasepfx(parm, "-disable_plugins") ||
                    strcasepfx(parm, "--disable-plugins") ||
                    strcasepfx(parm, "-disable-plugins") ||
                    strcasepfx(parm, "--disableplugins") ||
                    strcasepfx(parm, "-disableplugins")
          )
          {
            load_plugins_on_startup = FALSE;
          }
          /* Do not show splash on startup. */
          else if(strcasepfx(parm, "--no_splash") ||
                    strcasepfx(parm, "-no_splash") ||
                    strcasepfx(parm, "--no-splash") ||
                    strcasepfx(parm, "-no-splash") ||
                    strcasepfx(parm, "--nosplash") ||
                    strcasepfx(parm, "-nosplash")
          )
            {
            show_splash_on_startup = FALSE;
          }
          /* Some other unsupported option? */
          else if(strpfx(parm, "+") ||
                    strpfx(parm, "-")
          )
          {

          }
          /* All else assume file name. */
          else
          {
            filename = parm;
          }
      }

      /* Set signals to watch for. */
#ifndef MEMWATCH
      signal(SIGINT, VMASignalCB);
        signal(SIGTERM, VMASignalCB);
        signal(SIGKILL, VMASignalCB);
        signal(SIGSEGV, VMASignalCB);
        signal(SIGSTOP, VMASignalCB);
        signal(SIGCONT, VMASignalCB);
        signal(SIGPIPE, VMASignalCB);
#endif

      /* Check if global configuration options list is declared
       * correctly.
       */
      status = sizeof(option) / sizeof(vma_cfg_item_struct *);
      if((status % 3) != 0)
      {
          fprintf(
            stderr,
"Internal error: vma_cfg_item_struct option[] is not aligned with 3 pointers.\n"
          );
      }


      /* Load preferences from file, this should be done first so
       * we have the currect locations of file and directory names.
       * If they do not exist then this will be considered a new
       * install and the user will be prompted about the install.
       */
      if(VMACFGLoadFromFile(fname.preferences, option))
      {
          /* Could not load preferences file, implying we
           * need to install locally.
           */
          status = VMADoInstall(
            &argc, &argv,
            fname.preferences, option
          );
          if(status)
          {
            /* Failed to install, check reason. */
            switch(status)
            {
              case -4:  /* User aborted. */
                    g_free(core_ptr);
                return(4);
                break;

              case -3:  /* Systems error. */
                    g_free(core_ptr);
                return(3);
                break;

              case -2:
                    g_free(core_ptr);
                return(2);
                break;

              default:  /* All else assume -1, general error. */
                    g_free(core_ptr);
                return(1);
                break;
            }
          }
          else
          {
            /* Installed successfully, the global configuration 
             * options list should be set up properly now.
             */
            VMACFGSaveToFile(fname.preferences, option);
          }
      }
      else
      {
          /* Preferences loaded successfully, check preferences
           * version number and see if we need an upgrade.
           */
          gint old_version_major, old_version_minor;
          gbool need_upgrade = FALSE;

          old_version_major = VMACFGItemListGetValueI(
            option, VMA_CFG_PARM_VERSION_MAJOR
          );
            old_version_minor = VMACFGItemListGetValueI(
                option, VMA_CFG_PARM_VERSION_MINOR
            );
          if(old_version_major < PROG_VERSION_MAJOR)
            need_upgrade = TRUE;
          else if(old_version_minor < PROG_VERSION_MINOR)
            need_upgrade = TRUE;

          if(need_upgrade)
          {
                status = VMADoInstallUpgrade(
                    &argc, &argv,
                    fname.preferences, option
                );
                if(status)
                {
                    /* Upgrade failed, check reason. */
                switch(status)
                {
                  case -4:    /* User aborted. */
                        g_free(core_ptr);
                  return(4);
                  break;

                  case -3:    /* Systems error. */
                        g_free(core_ptr);
                  return(3);
                  break;

                  case -2:
                        g_free(core_ptr);
                  return(2);
                  break;

                  default:    /* All else assume -1, general error. */
                        g_free(core_ptr);
                  return(1);
                  break;
                }
            }
            else
            {
                /* Upgraded successfully. */
            }
          }
      }

      /* Update global values based on the just loaded global
       * configuration items list values.
       */

      /* Explicitly set current program version to configuration options
       * list.
       */
      /* Version major. */
      val_32 = PROG_VERSION_MAJOR;
      VMACFGItemListMatchSetValue(
          option, VMA_CFG_PARM_VERSION_MAJOR, (void *)&val_32, FALSE
      );
        /* Version minor. */
        val_32 = PROG_VERSION_MINOR;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_VERSION_MINOR, (void *)&val_32, FALSE
        );

        /* Get local and global data directories. */
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_DIR_LOCAL);
        if(strptr != NULL)
        {
            strptr2 = dname.data_local; 
            strncpy(strptr2, strptr, PATH_MAX);
            strptr2[PATH_MAX - 1] = '\0';
        }
      strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_DIR_GLOBAL);
      if(strptr != NULL)
      {
            strptr2 = dname.data_global;
            strncpy(strptr2, strptr, PATH_MAX);
            strptr2[PATH_MAX - 1] = '\0';
        }
        /* Get local and global preset models directories. */
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_DIR_PRESET_MODELS_LOCAL);
        if(strptr != NULL)
        {
            strptr2 = dname.preset_models_local;
            strncpy(strptr2, strptr, PATH_MAX);
            strptr2[PATH_MAX - 1] = '\0';
        }
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_DIR_PRESET_MODELS_GLOBAL);
        if(strptr != NULL)
        {
            strptr2 = dname.preset_models_global;
            strncpy(strptr2, strptr, PATH_MAX);
            strptr2[PATH_MAX - 1] = '\0';
        }
        /* Get local and global preset primitives directories. */
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_DIR_PRESET_PRIMITIVES_LOCAL);
        if(strptr != NULL)
        {
            strptr2 = dname.preset_primitives_local;
            strncpy(strptr2, strptr, PATH_MAX);
            strptr2[PATH_MAX - 1] = '\0';
        }
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_DIR_PRESET_PRIMITIVES_GLOBAL);
        if(strptr != NULL)
        {
            strptr2 = dname.preset_primitives_global;
            strncpy(strptr2, strptr, PATH_MAX);
            strptr2[PATH_MAX - 1] = '\0';
        }
        /* Get local and global plug-ins directories. */
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_DIR_PLUGINS_LOCAL);
        if(strptr != NULL)
        {
            strptr2 = dname.plugins_local;
            strncpy(strptr2, strptr, PATH_MAX);
            strptr2[PATH_MAX - 1] = '\0';
        }
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_DIR_PLUGINS_GLOBAL);
        if(strptr != NULL)
        {
            strptr2 = dname.plugins_global;
            strncpy(strptr2, strptr, PATH_MAX);
            strptr2[PATH_MAX - 1] = '\0';
        }
        /* Get tempory files directory. */
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_DIR_TMP);
        if(strptr != NULL)
        {
            strptr2 = dname.tmp;
            strncpy(strptr2, strptr, PATH_MAX);
            strptr2[PATH_MAX - 1] = '\0';  
        }
      /* Get last models directory. */
      strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_LAST_DIR_MODELS);
        if(strptr != NULL)
      {
          strptr2 = dname.fb_last_models;
          strncpy(strptr2, strptr, PATH_MAX);
          strptr2[PATH_MAX - 1] = '\0';
      }
      /* Get last textures directory. */
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_LAST_DIR_TEXTURES);
        if(strptr != NULL)
        {
            strptr2 = dname.fb_last_textures;
            strncpy(strptr2, strptr, PATH_MAX);
            strptr2[PATH_MAX - 1] = '\0';
        }
      /* Get last view background image directory. */
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_LAST_DIR_VIEW_BACKGROUND_IMAGE);
        if(strptr != NULL)
        {
            strptr2 = dname.fb_last_view_background_image;
            strncpy(strptr2, strptr, PATH_MAX);   
            strptr2[PATH_MAX - 1] = '\0';
        }

      /* Scratch pad file. */
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_FILE_SCRATCHPAD);
        if(strptr != NULL)
        {
            strptr2 = fname.scratchpad;
            strncpy(strptr2, strptr, PATH_MAX + NAME_MAX);
            strptr2[PATH_MAX + NAME_MAX - 1] = '\0';
        }
        /* Plugins file. */
        strptr = VMACFGItemListGetValueS(option, VMA_CFG_PARM_FILE_PLUGINS);
        if(strptr != NULL)
        {
            strptr2 = fname.plugins;
            strncpy(strptr2, strptr, PATH_MAX + NAME_MAX);
            strptr2[PATH_MAX + NAME_MAX - 1] = '\0';
        }



      /* Create file extension types list (used with file browser). */
      VMACreateFileTypes(&ftype);


      /* Initialize GTK+ as needed. */
      if(!initialized_gtk)
      {
            if(!gtk_init_check(&argc, &argv))
          {
                fprintf(
                    stderr,
 "This program requires X.\n"
                );
                g_free(core_ptr);
            return(1);
          }
          initialized_gtk = TRUE;
      }

      /* Initialize GDK RGB buffers. */
      gdk_rgb_init();

#ifdef HAVE_IMLIB
      /* Initialize image library. */
      imlib_handle = Imlib_init(GDK_DISPLAY());
#endif

      /* Check if OpenGL available. */
        if(gdk_gl_query() == FALSE)
        {
            fprintf(stderr, "OpenGL not available.\n");
            g_free(core_ptr);
            return(1);
        }

      /* Create splash window? */
      if(show_splash_on_startup && (core_ptr->splash_win == NULL))
      {
          gchar *splash_path = NULL;;

          cstrptr = PrefixPaths(dname.data_global, VMA_DEF_SPLASH_IMAGE_BG);
          if(cstrptr != NULL)
            splash_path = g_strdup(cstrptr);

          core_ptr->splash_win = SplashNew(
            1,          /* Number of progress bars. */
            splash_path
          );
          SplashWinMap(core_ptr->splash_win);

          g_free(splash_path);
      }
      SplashUpdate(
          core_ptr->splash_win,
          0,                  /* Progress bar number. */
          0.0,
          NULL,
          TRUE
      );
        SplashUpdate(
            core_ptr->splash_win,
            1,                /* Progress bar number. */
            0.0,
            NULL,
            TRUE
        );


      /* Enable/disable tooltips. */
      if(VMACFGItemListGetValueI(option, VMA_CFG_PARM_SHOW_TOOLTIPS))
          GUISetGlobalTipsState(TRUE);
      else
          GUISetGlobalTipsState(FALSE);

        /* Load GTK+ styles list. */
        VMAStylesListCreate(&styles_list);

      /* Load global pixmaps. */
      VMAPixmapsListLoad(core_ptr, &vma_pixmaps_list, core_ptr->splash_win);

      /* Load preset V3D models (for the editor's create model dialog). */
      VMAPresetModelsLoad(core_ptr, &vma_preset_models);

      /* Initialize confermation dialog. */
      CDialogInit();

      /* Initialized clipboard browser and system. */
      ClipboardBrowserInit();

      /* Color selection dialog. */
        CSDInit();

      /* Font selection dialog. */
      FSDInit();

      /* Initialize prompt dialog. */
      PDialogInit();

      /* Initialize file browser. */
      FileBrowserInit();

      /* Initialize progress dialog. */
      ProgressDialogInit();

      /* Initialize Floating prompt. */
      FPromptInit();


      /* Preferences window (initialized when needed). */
      core_ptr->pref_win = NULL;

      /* Print window (initialized when needed). */
      core_ptr->print_win = NULL;

      /* Scratch pad. */
      core_ptr->scratch_pad = ScratchPadNew(core_ptr);
      /* Load last scratch pad file. */
      ScratchPadLoadFromFile(core_ptr->scratch_pad, fname.scratchpad);

      /* Load plug-ins, the plug-ins (if any) will be loaded from the
       * global and local plug-in directories (if either exists).
       */
      core_ptr->plugin = NULL;
      core_ptr->total_plugins = 0;
      if(load_plugins_on_startup)
      {
          vma_plugin_struct *plugin_ptr;


          VPILoadPluginsFromDirectory(
            &core_ptr->plugin, &core_ptr->total_plugins,
            dname.plugins_global,
            TRUE,       /* Load as disabled. */
            TRUE,       /* Is global. */
            core_ptr,
            core_ptr->splash_win
          );
          VPILoadPluginsFromDirectory(
            &core_ptr->plugin, &core_ptr->total_plugins,
            dname.plugins_local,
            TRUE,       /* Load as disabled. */
            FALSE,            /* Is not global. */
            core_ptr,
            core_ptr->splash_win
          );
          /* If any plugins were loaded, then we need to set their
           * attributes from the plugins configuration file (if it
           * exists).
           */
          VPILoadConfigurationFromFile(
            &core_ptr->plugin, &core_ptr->total_plugins,
            fname.plugins
          );

          /* Request information from each loaded plug-in. */
          for(i = 0; i < core_ptr->total_plugins; i++)
          {
            plugin_ptr = core_ptr->plugin[i];
            if(plugin_ptr == NULL)
                continue;

            if(plugin_ptr->handle == NULL)
                continue;

            if(!VPIDoGetInfo(plugin_ptr))
            {
                /* Unable to get info, need to disable plug-in. */
                VPIDisable(plugin_ptr);
                continue;
            }

            if(SplashUpdate(
                core_ptr->splash_win,
                0, (gdouble)(i + 1) / (gdouble)core_ptr->total_plugins,
                "Getting information from plug-ins...",
                TRUE
            ) == SPLASH_ABORT)
                break;
            }
      }


        /* Create first editor. */
      SplashUpdate(
          core_ptr->splash_win,
          0, 0.0,
          "Creating editor...",
          TRUE
      );
      VMANewEditor(core_ptr);
        SplashUpdate(
            core_ptr->splash_win,
            0, 1.0,
            "Creating editor...",
            TRUE
        );


        /* Destroy splash window, we don't need it anymore. Note that
       * the splash window should be destroyed just before its possible
       * for user input, otherwise we have reenterent issues which
       * although may not be serious- we'ed rather not worry about it.
       */
        SplashDelete(core_ptr->splash_win);
        core_ptr->splash_win = NULL;


      /* Create tip of day window? */
      if(VMACFGItemListGetValueI(option, VMA_CFG_PARM_SHOW_TIPOFDAY))
        {
          static const gchar *tod_msglist[] = VMA_MSGLIST_TOD_MESSAGE_LIST;

          if(core_ptr->todwin == NULL)
            core_ptr->todwin = TODWinNew(
                (gpointer)core_ptr,
                tod_msglist,
                TRUE,
                (gpointer)core_ptr,
                VMAShowTipOfDayNextTimeToggleCB
            );
          if(core_ptr->todwin != NULL)
            TODWinMapTip(
                core_ptr->todwin,
                time(NULL),
                -1
            );
      }


        /* Set GTK+ timeout callbacks. */
      /* Standard timeout callback. */
      vma_manage_toid = gtk_timeout_add(
            1000,       /* 1 second interval. */
            (GtkFunction)VMATimeoutCB,
            core_ptr
        );
      /* Backup timeout callback. */
      i = VMACFGItemListGetValueI(option, VMA_CFG_PARM_BACKUP_PERIODIC_INT);
      if(i > 0)
      {
          core_ptr->backup_toid = gtk_timeout_add(   
            i * 60 * 1000,    /* Convert to milliseconds. */
            (GtkFunction)VMABackupTimeoutCB,
            (gpointer)core_ptr
          );

          /* Need to update menus on editor. */
          if(core_ptr->total_editors > 0)
          {
            ma_editor_struct *editor_ptr = core_ptr->editor[0];
            if(editor_ptr != NULL)
            {
                EditorUpdateMenus(editor_ptr);
                EditorUpdateAllViewMenus(editor_ptr);
            }
          }
      }
      /* Plug-ins timeout callback. */
      core_ptr->plugin_manage_toid = gtk_timeout_add(
          50,
          (GtkFunction)VMAPluginManageTimeoutCB,
          (gpointer)core_ptr
      );
/*
      core_ptr->plugin_manage_idleid = gtk_idle_add_priority(
            G_PRIORITY_LOW,
            (GtkFunction)VMAPluginManageTimeoutCB,
            (gpointer)core_ptr
        );
 */


      /* Load filename at startup? */
      if((filename != NULL) &&
           (core_ptr->total_editors > 0)
      )
      {
          ma_editor_struct *editor_ptr = core_ptr->editor[0];
          if(editor_ptr != NULL)
          {
            EditorLoadModelFile(editor_ptr, filename);
            EditorUpdateMenus(editor_ptr);
            EditorUpdateAllViewMenus(editor_ptr);
          }
      }


      /* Enter main GUI management loop. */
        gtk_main();


      /* Begin updating certain preferences before saving them. */
      /* Local and global data directories. */
      strptr = dname.data_local;
      VMACFGItemListMatchSetValue(
          option, VMA_CFG_PARM_DIR_LOCAL, strptr, TRUE
      );
        strptr = dname.data_global;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_DIR_GLOBAL, strptr, TRUE
        );
      /* Local and global preset models directories. */
        strptr = dname.preset_models_local;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_DIR_PRESET_MODELS_LOCAL, strptr, TRUE
        );
        strptr = dname.preset_models_global;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_DIR_PRESET_MODELS_GLOBAL, strptr, TRUE
        );
        /* Local and global preset primitives directories. */
        strptr = dname.preset_primitives_local;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_DIR_PRESET_PRIMITIVES_LOCAL, strptr, TRUE
        );
        strptr = dname.preset_primitives_global;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_DIR_PRESET_PRIMITIVES_GLOBAL, strptr, TRUE
        );
      /* Local and global plug-ins directories. */
        strptr = dname.plugins_local;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_DIR_PLUGINS_LOCAL, strptr, TRUE
        );
        strptr = dname.plugins_global;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_DIR_PLUGINS_GLOBAL, strptr, TRUE
        );
      /* Tempory directory. */
        strptr = dname.tmp;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_DIR_TMP, strptr, TRUE
        );
      /* Last file paths. */
        strptr = dname.fb_last_models;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_LAST_DIR_MODELS, strptr, TRUE
        );
        strptr = dname.fb_last_textures;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_LAST_DIR_TEXTURES, strptr, TRUE
        );
        strptr = dname.fb_last_view_background_image;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_LAST_DIR_VIEW_BACKGROUND_IMAGE,
          strptr, TRUE
        );
        /* Scratchpad file. */
        strptr = fname.scratchpad;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_FILE_SCRATCHPAD, strptr, TRUE
        );
        /* Plug-ins file. */
        strptr = fname.plugins;
        VMACFGItemListMatchSetValue(
            option, VMA_CFG_PARM_FILE_PLUGINS, strptr, TRUE
        );

      /* Save plug-ins configuration file. */
        VPISaveConfigurationToFile(
          core_ptr->plugin, core_ptr->total_plugins,
          fname.plugins
      );

      /* Save scratchpad file. */
      ScratchPadSaveToFile(core_ptr->scratch_pad, fname.scratchpad);

      /* Save preferences. */
      VMACFGSaveToFile(fname.preferences, option);

      /* Shutdown all resources on core structure. */
      VMAShutdownCB(core_ptr);
      /* Shut down related resources. */
      FPromptShutdown();
      PDialogShutdown();
      ProgressDialogShutdown();
      FileBrowserShutdown();
      FSDShutdown();
      CSDShutdown();
      ClipboardBrowserShutdown();
      CDialogShutdown();      /* Confermation dialog last. */

      /* Unload preset models. */
      VMAPresetModelsUnload(core_ptr, &vma_preset_models);

        /* Global pixmaps. */
        VMAPixmapsListUnload(core_ptr, &vma_pixmaps_list);

        /* File extension types list. */
        VMADestroyFileTypes(&ftype);

      /* GTK+ styles list. */
      VMAStylesListDestroy(&styles_list);


      /* Free core structure. */
      g_free(core_ptr);
      core_ptr = NULL;

#ifdef HAVE_IMLIB
      /* Reset image library handle. */
      imlib_handle = NULL;
#endif


      /* Delete configuration option list's values but leave parameter
       * and type alone since they were statically allocated.
       */
      i = 0;
      while(((&option[i])->type != VMA_CFG_ITEM_TYPE_NONE) ||
              ((&option[i])->parameter != NULL)
      )
      {
          VMACFGItemResetValue(&option[i]);
          i++;
      }

/*
This needed? Shouldn't GTK+ resources be freed when program returns?
      gtk_exit(0);
 */

      return(0);
}

Generated by  Doxygen 1.6.0   Back to index