Mercurial > pidgin
annotate src/themes.c @ 4891:cfa045006bec
[gaim-migrate @ 5221]
this saves the blist.xml file to an alternate name, and then moves it, that
way we don't lose your precious buddies if gaim crashes.
Of course, if gaim were to crash, it wouldn't be gaim's fault, it would be
the fault of some external force. This is because gaim is perfect, and
Sean is perfect. Yeah.
This should be done for .gaimrc too, but i'm too tired to do that right now.
committer: Tailor Script <tailor@pidgin.im>
| author | Nathan Walp <nwalp@pidgin.im> |
|---|---|
| date | Tue, 25 Mar 2003 06:35:45 +0000 |
| parents | 94e75b03c598 |
| children | dc6de8ad81ae |
| rev | line source |
|---|---|
| 4263 | 1 /* |
| 2 * Themes for Gaim | |
| 3 * | |
| 4 * Copyright (C) 2003, Sean Egan <bj91704@binghamton.edu> | |
| 5 * | |
| 6 * This program is free software; you can redistribute it and/or modify | |
| 7 * it under the terms of the GNU General Public License as published by | |
| 8 * the Free Software Foundation; either version 2 of the License, or | |
| 9 * (at your option) any later version. | |
| 10 * | |
| 11 * This program is distributed in the hope that it will be useful, | |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 * GNU General Public License for more details. | |
| 15 * | |
| 16 * You should have received a copy of the GNU General Public License | |
| 17 * along with this program; if not, write to the Free Software | |
| 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 19 * | |
| 20 */ | |
| 21 | |
| 4288 | 22 #include "gaim.h" |
| 23 #include "ui.h" | |
| 4263 | 24 #include "gtkimhtml.h" |
| 4667 | 25 #include "prpl.h" |
| 4263 | 26 #include <stdio.h> |
| 4298 | 27 #include <string.h> |
| 28 #include <ctype.h> | |
| 4341 | 29 #include <sys/stat.h> |
| 4263 | 30 |
|
4321
1cfad48b7d93
[gaim-migrate @ 4576]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4301
diff
changeset
|
31 #ifdef _WIN32 |
|
1cfad48b7d93
[gaim-migrate @ 4576]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4301
diff
changeset
|
32 #include "win32dep.h" |
|
1cfad48b7d93
[gaim-migrate @ 4576]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4301
diff
changeset
|
33 #endif |
|
1cfad48b7d93
[gaim-migrate @ 4576]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4301
diff
changeset
|
34 |
| 4263 | 35 struct smiley_list { |
| 36 char *sml; | |
| 37 GSList *smileys; | |
| 38 struct smiley_list *next; | |
| 39 }; | |
| 40 | |
| 41 GSList *smiley_themes; | |
| 4288 | 42 struct smiley_theme *current_smiley_theme; |
| 4263 | 43 |
| 44 void smiley_themeize(GtkWidget *imhtml) | |
| 45 { | |
| 46 struct smiley_list *list; | |
| 47 if (!current_smiley_theme) | |
| 48 return; | |
| 49 | |
| 50 gtk_imhtml_remove_smileys(GTK_IMHTML(imhtml)); | |
| 51 list = current_smiley_theme->list; | |
| 52 while (list) { | |
| 53 char *sml = !strcmp(list->sml, "default") ? NULL : list->sml; | |
| 54 GSList *icons = list->smileys; | |
| 55 while (icons) { | |
| 56 gtk_imhtml_associate_smiley(GTK_IMHTML(imhtml), sml, icons->data); | |
| 57 icons = icons->next; | |
| 58 } | |
| 59 list = list->next; | |
| 60 } | |
| 61 } | |
| 62 | |
| 4298 | 63 struct smiley_theme *load_smiley_theme(const char *file, gboolean load) |
| 4263 | 64 { |
| 65 FILE *f = fopen(file, "r"); | |
| 66 char buf[256]; | |
| 67 char *i; | |
| 68 struct smiley_theme *theme=NULL; | |
| 69 struct smiley_list *list = NULL; | |
| 70 GSList *lst = smiley_themes; | |
| 71 char *dirname; | |
| 4323 | 72 gboolean old=FALSE; |
| 4630 | 73 |
| 4263 | 74 while (lst) { |
| 75 struct smiley_theme *thm = lst->data; | |
| 4288 | 76 if (!strcmp(thm->path, file)) { |
| 4263 | 77 theme = thm; |
| 4323 | 78 old = TRUE; |
| 4263 | 79 break; |
| 80 } | |
| 81 lst = lst->next; | |
| 82 } | |
| 4630 | 83 |
| 84 if (!f) | |
| 85 return NULL; | |
| 4263 | 86 if (!theme) { |
| 87 theme = g_new0(struct smiley_theme, 1); | |
| 4288 | 88 theme->path = g_strdup(file); |
| 4263 | 89 } |
| 4630 | 90 |
| 4263 | 91 dirname = g_path_get_dirname(file); |
| 92 if (load) { | |
| 93 if (current_smiley_theme) { | |
| 4288 | 94 GSList *already_freed = NULL; |
| 4263 | 95 struct smiley_list *wer = current_smiley_theme->list; |
| 96 while (wer) { | |
| 4288 | 97 GSList *already_freed = NULL; |
| 98 while (wer->smileys) { | |
| 99 GtkIMHtmlSmiley *uio = wer->smileys->data; | |
| 4263 | 100 if (uio->icon) |
| 101 g_object_unref(uio->icon); | |
| 4288 | 102 if (!g_slist_find(already_freed, uio->file)) { |
| 103 g_free(uio->file); | |
| 104 already_freed = g_slist_append(already_freed, uio->file); | |
| 105 } | |
| 4263 | 106 g_free(uio->smile); |
| 4288 | 107 g_free(uio); |
| 108 wer->smileys=g_slist_remove(wer->smileys, uio); | |
| 4263 | 109 } |
| 110 wer = wer->next; | |
| 111 } | |
| 4288 | 112 current_smiley_theme->list = NULL; |
| 113 g_slist_free(already_freed); | |
| 4263 | 114 } |
| 4288 | 115 current_smiley_theme = theme; |
| 4263 | 116 } |
| 4816 | 117 |
| 118 | |
| 4263 | 119 while (!feof(f)) { |
| 120 if (!fgets(buf, sizeof(buf), f)) { | |
| 4288 | 121 break; |
| 4263 | 122 } |
| 4630 | 123 |
| 124 if (buf[0] == '#' || buf[0] == '\0') | |
| 4263 | 125 continue; |
| 4630 | 126 |
| 4263 | 127 i = buf; |
| 128 while (isspace(*i)) | |
| 129 i++; | |
| 4630 | 130 |
| 4816 | 131 if (*i == '[' && strchr(i, ']') && load) { |
| 4263 | 132 struct smiley_list *child = g_new0(struct smiley_list, 1); |
| 4816 | 133 child->sml = g_strndup(i+1, (int)strchr(i, ']') - (int)i - 1); |
| 134 if (theme->list) | |
| 4263 | 135 list->next = child; |
| 136 else | |
| 137 theme->list = child; | |
| 138 list = child; | |
| 4816 | 139 } else if (!g_ascii_strncasecmp(i, "Name=", strlen("Name="))) { |
| 140 theme->name = g_strdup(i+ strlen("Name=")); | |
| 141 theme->name[strlen(theme->name)-1] = 0; | |
| 142 } else if (!g_ascii_strncasecmp(i, "Description=", strlen("Description="))) { | |
| 143 theme->desc = g_strdup(i + strlen("Description=")); | |
| 144 theme->desc[strlen(theme->desc)-1] = 0; | |
| 145 } else if (!g_ascii_strncasecmp(i, "Icon=", strlen("Icon="))) { | |
| 146 theme->icon = g_build_filename(dirname, i + strlen("Icon="), NULL); | |
| 147 theme->icon[strlen(theme->icon)-1] = 0; | |
| 148 } else if (!g_ascii_strncasecmp(i, "Author=", strlen("Author="))) { | |
| 149 theme->author = g_strdup(i + strlen("Author=")); | |
| 150 theme->author[strlen(theme->author)-1] = 0; | |
| 151 } else if (load && list) { | |
| 4667 | 152 gboolean hidden = FALSE; |
| 4288 | 153 char *sfile = NULL; |
| 4630 | 154 |
| 4266 | 155 if (*i == '!' && *(i + 1) == ' ') { |
| 4263 | 156 hidden = TRUE; |
| 157 i = i + 2; | |
| 158 } | |
| 159 while (*i) { | |
| 160 char l[64]; | |
| 161 int li = 0; | |
| 4630 | 162 while (!isspace(*i)) |
| 4263 | 163 l[li++] = *(i++); |
| 4288 | 164 if (!sfile) { |
| 4263 | 165 l[li] = 0; |
| 4288 | 166 sfile = g_build_filename(dirname, l, NULL); |
| 4263 | 167 } else { |
| 4632 | 168 GtkIMHtmlSmiley *smiley = g_new0(GtkIMHtmlSmiley, 1); |
| 4263 | 169 l[li] = 0; |
| 4288 | 170 smiley->file = sfile; |
| 4263 | 171 smiley->smile = g_strdup(l); |
| 4667 | 172 smiley->hidden = hidden; |
| 4263 | 173 list->smileys = g_slist_append(list->smileys, smiley); |
| 174 } | |
| 4630 | 175 while (isspace(*i)) |
| 4263 | 176 i++; |
| 4630 | 177 |
| 4263 | 178 } |
| 179 } | |
| 180 } | |
| 4288 | 181 |
| 182 if (load) { | |
|
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4341
diff
changeset
|
183 GList *cnv; |
| 4630 | 184 |
|
4375
90eaa3486949
[gaim-migrate @ 4641]
Christian Hammond <chipx86@chipx86.com>
parents:
4359
diff
changeset
|
185 for (cnv = gaim_get_conversations(); cnv != NULL; cnv = cnv->next) { |
|
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4341
diff
changeset
|
186 struct gaim_conversation *conv = cnv->data; |
| 4630 | 187 |
|
4398
a8249a5250b6
[gaim-migrate @ 4667]
Christian Hammond <chipx86@chipx86.com>
parents:
4375
diff
changeset
|
188 if (GAIM_IS_GTK_CONVERSATION(conv)) |
|
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4341
diff
changeset
|
189 smiley_themeize(GAIM_GTK_CONVERSATION(conv)->imhtml); |
|
4338
6c1230d15958
[gaim-migrate @ 4602]
Christian Hammond <chipx86@chipx86.com>
parents:
4323
diff
changeset
|
190 } |
| 4288 | 191 } |
| 192 | |
| 4263 | 193 g_free(dirname); |
| 4323 | 194 return old ? NULL : theme; |
| 4263 | 195 } |
| 196 | |
| 197 void smiley_theme_probe() | |
| 198 { | |
| 199 GDir *dir; | |
| 200 const gchar *file; | |
| 201 gchar *path; | |
| 202 struct smiley_theme *smile; | |
| 203 int l; | |
| 204 | |
| 205 char* probedirs[3]; | |
| 206 probedirs[0] = g_build_filename(DATADIR, "pixmaps", "gaim", "smileys", NULL); | |
| 207 probedirs[1] = g_build_filename(gaim_user_dir(), "smileys", NULL); | |
| 208 probedirs[2] = 0; | |
| 209 for (l=0; probedirs[l]; l++) { | |
| 210 dir = g_dir_open(probedirs[l], 0, NULL); | |
| 211 if (dir) { | |
| 212 while ((file = g_dir_read_name(dir))) { | |
| 4301 | 213 path = g_build_filename(probedirs[l], file, "theme", NULL); |
| 4263 | 214 |
| 215 /* Here we check to see that the theme has proper syntax. | |
| 216 * We set the second argument to FALSE so that it doesn't load | |
| 217 * the theme yet. | |
| 218 */ | |
| 4298 | 219 if ((smile = load_smiley_theme(path, FALSE))) { |
| 4263 | 220 smiley_themes = g_slist_append(smiley_themes, smile); |
| 221 } | |
| 222 g_free(path); | |
| 223 } | |
| 224 g_dir_close(dir); | |
| 4341 | 225 } else if (l == 1) { |
| 226 mkdir(probedirs[l], S_IRUSR | S_IWUSR | S_IXUSR); | |
| 227 } | |
| 4263 | 228 g_free(probedirs[l]); |
| 229 } | |
| 230 } | |
| 4667 | 231 |
| 232 GSList *get_proto_smileys(int protocol) { | |
| 233 struct prpl *proto = find_prpl(protocol); | |
| 234 struct smiley_list *list, *def; | |
| 235 | |
| 236 if(!current_smiley_theme) | |
| 237 return NULL; | |
| 238 | |
| 239 def = list = current_smiley_theme->list; | |
| 240 | |
| 241 while(list) { | |
| 242 if(!strcmp(list->sml, "default")) | |
| 243 def = list; | |
| 244 else if(proto && !strcmp(proto->name, list->sml)) | |
| 245 break; | |
| 246 | |
| 247 list = list->next; | |
| 248 } | |
| 249 | |
| 250 return list ? list->smileys : def->smileys; | |
| 251 } |
