Complete.Org: Mailing Lists: Archives: freeciv-dev: August 2005:
[Freeciv-Dev] (PR#13589) Theme support
Home

[Freeciv-Dev] (PR#13589) Theme support

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13589) Theme support
From: "Mateusz Stefek" <mstefek@xxxxxxxxx>
Date: Sat, 20 Aug 2005 02:29:55 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13589 >

Some more documentation and a feature to use default system theme.

It still needs empty implementations for other guis to be comitted.

The other issue is that the code isn't used at all. Maybe it will be
easier to produce patches and themes if it is in CVS.

--
mateusz
diff -urN -Xfreeciv/diff_ignore freeciv/client/civclient.c 
themes/client/civclient.c
--- freeciv/client/civclient.c  2005-08-03 08:28:25.000000000 +0200
+++ themes/client/civclient.c   2005-08-20 11:10:46.000000000 +0200
@@ -68,6 +68,7 @@
 #include "plrdlg_g.h"
 #include "repodlgs_g.h"
 #include "tilespec.h"
+#include "themes_common.h"
 
 #include "civclient.h"
 
@@ -315,6 +316,7 @@
   chatline_common_init();
   message_options_init();
   init_player_dlg_common();
+  init_themes();
   settable_options_init();
 
   load_general_options();
diff -urN -Xfreeciv/diff_ignore freeciv/client/gui-gtk-2.0/Makefile.am 
themes/client/gui-gtk-2.0/Makefile.am
--- freeciv/client/gui-gtk-2.0/Makefile.am      2005-08-03 08:28:25.000000000 
+0200
+++ themes/client/gui-gtk-2.0/Makefile.am       2005-08-20 11:10:46.000000000 
+0200
@@ -85,6 +85,7 @@
        spaceshipdlg.h  \
        sprite.c        \
        sprite.h        \
+       themes.c        \
        wldlg.c         \
        wldlg.h 
 
diff -urN -Xfreeciv/diff_ignore freeciv/client/gui-gtk-2.0/themes.c 
themes/client/gui-gtk-2.0/themes.c
--- freeciv/client/gui-gtk-2.0/themes.c 1970-01-01 01:00:00.000000000 +0100
+++ themes/client/gui-gtk-2.0/themes.c  2005-08-20 11:19:10.000000000 +0200
@@ -0,0 +1,147 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 2005 The Freeciv Team
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+
+#include "mem.h"
+#include "support.h"
+
+#include "themes_common.h"
+#include "themes_g.h"
+
+/*****************************************************************************
+  Loads a gtk theme directory/theme_name
+*****************************************************************************/
+void gui_load_theme(const char *directory, const char *theme_name)
+{
+  char buf[strlen(directory) + strlen(theme_name) + 32];
+  gchar *default_files[] = {buf, NULL};
+  
+  /* Gtk theme is a directory containing gtk-2.0/gtkrc file */
+  my_snprintf(buf, sizeof(buf), "%s/%s/gtk-2.0/gtkrc", directory,
+             theme_name);
+
+  gtk_rc_set_default_files(default_files);
+
+  gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
+}
+
+/*****************************************************************************
+  Clears a theme (sets default system theme)
+*****************************************************************************/
+void gui_clear_theme(void)
+{
+  gchar *default_files[] = {NULL};
+  
+  gtk_rc_set_default_files(default_files);
+  gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
+}
+
+/*****************************************************************************
+  Each gui has its own themes directories.
+  For gtk2 these are:
+  - /usr/share/themes
+  - ~/.themes
+  Returns an array containing these strings and sets array size in count.
+  The caller is responsible for freeing the array and the paths.
+*****************************************************************************/
+char **get_gui_specific_themes_directories(int *count)
+{
+  gchar *standard_dir;
+  char *home_dir;
+  char **directories = fc_malloc(sizeof(char *) * 2);
+
+  *count = 0;
+
+  standard_dir = gtk_rc_get_theme_dir();
+  directories[*count] = mystrdup(standard_dir);
+  (*count)++;
+  g_free(standard_dir);
+
+  home_dir = user_home_dir();
+  if (home_dir) {
+    char buf[strlen(home_dir) + 16];
+    
+    my_snprintf(buf, sizeof(buf), "%s/.themes/", home_dir);
+    directories[*count] = mystrdup(buf);
+    (*count)++;
+  }
+
+  return directories;
+}
+
+/*****************************************************************************
+  Return an array of names of usable themes in the given directory.
+  Array size is stored in count.
+  Useable theme for gtk+ is a directory which contains file gtk-2.0/gtkrc.
+  The caller is responsible for freeing the array and the names
+*****************************************************************************/
+char **get_useable_themes_in_directory(const char *directory, int *count)
+{
+  DIR *dir;
+  struct dirent *entry;
+  
+  char **theme_names = fc_malloc(sizeof(char *) * 2);
+  /* Allocated memory size */
+  int t_size = 2;
+
+
+  *count = 0;
+
+  dir = opendir(directory);
+  if (!dir) {
+    /* This isn't directory or we can't list it */
+    return theme_names;
+  }
+
+  while ((entry = readdir(dir))) {
+    char buf[strlen(directory) + strlen(entry->d_name) + 32];
+    struct stat stat_result;
+
+    my_snprintf(buf, sizeof(buf),
+               "%s/%s/gtk-2.0/gtkrc", directory, entry->d_name);
+
+    if (stat(buf, &stat_result) != 0) {
+      /* File doesn't exist */
+      continue;
+    }
+    
+    if (!S_ISREG(stat_result.st_mode)) {
+      /* Not a regular file */
+      continue;
+    }
+    
+    /* Otherwise it's ok */
+    
+    /* Increase array size if needed */
+    if (*count == t_size) {
+      theme_names = fc_realloc(theme_names, t_size * 2 * sizeof(char *));
+      t_size *= 2;
+    }
+
+    theme_names[*count] = mystrdup(entry->d_name);
+    (*count)++;
+  }
+
+  closedir(dir);
+
+  return theme_names;
+}
diff -urN -Xfreeciv/diff_ignore freeciv/client/include/Makefile.am 
themes/client/include/Makefile.am
--- freeciv/client/include/Makefile.am  2005-08-03 08:28:26.000000000 +0200
+++ themes/client/include/Makefile.am   2005-08-20 11:10:46.000000000 +0200
@@ -26,4 +26,5 @@
        repodlgs_g.h    \
        spaceshipdlg_g.h        \
        sprite_g.h              \
+       themes_g.h              \
        wldlg_g.h
diff -urN -Xfreeciv/diff_ignore freeciv/client/include/themes_g.h 
themes/client/include/themes_g.h
--- freeciv/client/include/themes_g.h   1970-01-01 01:00:00.000000000 +0100
+++ themes/client/include/themes_g.h    2005-08-20 11:16:19.000000000 +0200
@@ -0,0 +1,21 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 2005 The Freeciv Team
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+#ifndef FC__THEMES_G_H
+#define FC__THEMES_G_H
+
+void gui_load_theme(const char* directory, const char* theme_name);
+void gui_clear_theme(void);
+char** get_gui_specific_themes_directories(int *count);
+char** get_useable_themes_in_directory(const char* directory, int* count);
+
+#endif
diff -urN -Xfreeciv/diff_ignore freeciv/client/Makefile.am 
themes/client/Makefile.am
--- freeciv/client/Makefile.am  2005-08-20 10:34:22.000000000 +0200
+++ themes/client/Makefile.am   2005-08-20 11:10:46.000000000 +0200
@@ -173,6 +173,8 @@
        servers.h               \
        text.c  \
        text.h  \
+       themes_common.c \
+       themes_common.h \
        tilespec.c      \
        tilespec.h      \
        audio.c         \
diff -urN -Xfreeciv/diff_ignore freeciv/client/themes_common.c 
themes/client/themes_common.c
--- freeciv/client/themes_common.c      1970-01-01 01:00:00.000000000 +0100
+++ themes/client/themes_common.c       2005-08-20 11:25:10.000000000 +0200
@@ -0,0 +1,190 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 2005 The Freeciv Team
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+
+
+#include "mem.h"
+#include "shared.h"
+#include "support.h"
+
+#include "themes_common.h"
+
+#include "themes_g.h"
+
+/***************************************************************************
+  A theme is a portion of client data, which for following reasons should
+  be separated from a tileset:
+  - Theme is not only graphic related
+  - Theme can be changed independently from tileset
+  - Theme implementation is gui specific and most themes can not be shared
+    between different guis.
+  Theme is recognized by its name.
+  
+  Theme is stored in a directory called like the theme. The directory contains
+  some data files. Each gui defines its own format in the
+  get_useable_themes_in_directory() function.
+****************************************************************************/
+
+/* A directory containing a list of usable themes */
+struct theme_directory {
+  /* Path on the filesystem */
+  char *path; 
+  /* Array of theme names */
+  char **themes;
+  /* Themes array length */
+  int num_themes;
+};
+
+/* List of all directories with themes */
+static int num_directories;
+struct theme_directory *directories;
+
+/****************************************************************************
+  Initialized themes data
+****************************************************************************/
+void init_themes(void)
+{
+  char **directories_paths = fc_malloc(sizeof(char *) * 2);
+  /* length of the directories_paths array */
+  int count = 0;
+  /* allocated size of the directories_paths array */
+  int t_size = 2;
+
+
+  int i;
+
+  struct stat stat_result;
+  int gui_directories_count;
+  char **gui_directories;
+
+  char *directory_tokens[strlen(DEFAULT_DATA_PATH)];
+  int num_tokens;
+
+  /* Directories are separated with : or ; */
+  num_tokens = get_tokens(DEFAULT_DATA_PATH,
+                          directory_tokens,
+                         strlen(DEFAULT_DATA_PATH),
+                         ":;");
+  
+  for (i = 0; i < num_tokens; i++) {
+    char buf[strlen(DEFAULT_DATA_PATH) + 16];
+
+    /* Check if there's 'themes' subdirectory */
+    my_snprintf(buf, sizeof(buf), "%s/themes", directory_tokens[i]);
+    
+    free(directory_tokens[i]);
+    
+    if (stat(buf, &stat_result) != 0) {
+      continue;
+    }
+    if (!S_ISDIR(stat_result.st_mode)) {
+      continue;
+    }
+
+    /* Increase array size if needed */
+    if (t_size == count) {
+      directories_paths =
+         fc_realloc(directories_paths, t_size * 2 * sizeof(char *));
+      t_size *= 2;
+    }
+
+    directories_paths[count] = mystrdup(buf);
+    count++;
+  }
+
+  /* Add gui specific directories */
+  gui_directories =
+      get_gui_specific_themes_directories(&gui_directories_count);
+
+  for (i = 0; i < gui_directories_count; i++) {
+    if (t_size == count) {
+      directories_paths =
+         fc_realloc(directories_paths, t_size * 2 * sizeof(char *));
+      t_size *= 2;
+    }
+    /* We are responsible for freeing the memory, so we don't need to copy */
+    directories_paths[count++] = gui_directories[i];
+  }
+  free(gui_directories);
+
+  /* Load useable themes in those directories */
+  directories = fc_malloc(sizeof(struct theme_directory) * count);
+  for (i = 0; i < count; i++) {
+    directories[i].path = directories_paths[i];
+
+    /* Gui specific function must search for themes */
+    directories[i].themes =
+       get_useable_themes_in_directory(directories_paths[i],
+                                       &(directories[i].num_themes));
+  }
+  num_directories = count;
+  free(directories_paths);
+}
+
+/****************************************************************************
+  Return an array of useable theme names. The array is NULL terminated and 
+  the caller is responsible for freeing the array.
+****************************************************************************/
+const char **get_themes_list(void)
+{
+  int size = 0;
+  int i, j, k, c;
+  const char **themes;
+
+  for (i = 0; i < num_directories; i++) {
+    size += directories[i].num_themes;
+  }
+
+  themes = fc_malloc(sizeof(char *) * (size + 1));
+
+  /* Copy theme names from all directories, but remove duplicates */
+  c = 0;
+  for (i = 0; i < num_directories; i++) {
+    for (j = 0; j < directories[i].num_themes; j++) {
+      for (k = 0; k < c; k++) {
+       if (strcmp(themes[k], directories[i].themes[j]) == 0) {
+         break;
+       }
+      }
+      if (k == c) {
+       themes[c++] = directories[i].themes[j];
+      }
+    }
+  }
+  themes[c] = NULL;
+  return themes;
+}
+
+/****************************************************************************
+  Loads a theme with the given name. First matching directory will be used.
+****************************************************************************/
+void load_theme(const char *theme_name)
+{
+  int i, j;
+  for (i = 0; i < num_directories; i++) {
+    for (j = 0; j < directories[i].num_themes; j++) {
+      if (strcmp(theme_name, directories[i].themes[j]) == 0) {
+       gui_load_theme(directories[i].path, directories[i].themes[j]);
+       return;
+      }
+    }
+  }
+}
diff -urN -Xfreeciv/diff_ignore freeciv/client/themes_common.h 
themes/client/themes_common.h
--- freeciv/client/themes_common.h      1970-01-01 01:00:00.000000000 +0100
+++ themes/client/themes_common.h       2005-08-20 11:10:46.000000000 +0200
@@ -0,0 +1,20 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 2005 The Freeciv Team
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+#ifndef FC__THEMES_COMMON_H
+#define FC__THEMES_COMMON_H
+#include "options.h"
+
+void init_themes(void);
+const char** get_themes_list(void);
+void load_theme(const char* theme_name);
+#endif

[Prev in Thread] Current Thread [Next in Thread]