1 /*
2 * Copyright (c) 2005 Sasha Vasko <sasha at aftercode.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 */
19
20
21 /* #define LOCAL_DEBUG */
22 /*#define DO_CLOCKING */
23
24 #include "../configure.h"
25
26 #include <unistd.h>
27
28 #include "../libAfterStep/asapp.h"
29 #include "../libAfterStep/afterstep.h"
30 #include "../libAfterStep/session.h"
31 #include "../libAfterStep/desktop_category.h"
32
33 #include "afterconf.h"
34
35 const char *default_aliases[][2] = {
36 {"ArcadeGame", "Arcade"},
37 {"Application", "Applications"},
38 {"Game", "Games"},
39 {"Utility", "Utilities"},
40 {NULL, NULL}
41
42 };
43
44
45 /*************************************************************************/
46 /* private stuff : */
47 /*************************************************************************/
48 #if 0
49 static char **parse_category_list (char *list, int *pnum_return)
50 {
51 char **shortcuts = NULL;
52 int num = 0;
53
54 if (list) {
55 int i;
56
57 for (i = 0; list[i]; ++i)
58 if (list[i] == ';')
59 ++num;
60 if (i > 0 && list[i - 1] != ';')
61 ++num;
62 if (num > 0) {
63 int sc_i = 0;
64
65 shortcuts = safecalloc (num + 1, sizeof (char *));
66
67 shortcuts[sc_i++] = &list[0];
68 for (i = 0; list[i]; ++i)
69 if (list[i] == ';') {
70 list[i++] = '\0';
71 if (list[i] == '\0' || sc_i >= num)
72 break;
73 shortcuts[sc_i++] = &list[i];
74 }
75 }
76 }
77 if (pnum_return)
78 *pnum_return = num;
79 return shortcuts;
80 }
81 #endif
82
filter_desktop_entry_exec(const char * exec)83 static char *filter_desktop_entry_exec (const char *exec)
84 {
85 char *clean_exec = mystrdup (exec);
86 int start = 0, ts;
87
88 while (clean_exec[start] != '\0' && !isspace (clean_exec[start]))
89 ++start;
90 while (clean_exec[start] != '\0') {
91 ts = start;
92 while (isspace (clean_exec[ts]))
93 ++ts;
94 if (clean_exec[ts] == '%' && isalpha (clean_exec[ts + 1])) {
95 while (!isspace (clean_exec[ts]) && clean_exec[ts] != '\0') {
96 clean_exec[ts] = ' ';
97 ++ts;
98 }
99 start = ts;
100 } else if (mystrncasecmp (&clean_exec[ts], "-caption ", 9) == 0) {
101 ts += 9;
102 while (isspace (clean_exec[ts]))
103 ++ts;
104 if (mystrncasecmp (&clean_exec[ts], "\"%c\"", 4) == 0) {
105 ts += 3;
106 while (start < ts)
107 clean_exec[++start] = ' ';
108 } else if (clean_exec[ts] == '%' && isalpha (clean_exec[ts + 1])) {
109 ts += 1;
110 while (start < ts)
111 clean_exec[++start] = ' ';
112 }
113 } else if (clean_exec[ts] == '\"') {
114 char *end = find_doublequotes (&clean_exec[ts]);
115
116 if (end != NULL)
117 start = end - &clean_exec[0];
118 else
119 start = ts;
120 ++start;
121 } else
122 for (start = ts;
123 !isspace (clean_exec[start]) && clean_exec[start] != '\0';
124 ++start) ;
125 }
126 while (isspace (clean_exec[start - 1])) {
127 --start;
128 clean_exec[start] = '\0';
129 }
130 return clean_exec;
131 }
132
stripcpy_localized(char * ptr)133 char *stripcpy_localized (char *ptr)
134 {
135 int i = 0;
136 static char default_locale[] = "us";
137 char *locale = MyArgs.locale[0] ? MyArgs.locale : &default_locale[0];
138
139 while (locale[i] != '.' && locale[i] != '\0' && ptr[i] != ']') {
140 if (ptr[i] != locale[i])
141 break;
142 ++i;
143 }
144 if ((locale[i] == '.' || locale[i] == '_' || locale[i] == '\0')
145 && ptr[i] == ']')
146 return stripcpy (ptr + i + 2);
147 return NULL;
148 }
149
parse_desktop_entry_line(ASDesktopEntry * de,char * ptr)150 static void parse_desktop_entry_line (ASDesktopEntry * de, char *ptr)
151 {
152 #define PARSE_ASDE_TYPE_VAL(val) if(mystrncasecmp(ptr, #val, ASDE_KEYWORD_##val##_LEN) == 0){de->type = ASDE_Type##val; return;}
153 #define PARSE_ASDE_STRING_VAL(val) if(mystrncasecmp(ptr, #val "=", ASDE_KEYWORD_##val##_LEN+1) == 0){if( de->val ) free( de->val ) ; de->val = stripcpy(ptr+ASDE_KEYWORD_##val##_LEN+1); return;}
154 #define PARSE_ASDE_FLAG_VAL(val) if(mystrncasecmp(ptr, #val "=", ASDE_KEYWORD_##val##_LEN+1) == 0){char *tmp = stripcpy(ptr+ASDE_KEYWORD_##val##_LEN+1); if( tmp[0] == '1' || mystrcasecmp(tmp, "true") == 0 ) set_flags(de->flags, ASDE_##val); free(tmp); return;}
155
156 if (ptr[0] == 'X' && ptr[1] == '-') {
157 ptr += 2;
158 if (mystrncasecmp (ptr, "AfterStep-", 10) == 0) {
159 ptr += 10;
160 PARSE_ASDE_STRING_VAL (IndexName)
161 PARSE_ASDE_STRING_VAL (Aliases)
162 PARSE_ASDE_FLAG_VAL (ASModule)
163 PARSE_ASDE_FLAG_VAL (CheckAvailability)} else
164 if (mystrncasecmp (ptr, "KDE-", 4) == 0)
165 set_flags (de->flags, ASDE_KDE);
166 else if (mystrncasecmp (ptr, "GNOME-", 6) == 0)
167 set_flags (de->flags, ASDE_GNOME);
168 } else if (mystrncasecmp (ptr, "Name[", 5) == 0
169 && MyArgs.locale[0] == ptr[5]) {
170 char *val = stripcpy_localized (ptr + 5);
171
172 if (val)
173 set_string (&(de->Name_localized), val);
174 } else if (mystrncasecmp (ptr, "Type=", 5) == 0) {
175 ptr += 5;
176
177 PARSE_ASDE_TYPE_VAL (Application)
178 PARSE_ASDE_TYPE_VAL (Link)
179 PARSE_ASDE_TYPE_VAL (FSDevice)
180 PARSE_ASDE_TYPE_VAL (Directory)} else
181 if (mystrncasecmp (ptr, "Comment[", 8) == 0
182 && MyArgs.locale[0] == ptr[8]) {
183 char *val = stripcpy_localized (ptr + 8);
184
185 if (val)
186 set_string (&(de->Comment_localized), val);
187 } else if (mystrncasecmp (ptr, "Encoding=", 9) == 0
188 && mystrncasecmp (ptr + 9, "UTF-8", 5) != 0) {
189 set_flags (de->flags, ASDE_EncodingNonUTF8);
190 } else {
191 PARSE_ASDE_STRING_VAL (Name)
192 PARSE_ASDE_STRING_VAL (GenericName)
193 PARSE_ASDE_STRING_VAL (Comment)
194 PARSE_ASDE_STRING_VAL (Icon)
195 PARSE_ASDE_STRING_VAL (TryExec)
196 PARSE_ASDE_STRING_VAL (Exec)
197 PARSE_ASDE_STRING_VAL (Path)
198 PARSE_ASDE_STRING_VAL (SwallowTitle)
199 PARSE_ASDE_STRING_VAL (SwallowExec)
200 PARSE_ASDE_STRING_VAL (SortOrder)
201 PARSE_ASDE_STRING_VAL (Categories)
202 PARSE_ASDE_STRING_VAL (OnlyShowIn)
203 PARSE_ASDE_STRING_VAL (NotShowIn)
204 PARSE_ASDE_STRING_VAL (StartupWMClass)
205 PARSE_ASDE_FLAG_VAL (NoDisplay)
206 PARSE_ASDE_FLAG_VAL (Hidden) PARSE_ASDE_FLAG_VAL (Terminal)
207 PARSE_ASDE_FLAG_VAL (StartupNotify)}
208 }
209
210 static void
fix_desktop_entry(ASDesktopEntry * de,const char * default_category,const char * icon_path,const char * origin,Bool applnk)211 fix_desktop_entry (ASDesktopEntry * de, const char *default_category,
212 const char *icon_path, const char *origin, Bool applnk)
213 {
214 if (de->Categories == NULL && default_category) {
215 if (get_flags (de->flags, ASDE_KDE | ASDE_GNOME) == 0) {
216 if (mystrncasecmp (default_category, "KDE", 3) == 0)
217 set_flags (de->flags, ASDE_KDE);
218 else if (mystrncasecmp (default_category, "GNOME", 5) == 0)
219 set_flags (de->flags, ASDE_GNOME);
220 }
221 if (de->type != ASDE_TypeDirectory)
222 de->Categories = mystrdup (default_category);
223 }
224 if (applnk)
225 set_flags (de->flags, ASDE_KDE);
226
227 if (de->Categories != NULL) {
228 de->categories_len = strlen (de->Categories);
229 de->categories_shortcuts =
230 compound_string2string_list (de->Categories, ';', False,
231 &(de->categories_num));
232 if (get_flags (de->flags, ASDE_KDE | ASDE_GNOME) == 0) {
233 int i = de->categories_num;
234 ASFlagType kind = 0;
235
236 while (--i >= 0 && kind == 0) {
237 char *ptr = de->categories_shortcuts[i];
238
239 if (ptr[0] == 'X') {
240 if (ptr[1] != '-')
241 continue;
242 ptr += 2;
243 }
244 if (mystrncasecmp (ptr, "KDE", 3) == 0)
245 set_flags (kind, ASDE_KDE);
246 else if (mystrncasecmp (ptr, "GNOME", 5) == 0)
247 set_flags (kind, ASDE_GNOME);
248 }
249 set_flags (de->flags, kind);
250 }
251 }
252 if (get_flags (de->flags, ASDE_KDE | ASDE_GNOME) == 0 && de->Name) {
253 if (de->Name[0] == 'G')
254 set_flags (de->flags, ASDE_GNOME);
255 else if (de->Name[0] == 'K')
256 set_flags (de->flags, ASDE_KDE);
257 }
258 if (de->Aliases != NULL) {
259 de->aliases_len = strlen (de->Aliases);
260 de->aliases_shortcuts =
261 compound_string2string_list (de->Aliases, ';', False,
262 &(de->aliases_num));
263 }
264
265 if (de->OnlyShowIn != NULL) {
266 de->show_in_len = strlen (de->OnlyShowIn);
267 de->show_in_shortcuts =
268 compound_string2string_list (de->OnlyShowIn, ';', False,
269 &(de->show_in_num));
270 }
271 if (de->NotShowIn != NULL) {
272 de->not_show_in_len = strlen (de->NotShowIn);
273 de->not_show_in_shortcuts =
274 compound_string2string_list (de->NotShowIn, ';', False,
275 &(de->not_show_in_num));
276 }
277 if (de->Exec)
278 de->clean_exec = filter_desktop_entry_exec (de->Exec);
279
280 de->origin = mystrdup (origin);
281
282 if (get_flags (de->flags, ASDE_CheckAvailability)) {
283 if (!is_executable_in_path (de->clean_exec))
284 set_flags (de->flags, ASDE_Unavailable);
285 LOCAL_DEBUG_OUT
286 ("checking availability(clean_exec) for \"%s\" - %s available",
287 de->clean_exec,
288 (get_flags (de->flags, ASDE_Unavailable) ? "not" : ""));
289 } else if (de->TryExec != NULL) {
290 if (!is_executable_in_path (de->TryExec))
291 set_flags (de->flags, ASDE_Unavailable);
292 LOCAL_DEBUG_OUT
293 ("checking availability(TryExec) for \"%s\" - %s available",
294 de->clean_exec,
295 (get_flags (de->flags, ASDE_Unavailable) ? "not" : ""));
296 }
297
298 }
299
parse_desktop_entry(const char * fullfilename,const char * default_category,ASDesktopEntryTypes default_type,const char * icon_path,Bool applnk)300 static ASDesktopEntry *parse_desktop_entry (const char *fullfilename,
301 const char *default_category,
302 ASDesktopEntryTypes
303 default_type,
304 const char *icon_path,
305 Bool applnk)
306 {
307 ASDesktopEntry *de = NULL;
308 FILE *fp = NULL;
309
310 if (fullfilename)
311 fp = fopen (fullfilename, "r");
312
313 if (fp) {
314 static char rb[MAXLINELENGTH + 1];
315
316 de = create_desktop_entry (default_type);
317 while (fgets (&(rb[0]), MAXLINELENGTH, fp) != NULL)
318 parse_desktop_entry_line (de, &(rb[0]));
319 fix_desktop_entry (de, default_category, icon_path, fullfilename,
320 applnk);
321 fclose (fp);
322 }
323 return de;
324 }
325
326 int
parse_desktop_entry_list(const char * fullfilename,ASBiDirList * entry_list,const char * default_category,ASDesktopEntryTypes default_type,const char * icon_path,Bool applnk)327 parse_desktop_entry_list (const char *fullfilename,
328 ASBiDirList * entry_list,
329 const char *default_category,
330 ASDesktopEntryTypes default_type,
331 const char *icon_path, Bool applnk)
332 {
333 ASDesktopEntry *de = NULL;
334 int count = 0;
335 FILE *fp = NULL;
336
337 /*LOCAL_DEBUG_OUT( "PARSING \"%s\"", fullfilename ); */
338 if (fullfilename)
339 fp = fopen (fullfilename, "r");
340
341 if (fp) {
342 static char rb[MAXLINELENGTH + 1];
343
344 while (fgets (&(rb[0]), MAXLINELENGTH, fp) != NULL) {
345 /*LOCAL_DEBUG_OUT( "rb = \"%s\", de = %p", &(rb[0]), de ); */
346 if (rb[0] == '[') {
347 if ((rb[1] == 'D'
348 && (mystrncasecmp (&(rb[2]), "esktop Entry]", 13) == 0
349 || mystrncasecmp (&(rb[2]), "esktopEntry]", 12) == 0))
350 || (rb[1] == 'K'
351 && mystrncasecmp (&(rb[2]), "DE Desktop Entry]",
352 17) == 0)) {
353 if (de) {
354 fix_desktop_entry (de, default_category, icon_path,
355 fullfilename, applnk);
356 append_bidirelem (entry_list, de);
357 }
358 de = create_desktop_entry (default_type);
359 ++count;
360 } else if (de) {
361 fix_desktop_entry (de, default_category, icon_path, fullfilename,
362 applnk);
363 append_bidirelem (entry_list, de);
364 de = NULL;
365 }
366 } else if (de)
367 parse_desktop_entry_line (de, &(rb[0]));
368 }
369 if (de) {
370 fix_desktop_entry (de, default_category, icon_path, fullfilename,
371 applnk);
372 append_bidirelem (entry_list, de);
373 }
374 fclose (fp);
375 }
376 return count;
377 }
378
379
380
381 static void
parse_desktop_entry_tree(char * fullpath,const char * dirname,ASBiDirList * entry_list,ASDesktopEntry * parent,const char * icon_path,const char * default_app_category,Bool applnk)382 parse_desktop_entry_tree (char *fullpath, const char *dirname,
383 ASBiDirList * entry_list,
384 ASDesktopEntry * parent, const char *icon_path,
385 const char *default_app_category, Bool applnk)
386 {
387 struct direntry **list = NULL;
388 int list_len, i, curr_dir_index = -1;
389 char *dir_category = NULL;
390 ASDesktopEntry *tmp, *curr_dir = NULL;
391
392
393 list_len = my_scandir (fullpath, &list, no_dots_except_directory, NULL);
394
395 fprintf (stderr, "number of items in %s = %d\n", fullpath, list_len);
396 for (i = 0; i < list_len; i++) {
397 if (!S_ISDIR (list[i]->d_mode) && list[i]->d_name[0] == '.') {
398 if (strcasecmp (list[i]->d_name, ".directory") == 0) {
399 curr_dir_index = i;
400 tmp =
401 parse_desktop_entry (fullpath, parent ? parent->Name : NULL,
402 ASDE_TypeDirectory, icon_path, applnk);
403 if (tmp) {
404 if (tmp->Name == NULL)
405 tmp->Name = mystrdup (dirname);
406 if (mystrcasecmp (tmp->Name, DEFAULT_DESKTOP_CATEGORY_NAME) != 0)
407 dir_category = mystrdup (tmp->Name);
408 curr_dir = tmp;
409 append_bidirelem (entry_list, tmp);
410 }
411 break;
412 }
413 }
414 }
415 if (curr_dir == NULL) {
416 curr_dir =
417 parse_desktop_entry (fullpath, parent ? parent->Name : NULL,
418 ASDE_TypeDirectory, icon_path, applnk);
419 if (curr_dir) {
420 if (curr_dir->Name == NULL) {
421 curr_dir->Name = mystrdup (dirname);
422 append_bidirelem (entry_list, curr_dir);
423 }
424 }
425 }
426 for (i = 0; i < list_len; i++) {
427 if (list[i]->d_name[0] != '.') {
428 char *entry_fullpath = make_file_name (fullpath, list[i]->d_name);
429
430 if (S_ISDIR (list[i]->d_mode)) {
431 /*fprintf(stderr, "Parsing subtree %s.\n", entry_fullpath);*/
432 parse_desktop_entry_tree (entry_fullpath, list[i]->d_name,
433 entry_list, curr_dir, icon_path,
434 default_app_category, applnk);
435 } else if (i != curr_dir_index) {
436 /*fprintf(stderr, "Parsing subitem %s.\n", entry_fullpath);*/
437 parse_desktop_entry_list (entry_fullpath, entry_list,
438 dir_category ? dir_category :
439 default_app_category,
440 ASDE_TypeApplication, icon_path, applnk);
441 }
442 free (entry_fullpath);
443 }
444 free (list[i]);
445 }
446
447 if (list)
448 free (list);
449
450 if (dir_category)
451 free (dir_category);
452 }
453
desktop_entry_destroy_list_item(void * data)454 static void desktop_entry_destroy_list_item (void *data)
455 {
456 unref_desktop_entry ((ASDesktopEntry *) data);
457 }
458
register_desktop_entry_list_item(void * data,void * aux_data)459 static Bool register_desktop_entry_list_item (void *data, void *aux_data)
460 {
461 register_desktop_entry ((ASCategoryTree *) aux_data,
462 (ASDesktopEntry *) data);
463 return True;
464 }
465
466 /*************************************************************************/
467 /* public methods : */
468 /*************************************************************************/
469
load_category_tree(ASCategoryTree * ct)470 Bool load_category_tree (ASCategoryTree * ct)
471 {
472 if (ct && ct->dir_list) {
473 int i;
474 ASBiDirList *entry_list =
475 create_asbidirlist (desktop_entry_destroy_list_item);
476
477 for (i = 0; i < ct->dir_num; ++i) {
478 Bool applnk = (strstr (ct->dir_list[i], "/applnk") != NULL);
479
480 if (CheckDir (ct->dir_list[i]) == 0) {
481 /* fprintf( stderr, "location : \"%s\", applnk == %d\n", ct->dir_list[i], applnk );
482 */
483 parse_desktop_entry_tree (ct->dir_list[i], NULL, entry_list, NULL,
484 ct->icon_path, ct->name, applnk);
485 } else if (CheckFile (ct->dir_list[i]) == 0)
486 parse_desktop_entry_list (ct->dir_list[i], entry_list, ct->name,
487 ASDE_TypeDirectory, ct->icon_path,
488 applnk);
489 }
490 LOCAL_DEBUG_OUT ("Done parsing for tree %s", ct->name);
491 iterate_asbidirlist (entry_list, register_desktop_entry_list_item, ct,
492 NULL, False);
493 destroy_asbidirlist (&entry_list);
494 /* flush_asbidirlist_memory_pool(); */
495 /* print_unfreed_mem (); */
496 return True;
497 }
498 return False;
499 }
500
DestroyCategories()501 void DestroyCategories ()
502 {
503 if (StandardCategories)
504 destroy_category_tree (&StandardCategories);
505 if (AfterStepCategories)
506 destroy_category_tree (&AfterStepCategories);
507 if (KDECategories)
508 destroy_category_tree (&KDECategories);
509 if (GNOMECategories)
510 destroy_category_tree (&GNOMECategories);
511 if (OtherCategories)
512 destroy_category_tree (&OtherCategories);
513 if (CombinedCategories)
514 destroy_category_tree (&CombinedCategories);
515 #ifdef DEBUG_ALLOCS
516 /* print_unfreed_mem (); */
517 #endif /* DEBUG_ALLOCS */
518 }
519
save_category_tree_cache(ASCategoryTree * ct,const char * fname)520 void save_category_tree_cache (ASCategoryTree * ct, const char *fname)
521 {
522 char *configfile;
523 FILE *fp;
524
525 configfile = make_session_data_file (Session, False, 0, fname, NULL);
526 if (configfile) {
527 fp = fopen (configfile, "wb");
528 if (fp) {
529 save_category_tree (ct, fp);
530 fclose (fp);
531 }
532 free (configfile);
533 }
534 }
535
UpdateCategoriesCache()536 void UpdateCategoriesCache ()
537 {
538 save_category_tree_cache (AfterStepCategories, AFTERSTEP_CACHE_FILE);
539 save_category_tree_cache (KDECategories, KDE_CACHE_FILE);
540 save_category_tree_cache (GNOMECategories, GNOME_CACHE_FILE);
541 save_category_tree_cache (OtherCategories, OTHER_CACHE_FILE);
542 }
543
ReloadCategories(Bool cached)544 void ReloadCategories (Bool cached)
545 {
546 char *configfile;
547
548 START_TIME (started);
549
550 DestroyCategories ();
551
552 if ((configfile =
553 make_session_file (Session, STANDARD_CATEGORIES_FILE,
554 False)) != NULL) {
555 StandardCategories =
556 create_category_tree ("Default", configfile,
557 Environment ? Environment->
558 pixmap_path : NULL, 0, -1);
559 free (configfile);
560 }
561
562 if (cached) {
563 char *configfile =
564 make_session_data_file (Session, False, 0, AFTERSTEP_CACHE_FILE,
565 NULL);
566
567 AfterStepCategories =
568 create_category_tree ("AfterStep", configfile,
569 Environment ? Environment->
570 pixmap_path : NULL, 0, -1);
571 free (configfile);
572 configfile =
573 make_session_data_file (Session, False, 0, KDE_CACHE_FILE, NULL);
574 KDECategories =
575 create_category_tree ("KDE", configfile, KDE_ICONS_PATH, 0, -1);
576 free (configfile);
577 configfile =
578 make_session_data_file (Session, False, 0, GNOME_CACHE_FILE, NULL);
579 GNOMECategories =
580 create_category_tree ("GNOME", configfile, GNOME_ICONS_PATH, 0,
581 -1);
582 free (configfile);
583 configfile =
584 make_session_data_file (Session, False, 0, OTHER_CACHE_FILE, NULL);
585 OtherCategories =
586 create_category_tree ("OTHER", configfile, OTHER_ICONS_PATH, 0,
587 -1);
588 free (configfile);
589 } else {
590 char *path = make_session_apps_path (Session);
591
592 if (path) {
593 AfterStepCategories =
594 create_category_tree ("AfterStep", path,
595 Environment ? Environment->
596 pixmap_path : NULL, 0, -1);
597 free (path);
598 }
599
600 KDECategories =
601 create_category_tree ("KDE", KDE_APPS_PATH, KDE_ICONS_PATH,
602 ASCT_OnlyKDE, -1);
603 GNOMECategories =
604 create_category_tree ("GNOME", GNOME_APPS_PATH, GNOME_ICONS_PATH,
605 ASCT_OnlyGNOME, -1);
606 OtherCategories =
607 create_category_tree ("OTHER", OTHER_APPS_PATH, OTHER_ICONS_PATH,
608 ASCT_ExcludeGNOME | ASCT_ExcludeKDE, -1);
609
610 }
611
612 CombinedCategories = create_category_tree ("", NULL, NULL, 0, -1);
613
614 load_category_tree (StandardCategories);
615 SHOW_TIME ("Standard categories", started);
616 if (!cached) {
617 add_category_tree_subtree (AfterStepCategories, StandardCategories);
618 add_category_tree_subtree (KDECategories, StandardCategories);
619 add_category_tree_subtree (GNOMECategories, StandardCategories);
620 add_category_tree_subtree (OtherCategories, StandardCategories);
621 }
622 load_category_tree (AfterStepCategories);
623 SHOW_TIME ("AfterStep categories", started);
624 load_category_tree (KDECategories);
625 SHOW_TIME ("KDE categories", started);
626 load_category_tree (GNOMECategories);
627 SHOW_TIME ("GNOME categories", started);
628 load_category_tree (OtherCategories);
629 SHOW_TIME ("Other categories", started);
630
631 LOCAL_DEBUG_OUT
632 ("@ Building up Combined: @@@@@@@@@@@@@@@@@@@@@@@@@@@@%s", "");
633
634 add_category_tree_subtree (CombinedCategories, StandardCategories);
635 add_category_tree_subtree (CombinedCategories, AfterStepCategories);
636 add_category_tree_subtree (CombinedCategories, KDECategories);
637 add_category_tree_subtree (CombinedCategories, GNOMECategories);
638 add_category_tree_subtree (CombinedCategories, OtherCategories);
639
640 SHOW_TIME (__FUNCTION__, started);
641 }
642
643
644 #ifdef PRINT_DESKTOP_ENTRIES
main(int argc,char ** argv)645 int main (int argc, char **argv)
646 {
647 int i;
648 ASDesktopCategory *dc = NULL;
649 ASCategoryTree *ct = NULL;
650 Bool cached = False;
651
652 InitMyApp ("PrintDesktopEntries", argc, argv, NULL, NULL, 0);
653 InitSession ();
654 for (i = 1; i < argc; ++i)
655 if (argv[i] && strcmp (argv[i], "--cached") == 0)
656 cached = True;
657
658 ReloadCategories (cached);
659
660 for (i = 1; i < argc; ++i)
661 if (argv[i] && strcmp (argv[i], "--cached") != 0) {
662 char *name = NULL;
663 char *colon = strchr (argv[i], ':');
664 int len = strlen (argv[i]);
665
666 if (colon == NULL) {
667 name = safemalloc (len + 1 + 7 + 1);
668 sprintf (name, "%s:Default", argv[i]);
669 } else if (colon[1] == '\0') {
670 name = safemalloc (len + 7 + 1);
671 sprintf (name, "%sDefault", argv[i]);
672 } else
673 name = mystrdup (argv[i]);
674
675 dc = name2desktop_category (name, &ct);
676 if (dc == NULL) {
677 fprintf (stderr, "Invalid category name \"%s\"", argv[i]);
678 return 0;
679 }
680 free (name);
681 break;
682 }
683 if (dc && ct) {
684 print_category_tree2 (ct, dc);
685
686 } else {
687 fprintf (stderr,
688 "#Standard: ####################################################\n");
689 print_category_tree2 (StandardCategories, NULL);
690 fprintf (stderr,
691 "#AfterStep:####################################################\n");
692 print_category_tree2 (AfterStepCategories, NULL);
693 fprintf (stderr,
694 "#KDE: ####################################################\n");
695 print_category_tree2 (KDECategories, NULL);
696 fprintf (stderr,
697 "#GNOME: ####################################################\n");
698 print_category_tree2 (GNOMECategories, NULL);
699 fprintf (stderr,
700 "#OTHER: ####################################################\n");
701 print_category_tree2 (OtherCategories, NULL);
702 fprintf (stderr,
703 "#Combined: ####################################################\n");
704 print_category_tree2 (CombinedCategories, NULL);
705 fprintf (stderr,
706 "#####################################################\n");
707 }
708 DestroyCategories ();
709 FreeMyAppResources ();
710 return 1;
711 }
712
713 #else
714 #ifdef TEST_AS_DESKTOP_ENTRY
715
716 #define REDHAT_APPLNK "/etc/X11/applnk"
717 #define DEBIAN_APPLNK "/usr/share/applications"
718
719 /*
720 * From e-mail :
721 * The paths to the directories should be given by the DESKTOP_FILE_PATH
722 * enviromental variable if other directories then /usr/share/applications/ are
723 * needed. This environment variable has the same format as the PATH
724 * evironment variable, ':'separating entries. If DESKTOP_FILE_PATH is present,
725 * /usr/share/applications is not checked by default, and thus shoul dbe included
726 * in the path.
727 *
728 * see: https://listman.redhat.com/archives/xdg-list/2002-July/msg00049.html
729 * http://standards.freedesktop.org/menu-spec/menu-spec-0.9.html#paths
730 * http://www.freedesktop.org/Standards/desktop-entry-spec
731 */
732
main(int argc,char ** argv)733 int main (int argc, char **argv)
734 {
735
736
737 // ASBiDirList *entry_list = create_asbidirlist( desktop_entry_destroy_list_item );
738
739 InitMyApp ("TestASDesktopEntry", argc, argv, NULL, NULL, 0);
740 InitSession ();
741 ReloadCategories (False);
742 // ReloadCategories();
743 // ReloadCategories();
744
745 fprintf (stderr,
746 "#Standard: ####################################################\n");
747 print_category_tree2 (StandardCategories, NULL);
748 fprintf (stderr,
749 "#AfterStep: ####################################################\n");
750 print_category_tree2 (AfterStepCategories, NULL);
751 fprintf (stderr,
752 "#KDE: ####################################################\n");
753 print_category_tree2 (KDECategories, NULL);
754 fprintf (stderr,
755 "#GNOME: ####################################################\n");
756 print_category_tree2 (GNOMECategories, NULL);
757 fprintf (stderr,
758 "#OTHER: ####################################################\n");
759 print_category_tree2 (OtherCategories, NULL);
760 fprintf (stderr,
761 "#Combined: ####################################################\n");
762 print_category_tree2 (CombinedCategories, NULL);
763 fprintf (stderr,
764 "#####################################################\n");
765
766 DestroyCategories ();
767 FreeMyAppResources ();
768 #ifdef DEBUG_ALLOCS
769 print_unfreed_mem ();
770 #endif /* DEBUG_ALLOCS */
771 return 1;
772 }
773 #else
774 #ifdef MAKE_STANDARD_CATEGORIES
775 /* helper app to generate set of .desktop files for the list */
main(int argc,char ** argv)776 int main (int argc, char **argv)
777 {
778 char *doc_str;
779 xml_elem_t *doc;
780 xml_elem_t *tr, *td;
781
782
783
784 if (argc < 2) {
785 show_error ("Usage: make_standard_categories <source_file_name>\n");
786 exit (1);
787 }
788
789 doc_str = load_file (argv[1]);
790 if (!doc_str) {
791 show_error ("Unable to load file [%s]: %s.\n", argv[1],
792 strerror (errno));
793 exit (1);
794 }
795
796 doc = xml_parse_doc (doc_str, NULL);
797 if (!doc) {
798 show_error ("Unable to parse data: %s.\n", strerror (errno));
799 exit (1);
800 }
801
802 for (tr = doc->child; tr; tr = tr->next) {
803 if (strcmp (tr->tag, "tr") == 0) {
804 char *name = NULL, *parent = NULL, *comment = NULL;
805
806 td = tr->child;
807 if (td && td->child && strcmp (td->child->tag, XML_CDATA_STR) == 0) {
808 name = td->child->parm;
809 td = td->next;
810 if (td) {
811 if (td->child && strcmp (td->child->tag, XML_CDATA_STR) == 0)
812 comment = td->child->parm;
813 td = td->next;
814 if (td && td->child
815 && strcmp (td->child->tag, XML_CDATA_STR) == 0)
816 parent = td->child->parm;
817 }
818 }
819 if (name && strlen (name) < 200) {
820 char filename[1024];
821 FILE *fp;
822
823 sprintf (filename, "categories/%s.desktop", name);
824 fp = fopen (filename, "wt");
825 if (fp) {
826 fprintf (fp, "[DesktopEntry]\nName=%s\n", name);
827 fprintf (fp, "X-AfterStep-IndexName=%s\n", name);
828 fprintf (fp, "Categories=%s\n", parent ? parent : "");
829 fprintf (fp, "Comment=%s\n", comment ? comment : "");
830 fclose (fp);
831 }
832 }
833
834 }
835 }
836
837 return 1;
838 }
839 #endif
840 #endif
841 #endif
842