14 static gzFile gzf = NULL;
16 #define gtk_msg(type, args...) \
19 msgw = gtk_message_dialog_new(GTK_WINDOW(mainwin), \
20 GTK_DIALOG_DESTROY_WITH_PARENT | \
25 gtk_dialog_run(GTK_DIALOG(msgw)); \
26 gtk_widget_destroy(msgw); \
29 static int gzopen_frontend(const char *path, int oflags, int mode);
30 static int gzclose_frontend(int nothing);
31 static ssize_t gzread_frontend(int nothing, void *buf, size_t s);
32 static ssize_t gzwrite_frontend(int nothing, const void *buf, size_t s);
33 static gchar *get_theme_dir();
34 static gboolean change_dir(const gchar *dir);
35 static gboolean install_theme_to(gchar *theme, gchar *file, gchar *to);
36 static gchar* name_from_file(const gchar *path);
37 static gchar* name_from_dir(const gchar *dir);
38 static gboolean create_theme_archive(gchar *dir, gchar *name, gchar *to);
41 (openfunc_t) gzopen_frontend,
42 (closefunc_t) gzclose_frontend,
43 (readfunc_t) gzread_frontend,
44 (writefunc_t) gzwrite_frontend
47 gchar* theme_install(gchar *path)
53 if (!(dest = get_theme_dir()))
56 curdir = g_get_current_dir();
57 if (!change_dir(dest)) {
62 if (!(name = name_from_file(path)))
65 if (install_theme_to(name, path, dest)) {
66 gtk_msg(GTK_MESSAGE_INFO, _("\"%s\" was installed to %s"), name, dest);
80 void theme_archive(gchar *path)
85 if (!(name = name_from_dir(path)))
90 file = g_strdup_printf("%s.obt", name);
91 dest = g_build_path(G_DIR_SEPARATOR_S,
92 g_get_current_dir(), file, NULL);
96 if (create_theme_archive(path, name, dest))
97 gtk_msg(GTK_MESSAGE_INFO, _("\"%s\" was successfully created"),
104 static gboolean create_theme_archive(gchar *dir, gchar *name, gchar *to)
109 if (tar_open(&t, to, &funcs, O_WRONLY | O_CREAT, 0666, TAR_GNU) == -1) {
110 gtk_msg(GTK_MESSAGE_ERROR,
111 _("Unable to create the file \"%s\": %s"),
112 to, strerror(errno));
116 r = tar_append_tree(t, dir, name);
120 gtk_msg(GTK_MESSAGE_ERROR,
121 _("Unable to create the theme archive \"%s\": %s"),
122 to, strerror(errno));
128 static gchar *get_theme_dir()
133 dir = g_build_path(G_DIR_SEPARATOR_S, g_get_home_dir(), ".themes", NULL);
134 r = mkdir(dir, 0777);
135 if (r == -1 && errno != EEXIST) {
136 gtk_msg(GTK_MESSAGE_ERROR,
137 _("Unable to create directory \"%s\": %s"),
138 dir, strerror(errno));
146 static gchar* name_from_dir(const gchar *dir)
152 rc = g_build_path(G_DIR_SEPARATOR_S, dir, "openbox-3", "themerc", NULL);
154 r = (stat(rc, &st) == 0 && S_ISREG(st.st_mode));
158 gtk_msg(GTK_MESSAGE_ERROR,
159 _("\"%s\" does not appear to be a valid Openbox theme directory"),
163 return g_path_get_basename(dir);
166 static gchar* name_from_file(const gchar *path)
168 /* decipher the theme name from the file name */
169 gchar *fname = g_path_get_basename(path);
170 gint len = strlen(fname);
174 (fname[len-4] == '.' && fname[len-3] == 'o' &&
175 fname[len-2] == 'b' && fname[len-1] == 't'))
178 name = g_strdup(fname);
183 gtk_msg(GTK_MESSAGE_ERROR,
184 _("Unable to determine the theme's name from \"%s\". File name should be ThemeName.obt."), fname);
189 static gboolean change_dir(const gchar *dir)
191 if (chdir(dir) == -1) {
192 gtk_msg(GTK_MESSAGE_ERROR, _("Unable to move to directory \"%s\": %s"),
193 dir, strerror(errno));
199 static gboolean install_theme_to(gchar *theme, gchar *file, gchar *to)
205 if (tar_open(&t, file, &funcs, O_RDONLY, 0666, TAR_GNU) == -1) {
206 gtk_msg(GTK_MESSAGE_ERROR,
207 _("Unable to open the file \"%s\": %s"),
208 file, strerror(errno));
212 glob = g_strdup_printf("%s/openbox-3/*", theme);
213 r = tar_extract_glob(t, glob, to);
219 gtk_msg(GTK_MESSAGE_ERROR,
220 _("Unable to extract the file \"%s\".\nPlease ensure that \"%s\" is writable and that the file is a valid Openbox theme archive"),
221 file, strerror(errno));
226 static int gzopen_frontend(const char *path, int oflags, int mode)
231 if ((oflags & O_ACCMODE) == O_RDONLY)
233 else if ((oflags & O_ACCMODE) == O_WRONLY)
236 g_assert_not_reached();
238 if ((fd = open(path, oflags, mode)) < 0) return -1;
239 if (!(gzf = gzdopen(fd, gzflags))) return -1;
243 static int gzclose_frontend(int nothing)
245 g_return_val_if_fail(gzf != NULL, 0);
249 static ssize_t gzread_frontend(int nothing, void *buf, size_t s)
251 return gzread(gzf, buf, s);
254 static ssize_t gzwrite_frontend(int nothing, const void *buf, size_t s)
256 return gzwrite(gzf, buf, s);