823 lines
17 KiB
C
823 lines
17 KiB
C
#include <config.h>
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
#include <unistd.h>
|
||
#include <dirent.h>
|
||
#include <sys/stat.h>
|
||
#include <fcntl.h>
|
||
|
||
#include <X11/X.h>
|
||
#include <X11/xpm.h>
|
||
|
||
#include <time.h>
|
||
#include "wmgeneral.h"
|
||
#include "stringlist.h"
|
||
|
||
#include "xpm/back.xpm"
|
||
#include "xpm/star.xpm"
|
||
#include "xpm/no_icon.xpm"
|
||
|
||
|
||
|
||
/*
|
||
* Delay between refreshes (in microseconds)
|
||
*/
|
||
#define DELAY 10000L
|
||
|
||
#define ICONSIZE 64
|
||
|
||
|
||
/* Database structures */
|
||
|
||
enum th_type {THEME, WALL};
|
||
|
||
struct theme {
|
||
enum th_type type;
|
||
char * path;
|
||
/* int theme;
|
||
char * options;*/
|
||
};
|
||
|
||
struct category {
|
||
char * name;
|
||
LIST * themes;
|
||
};
|
||
|
||
|
||
LIST * thm_db;
|
||
LIST * cat_db;
|
||
|
||
/* Themes directories, last one will be replaced */
|
||
char * themes_dir[] = {
|
||
"/usr/share/WindowMaker/Themes",
|
||
"/usr/X11R6/share/WindowMaker/Themes",
|
||
"/usr/local/share/WindowMaker/Themes",
|
||
"$GNUSTEP_USER_ROOT/Library/WindowMaker/Themes"
|
||
};
|
||
|
||
|
||
/* Wallpapers directories, last one will be replaced */
|
||
char * wallpapers_dir[] = {
|
||
"/usr/share/WindowMaker/Backgrounds",
|
||
"/usr/X11R6/share/WindowMaker/Backgrounds",
|
||
"/usr/local/share/WindowMaker/Backgrounds",
|
||
"$GNUSTEP_USER_ROOT/Library/WindowMaker/Backgrounds"
|
||
};
|
||
|
||
|
||
char hid_cat_db[] = ".wmThemeCh.cat.db";
|
||
char cat_db_file[] = "wmThemeCh.cat.db";
|
||
char reg_cat [] = "categories";
|
||
|
||
int current_category = 0;
|
||
unsigned long int auto_switch_delay = 0;
|
||
unsigned long int auto_switch_next = 0;
|
||
|
||
char * mask_bits;
|
||
|
||
XpmAttributes Attributes;
|
||
Colormap cmap;
|
||
|
||
|
||
int
|
||
BuildBitmask ()
|
||
{
|
||
int i, j, off = 0;
|
||
int size = (ICONSIZE * ICONSIZE - 1) / 8 + 1;
|
||
|
||
mask_bits = malloc (size);
|
||
|
||
/* must have iconsize % 8 = 0 */
|
||
|
||
for (i = 0; i < 4 * ICONSIZE / 8; i++) {
|
||
mask_bits[off++] = 0;
|
||
}
|
||
for (i = 0; i < ICONSIZE - 8; i++) {
|
||
mask_bits[off++] = 0xf0;
|
||
for (j = 0; j < (ICONSIZE / 8 - 2); j++) {
|
||
mask_bits[off++] = 0xff;
|
||
}
|
||
mask_bits[off++] = 0x0f;
|
||
}
|
||
for (i = 0; i < 4 * ICONSIZE / 8; i++) {
|
||
mask_bits[off++] = 0;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
#define ADD_CATEGORY(string) \
|
||
do { \
|
||
struct category * newcat; \
|
||
\
|
||
newcat = malloc (sizeof (struct category) ); \
|
||
newcat->name = strdup (string); \
|
||
newcat->themes = create_list (); \
|
||
add_item (cat_db, (unsigned int) newcat); \
|
||
} while (0);
|
||
|
||
#define PROCESS_CATEGORY_FILE \
|
||
if ( (catfile = fopen (catname,"r") ) ) \
|
||
{ \
|
||
while (fscanf (catfile, "%255s", ImageName) == 1) { \
|
||
ADD_CATEGORY(ImageName); \
|
||
} \
|
||
fclose (catfile); \
|
||
} \
|
||
free (catname);
|
||
|
||
/* Register categories recognized by system + user */
|
||
int
|
||
get_categories ()
|
||
{
|
||
char * catname;
|
||
char * home = getenv ("HOME");
|
||
char ImageName[256];
|
||
FILE * catfile;
|
||
|
||
ADD_CATEGORY("*");
|
||
|
||
catname = malloc (strlen (home) + strlen (PACKAGE_NAME)
|
||
+ strlen (reg_cat) + 4);
|
||
|
||
sprintf (catname, "%s/.%s/%s", home, PACKAGE_NAME, reg_cat);
|
||
|
||
PROCESS_CATEGORY_FILE
|
||
|
||
catname = malloc (strlen (PACKAGE) + strlen (reg_cat) + 13);
|
||
|
||
sprintf (catname, "/usr/share/%s/%s", PACKAGE, reg_cat);
|
||
|
||
PROCESS_CATEGORY_FILE
|
||
|
||
catname = malloc (strlen (PACKAGE) + strlen (reg_cat) + 19);
|
||
|
||
sprintf (catname, "/usr/local/share/%s/%s", PACKAGE, reg_cat);
|
||
|
||
PROCESS_CATEGORY_FILE
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
enum de_type { ERROR = -1, IGNORED, STYLE, DE_THEME, SUBDIR, IMAGE };
|
||
|
||
/* Return values :
|
||
* -1 : stat error
|
||
* 0 : Ignored entries : ., .., category
|
||
* 1 : regular file (.style)
|
||
* 2 : theme directory (.themed)
|
||
* 3 : sub-directory
|
||
* 4 : image
|
||
*/
|
||
enum de_type
|
||
entry_type (char * dir, char * entry)
|
||
{
|
||
char * name = malloc (strlen (dir) + strlen (entry) + 2);
|
||
struct stat buf;
|
||
|
||
sprintf (name, "%s/%s", dir, entry);
|
||
|
||
if (stat (name, &buf) ) {
|
||
perror ("stat ");
|
||
free (name);
|
||
return ERROR;
|
||
}
|
||
|
||
free (name);
|
||
|
||
if (! S_ISDIR (buf.st_mode) ) {
|
||
if (! strcmp (entry,cat_db_file ) ) return IGNORED;
|
||
if (! strcmp (entry,hid_cat_db) ) return IGNORED;
|
||
/* TODO : Use file (1) */
|
||
if (strstr (entry, ".xpm" ) ) return IMAGE;
|
||
if (strstr (entry, ".png" ) ) return IMAGE;
|
||
if (strstr (entry, ".jpg" ) ) return IMAGE;
|
||
if (strstr (entry, ".jpeg") ) return IMAGE;
|
||
if (strstr (entry, ".tif" ) ) return IMAGE;
|
||
if (strstr (entry, ".ppm" ) ) return IMAGE;
|
||
|
||
return STYLE;
|
||
}
|
||
|
||
if (strstr (entry, ".themed") ) return DE_THEME;
|
||
if (strcmp (entry,"." ) && strcmp (entry,"..") ) return SUBDIR;
|
||
|
||
return IGNORED;
|
||
}
|
||
|
||
|
||
struct theme *
|
||
insert_into_thm (char * path, enum th_type type)
|
||
{
|
||
struct theme * new_theme = malloc (sizeof (struct theme) );
|
||
|
||
new_theme->type = type;
|
||
new_theme->path = strdup (path);
|
||
add_item (thm_db, (int) new_theme);
|
||
|
||
return new_theme;
|
||
}
|
||
|
||
int
|
||
insert_into_cat (struct theme * theme, LIST * cat_list)
|
||
{
|
||
int i, j, lcat;
|
||
char * lcat_nam;
|
||
|
||
add_item ( ( (struct category *) get_item (cat_db, 0) ) -> themes,
|
||
(int) theme);
|
||
|
||
/* for each category theme is in */
|
||
for (j = 0; (lcat = get_item (cat_list, j) ) != -1; j++) {
|
||
int ucat;
|
||
lcat_nam = (char *) lcat;
|
||
/* for each user category */
|
||
for (i=1; (ucat = get_item (cat_db, i) ) != -1; i++) {
|
||
struct category * cat = (struct category *) ucat;
|
||
/* check if they match */
|
||
if (! strcmp (lcat_nam, cat->name) ) {
|
||
add_item (cat->themes, (int) theme);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
LIST *
|
||
theme_specific_cat (char * path, LIST * cat_list)
|
||
{
|
||
FILE * th_cat;
|
||
char * th_cat_nam = malloc (strlen (path) + strlen (hid_cat_db) + 2);
|
||
int i, ret, version, subversion;
|
||
char cat_nam[512];
|
||
LIST * new_list;
|
||
|
||
sprintf (th_cat_nam, "%s/%s", path, cat_db_file);
|
||
th_cat = fopen (th_cat_nam, "r");
|
||
|
||
if (! th_cat) {
|
||
sprintf (th_cat_nam, "%s/%s", path, hid_cat_db);
|
||
th_cat = fopen (th_cat_nam, "r");
|
||
|
||
if (! th_cat) {
|
||
free (th_cat_nam);
|
||
return cat_list;
|
||
}
|
||
}
|
||
|
||
ret = fscanf (th_cat, "# wmThemeCh categories database file version %i.%i",
|
||
&version, &subversion);
|
||
|
||
if (ret != 2) {
|
||
printf("%s : invalid signature\n", th_cat_nam);
|
||
fclose (th_cat);
|
||
free (th_cat_nam);
|
||
return cat_list;
|
||
}
|
||
|
||
if (version > 1) {
|
||
printf("%s : incompatible version\n", th_cat_nam);
|
||
fclose (th_cat);
|
||
free (th_cat_nam);
|
||
return cat_list;
|
||
}
|
||
|
||
new_list = create_list ();
|
||
add_list (new_list, cat_list);
|
||
|
||
while ( (ret = fscanf (th_cat, "%s", cat_nam) ) == 1) {
|
||
for (i=0; get_item (cat_db,i) != -1; i++) {
|
||
struct category * cat =
|
||
(struct category *) get_item (cat_db,i);
|
||
if (! strcmp (cat_nam, cat->name) ) {
|
||
/* printf("%s : '%s'\n", th_cat_nam, cat_nam); */
|
||
add_item (new_list, (int) strdup (cat->name) );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
fclose (th_cat);
|
||
free (th_cat_nam);
|
||
|
||
return new_list;
|
||
}
|
||
|
||
/* Read "categories" file in path.
|
||
* Themes in path and its subdirs are belonging to categories listed
|
||
* in that file if these categories are defined by user profile.
|
||
* Updates cat_list accordingly.
|
||
*/
|
||
int
|
||
add_dir_cat (const char * path, LIST * cat_list)
|
||
{
|
||
FILE * th_cat;
|
||
char * th_cat_nam = malloc (strlen (path) + strlen (hid_cat_db) + 2);
|
||
int ret, version, subversion;
|
||
char cat_nam[512];
|
||
|
||
sprintf (th_cat_nam, "%s/%s", path, hid_cat_db);
|
||
th_cat = fopen (th_cat_nam, "r");
|
||
|
||
if (! th_cat) {
|
||
free (th_cat_nam);
|
||
return 0;
|
||
}
|
||
|
||
ret = fscanf (th_cat, "# wmThemeCh categories database file version %i.%i",
|
||
&version, &subversion);
|
||
|
||
if (ret != 2) {
|
||
printf("%s : invalid signature\n", th_cat_nam);
|
||
fclose (th_cat);
|
||
free (th_cat_nam);
|
||
return 0;
|
||
}
|
||
|
||
|
||
while ( (ret = fscanf (th_cat, "%s", cat_nam) ) == 1) {
|
||
int i;
|
||
|
||
for (i=0; get_item (cat_db, i) != -1; i++) {
|
||
struct category * cat =
|
||
(struct category *) get_item (cat_db, i);
|
||
if (! strcmp (cat_nam, cat->name) ) {
|
||
/* printf("%s : '%s'\n", th_cat_nam, cat_nam); */
|
||
add_item (cat_list, (int) strdup (cat->name) );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
fclose (th_cat);
|
||
free (th_cat_nam);
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
int
|
||
get_themes (char * path, LIST * par_cat_list)
|
||
{
|
||
struct dirent ** namelist;
|
||
LIST * cat_list = create_list();
|
||
int themes_count = 0;
|
||
|
||
int count = scandir (path, &namelist, NULL, alphasort);
|
||
|
||
if (count < 0) {
|
||
free (cat_list);
|
||
return -1;
|
||
}
|
||
|
||
if (par_cat_list) add_list (cat_list, par_cat_list);
|
||
|
||
add_dir_cat (path, cat_list);
|
||
|
||
while (count--) {
|
||
char fullname[512];
|
||
struct theme * new_theme;
|
||
LIST * th_spec_cat;
|
||
|
||
sprintf (fullname, "%s/%s", path, namelist[count]->d_name);
|
||
|
||
switch (entry_type (path, namelist[count]->d_name) ) {
|
||
case ERROR :
|
||
case IGNORED : break;
|
||
case STYLE :
|
||
new_theme = insert_into_thm (fullname, THEME);
|
||
insert_into_cat (new_theme, cat_list);
|
||
break;
|
||
case DE_THEME :
|
||
new_theme = insert_into_thm (fullname, THEME);
|
||
th_spec_cat = theme_specific_cat (fullname, cat_list);
|
||
insert_into_cat (new_theme, th_spec_cat);
|
||
if (th_spec_cat != cat_list) {
|
||
delete_list (th_spec_cat);
|
||
}
|
||
break;
|
||
case SUBDIR :
|
||
get_themes (fullname, cat_list);
|
||
case IMAGE : break;
|
||
}
|
||
}
|
||
|
||
free (cat_list);
|
||
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
get_wallpapers (char * path, LIST * par_cat_list)
|
||
{
|
||
struct dirent ** namelist;
|
||
LIST * cat_list = create_list();
|
||
int themes_count = 0;
|
||
|
||
int count = scandir (path, &namelist, NULL, NULL);
|
||
|
||
if (count < 0) {
|
||
free (cat_list);
|
||
return -1;
|
||
}
|
||
|
||
if (par_cat_list) add_list (cat_list, par_cat_list);
|
||
|
||
add_dir_cat (path, cat_list);
|
||
|
||
while (count--) {
|
||
char fullname[512];
|
||
struct theme * new_theme;
|
||
|
||
sprintf (fullname, "%s/%s", path, namelist[count]->d_name);
|
||
|
||
switch (entry_type (path, namelist[count]->d_name) ) {
|
||
case ERROR :
|
||
case IGNORED :
|
||
case STYLE :
|
||
case DE_THEME: break;
|
||
case SUBDIR :
|
||
get_wallpapers (fullname, cat_list);
|
||
break;
|
||
case IMAGE :
|
||
new_theme = insert_into_thm (fullname, WALL);
|
||
insert_into_cat (new_theme, cat_list);
|
||
}
|
||
}
|
||
|
||
free (cat_list);
|
||
|
||
return 0;
|
||
}
|
||
|
||
int
|
||
BuildDatabase ()
|
||
{
|
||
char * user_theme_dir = "/Library/WindowMaker/Themes";
|
||
char * user_wallpaper_dir = "/Library/WindowMaker/Backgrounds";
|
||
char * gnustep_user_root = getenv("GNUSTEP_USER_ROOT");
|
||
|
||
int dir_idx;
|
||
|
||
thm_db = create_list();
|
||
cat_db = create_list();
|
||
|
||
if (!gnustep_user_root) {
|
||
char * home = getenv ("HOME");
|
||
gnustep_user_root = malloc (strlen (home) + 9);
|
||
sprintf (gnustep_user_root, "%s/GNUstep", home);
|
||
}
|
||
|
||
themes_dir[3] = malloc (strlen (gnustep_user_root)
|
||
+ strlen (user_theme_dir) + 1);
|
||
sprintf (themes_dir[3], "%s%s", gnustep_user_root, user_theme_dir);
|
||
|
||
wallpapers_dir[3] = malloc (strlen (gnustep_user_root)
|
||
+ strlen (user_wallpaper_dir) + 1);
|
||
sprintf (wallpapers_dir[3], "%s%s", gnustep_user_root, user_wallpaper_dir);
|
||
|
||
get_categories ();
|
||
|
||
for (dir_idx=0; dir_idx < 4; dir_idx++) {
|
||
get_themes ( themes_dir[dir_idx], NULL);
|
||
get_wallpapers (wallpapers_dir[dir_idx], NULL);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
char *
|
||
get_pixmap_path (const char * icon_name)
|
||
{
|
||
char * path;
|
||
char * home = getenv ("HOME");
|
||
struct stat stat_buf;
|
||
|
||
path = malloc ( strlen (home) + strlen (PACKAGE_NAME)
|
||
+ strlen (icon_name) + 8);
|
||
|
||
sprintf (path, "%s/.%s/%s.xpm", home, PACKAGE_NAME, icon_name);
|
||
|
||
if (! stat (path, &stat_buf) ) {
|
||
return path;
|
||
}
|
||
|
||
free (path);
|
||
path = malloc (strlen (PACKAGE) + strlen (icon_name) + 23);
|
||
|
||
sprintf (path, "/usr/local/share/%s/%s.xpm", PACKAGE, icon_name);
|
||
|
||
if (! stat (path, &stat_buf) ) {
|
||
return path;
|
||
}
|
||
|
||
free (path);
|
||
path = malloc (strlen (PACKAGE) + strlen (icon_name) + 17);
|
||
|
||
sprintf (path, "/usr/share/%s/%s.xpm", PACKAGE, icon_name);
|
||
|
||
if (! stat (path, &stat_buf) ) {
|
||
return path;
|
||
}
|
||
|
||
free (path);
|
||
return NULL;
|
||
}
|
||
|
||
|
||
int
|
||
DrawPixmap (char * XpmFileName)
|
||
{
|
||
static Pixmap NewPixmap, NewShapeMask = 0;
|
||
static int ret, havePixmap= 0;
|
||
|
||
/* copyXPMArea(5, 69, 54, 54, 5, 5); * Clear window */
|
||
copyXPMArea(4, 4, 56, 56, 4, 4); /* Clear window */
|
||
|
||
if (havePixmap) {
|
||
/*
|
||
* free up the colors, if we alloc'd some before
|
||
*/
|
||
if (Attributes.nalloc_pixels > 0)
|
||
XFreeColors(display, cmap, Attributes.alloc_pixels,
|
||
Attributes.nalloc_pixels, 0);
|
||
/*
|
||
* Free last pixmap -- we dont need it anymore...
|
||
* A ShapeMask is returned if the Pixmap
|
||
* had the color None used.
|
||
* We could probably change Transparent to None
|
||
* to make use of this, but for now,
|
||
* lets just ignore it...
|
||
*/
|
||
if (NewShapeMask != 0) XFreePixmap (display, NewShapeMask);
|
||
|
||
XFreePixmap(display, NewPixmap);
|
||
|
||
XpmFreeAttributes (&Attributes);
|
||
|
||
havePixmap= 0;
|
||
} /* havePixmap */
|
||
|
||
/*
|
||
* Grab new pixmap. Accept a reasonable color match.
|
||
*/
|
||
Attributes.valuemask = XpmExactColors | XpmCloseness
|
||
| XpmReturnAllocPixels;
|
||
Attributes.exactColors = 0;
|
||
Attributes.closeness = 40000;
|
||
|
||
/* TODO : We might cache icons */
|
||
|
||
if (XpmFileName) {
|
||
if (strcmp (XpmFileName,"*") ) {
|
||
ret = XpmReadFileToPixmap (display, Root, XpmFileName,
|
||
&NewPixmap, &NewShapeMask, &Attributes);
|
||
} else {
|
||
ret = XpmCreatePixmapFromData (display, Root, star_xpm,
|
||
&NewPixmap, &NewShapeMask, &Attributes);
|
||
}
|
||
} else {
|
||
ret = XpmCreatePixmapFromData (display, Root, no_icon_xpm,
|
||
&NewPixmap, &NewShapeMask, &Attributes);
|
||
}
|
||
|
||
if (ret >= 0)
|
||
{
|
||
int Height = Attributes.height;
|
||
XCopyArea (display, NewPixmap, wmgen.pixmap, NormalGC,
|
||
0, 0, Attributes.width, Height, 4, 4);
|
||
havePixmap= 1;
|
||
}
|
||
|
||
/*
|
||
* Make changes visible
|
||
*/
|
||
RedrawWindow();
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
int
|
||
ChangeCategory ()
|
||
{
|
||
char * XpmFileName = NULL;
|
||
|
||
current_category++;
|
||
if (get_item (cat_db, current_category) == -1) current_category = 0;
|
||
if (current_category) {
|
||
XpmFileName = get_pixmap_path (
|
||
( (struct category *) get_item
|
||
(cat_db, current_category) ) -> name);
|
||
} else {
|
||
XpmFileName = strdup("*");
|
||
}
|
||
|
||
DrawPixmap (XpmFileName);
|
||
|
||
if (XpmFileName) free (XpmFileName);
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
int
|
||
ChangeTheme ()
|
||
{
|
||
int fd;
|
||
char Command[512];
|
||
|
||
static unsigned int oldidx = -1;
|
||
unsigned int val, i;
|
||
struct category * cur_cat = (struct category *)
|
||
get_item (cat_db, current_category);
|
||
|
||
for (i = 0; get_item (cur_cat->themes, i) != -1; i++);
|
||
|
||
switch (i) {
|
||
case 0 : return 1;
|
||
case 1 : val = 0; break;
|
||
default :
|
||
fd = open ("/dev/random", O_RDONLY);
|
||
|
||
/* We're disallowing "changing" to the same */
|
||
read (fd, &val, sizeof (int) );
|
||
val = val % (i - 1);
|
||
if (val >= oldidx) val++;
|
||
|
||
close (fd);
|
||
oldidx = val;
|
||
}
|
||
|
||
switch ( ( (struct theme *) get_item (cur_cat->themes, val) ) -> type) {
|
||
case THEME :
|
||
sprintf (Command, "setstyle \"%s\"", ( (struct theme *)
|
||
get_item (cur_cat->themes, val) ) -> path);
|
||
break;
|
||
case WALL :
|
||
sprintf (Command, "wmsetbg -u \"%s\"", ( (struct theme *)
|
||
get_item (cur_cat->themes, val) ) -> path);
|
||
}
|
||
|
||
system(Command);
|
||
|
||
auto_switch_next = time(NULL) + (auto_switch_delay * 60);
|
||
return 0;
|
||
}
|
||
|
||
|
||
void
|
||
pressEvent (XButtonEvent *xev)
|
||
{
|
||
/* Mouse's left button clicked */
|
||
if (xev->button == Button1) ChangeTheme ();
|
||
|
||
/* Mouse's right button clicked */
|
||
if (xev->button == Button3) ChangeCategory ();
|
||
}
|
||
|
||
|
||
int
|
||
ProcessXEvents ()
|
||
{
|
||
while (XPending (display) )
|
||
{
|
||
XEvent event;
|
||
|
||
XNextEvent (display, &event);
|
||
|
||
switch (event.type) {
|
||
case Expose : RedrawWindow (); break;
|
||
case ButtonPress : pressEvent (&event.xbutton); break;
|
||
case ButtonRelease : break;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
void
|
||
print_usage ()
|
||
{
|
||
printf ("%s\n", PACKAGE_STRING);
|
||
printf ("Report problems to <%s>\n", PACKAGE_BUGREPORT);
|
||
printf ("\nusage: %s [options]...\n\n", PACKAGE_NAME);
|
||
printf ("\t-display <Display>\tUse alternate X display.\n");
|
||
printf ("\t-h\t\t\tDisplay help screen.\n\n");
|
||
}
|
||
|
||
|
||
void
|
||
ParseCMDLine (int argc, char *argv[])
|
||
{
|
||
int i, x;
|
||
|
||
for (i = 1; i < argc; i++) {
|
||
if (strcmp(argv[i], "-a") == 0) {
|
||
if (argc > i+1) {
|
||
x = sscanf(argv[i+1], "%u", &auto_switch_delay);
|
||
if (x != 1) {
|
||
auto_switch_delay = 0;
|
||
printf("Found auto-option but could not parse parameter\n");
|
||
exit(-1);
|
||
} else {
|
||
++i;
|
||
}
|
||
} else {
|
||
printf("Found auto-option but number is missing!\n");
|
||
exit(-1);
|
||
}
|
||
} else {
|
||
|
||
if (!strcmp (argv[i], "-display") ) {
|
||
++i;
|
||
} else {
|
||
print_usage();
|
||
exit (1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
int
|
||
Init (int argc, char * argv[])
|
||
{
|
||
char * basename = current_category
|
||
? ( (struct category *)
|
||
get_item (cat_db, current_category)
|
||
) -> name
|
||
: NULL;
|
||
|
||
char * path = NULL;
|
||
|
||
ParseCMDLine (argc, argv);
|
||
BuildDatabase ();
|
||
|
||
if (current_category) {
|
||
path = get_pixmap_path (basename);
|
||
} else {
|
||
path = strdup ("*");
|
||
}
|
||
|
||
BuildBitmask();
|
||
openXwindow (argc, argv, back_xpm, mask_bits,
|
||
ICONSIZE, ICONSIZE);
|
||
|
||
cmap = DefaultColormap(display, DefaultScreen(display));
|
||
|
||
Attributes.nalloc_pixels = 0;
|
||
|
||
DrawPixmap (path);
|
||
|
||
if (path) free (path);
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
int
|
||
main (int argc, char *argv[])
|
||
{
|
||
unsigned int delay_timer = 0;
|
||
Init (argc, argv);
|
||
|
||
if (auto_switch_delay > 0) {
|
||
auto_switch_next = time(NULL) + (auto_switch_delay * 60);
|
||
}
|
||
|
||
/* TODO : use sigsuspend */
|
||
|
||
while (1) {
|
||
ProcessXEvents ();
|
||
delay_timer += DELAY;
|
||
if ( delay_timer > 10000000L ) { /* check every 10 seconds */
|
||
delay_timer = 0;
|
||
if (auto_switch_delay > 0) {
|
||
if (auto_switch_next < time(NULL)) {
|
||
ChangeTheme();
|
||
}
|
||
}
|
||
}
|
||
usleep (DELAY);
|
||
}
|
||
}
|