dockapps/wmhexaclock/src/main.c

286 lines
6 KiB
C

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/X.h>
#include <X11/xpm.h>
#include <X11/Xlib.h>
#include <unistd.h>
#include <time.h>
#include <stdbool.h>
#include <getopt.h>
#include "wmgeneral.h"
#include "pixmaps.h"
#define HOUR 1
#define MINUTE 2
#define SECOND 3
#define VERSION "0.1"
#define RELEASED "October 2006"
/* Prototypes */
void beat(void);
void display_time(int number,int time_unit);
void display_lines(time_t seconds);
void display_date(int day_of_week, int day_of_month, int month, int year,int mode,time_t seconds);
void setColor(char *color);
void setMode(char *mode);
void display_help(void);
void display_version(void);
bool errorColor(char *color);
bool errorMode(char *mode);
/*Global Variables*/
time_t actualtime;
int g_mode=0;
char color_line[12]="+\tc #";
bool errorMode(char *mode)
{
if (strncmp(mode,"0",1)!=0 && strncmp(mode,"1",1)!=0)
return true;
else
return false;
}
bool errorColor(char *color)
{
int i=0;
if (strlen(color)!=6)
return true;
for (i=0;i<6;i++)
{
if ((color[i]<48 || color[i]>57) && (color[i]<65 || color[i]>70) && (color[i]<97 || color[i]>102))
return true;
}
return false;
}
void print_version()
{
puts("\033[1mwmHexaClock\033[0m");
printf("Version: \t%s\n",VERSION);
printf("Released: \t%s\n",RELEASED);
puts("Info: \t\thttp://www.bjoernw.de/");
exit (0);
}
void print_help()
{
puts("Usage: wmHexaClock [OPTIONS]");
puts("Possible Options are:\n");
puts(" -v or --version:\t\tGives information about version and release date");
puts(" -h or --help:\t\t\tPrints this dialog");
puts(" -c [COLOR] or --color [COLOR]:\tSpecifies the foreground color; for [COLOR] you use the hexadecimal notation RRGGBB (R=red, G=green, B=blue)");
puts(" \t\t\t\tExample: \"wmHexaClock -c FF0000\" for red");
puts(" -m [i] or --mode [i]:\t\tThere are two different display modes; for [i] you type 0 or 1 to chose between them (0 is default)");
exit(0);
}
void setColor(char *color)
{
if (!errorColor(color))
xpm_numbers[3]=strncat(color_line,color,6); //Edit the Color-Line in xpm_numbers (-> pixmaps.h)
else
{
fprintf (stderr,"The Color Code is nor correct! Example: \"-c 00FF00\" for green!\n");
exit (1);
}
}
void setMode(char *mode)
{
if (!errorMode(mode))
g_mode=((int)*(mode))-48;
else
{
fprintf (stderr,"Please choose between mode 0 and 1. Example: \"-mode 0\"!\n");
exit (1);
}
}
int main(int argc, char *argv[])
{
XEvent event;
actualtime=time(0);
static struct option long_options[] =
{
/* These options set a flag. */
{"version", no_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
{"color", required_argument, 0, 'c'},
{"mode", required_argument, 0, 'm'},
{0, 0, 0, 0}
};
while (1)
{
int c;
int option_index = 0;
c = getopt_long (argc, argv, "vhc:m:", long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
switch (c)
{
case 'v':
print_version();
break;
case 'h':
print_help();
break;
case 'c':
setColor(optarg);
break;
case 'm':
setMode(optarg);
break;
case '?':
puts("Type wmHexaClock -h for information");
exit(0);
break;
default:
abort();
}
}
openXwindow(argc, argv, xpm_numbers, xpm_master, xpm_mask_bits, xpm_mask_width, xpm_mask_height);
/* Loop Forever */
while (1)
{
if (actualtime!=time(0))
beat();
/* Process any pending X events. */
while (XPending(display))
{
XNextEvent(display, &event);
if (event.type==Expose)
RedrawWindow();
}
usleep(10000);
}
/* we should never get here */
return (0);
}
void beat()
{
struct tm *time_struct;
actualtime=time(0);
time_struct=localtime(&actualtime);
cleanXPMArea();
display_time(time_struct->tm_hour,HOUR);
display_time(time_struct->tm_min,MINUTE);
display_time(time_struct->tm_sec,SECOND);
copyXPMArea(177,0,8,12,27,3); /*Display the two dots*/
display_lines(time_struct->tm_sec);
display_date(time_struct->tm_wday,time_struct->tm_mday,time_struct->tm_mon,time_struct->tm_year+1900,g_mode,time_struct->tm_sec);
RedrawWindow();
}
void display_time(int number,int time_unit){
int first_pos=number/16;
int second_pos=number%16;
if (time_unit==HOUR)
{
copyXPMArea(first_pos*11,0,11,12,5,5);
copyXPMArea(second_pos*11,0,11,12,16,5);
}
else if (time_unit==MINUTE)
{
copyXPMArea(first_pos*11,0,11,12,35,5);
copyXPMArea(second_pos*11,0,11,12,46,5);
}
else if (time_unit==SECOND)
{
copyXPMArea(first_pos*7,12,7,8,40,20);
copyXPMArea(second_pos*7,12,7,8,48,20);
}
return;
}
void display_lines(time_t seconds)
{
int i;
for (i=0;i<(seconds/8);i++)
copyXPMArea(0,29,8,4,i*8+4,32);
return;
}
void display_date(int day_of_week, int day_of_month, int month, int year,int mode,time_t seconds)
{
int first_pos_day=day_of_month/16;
int second_pos_day=day_of_month%16;
int first_pos_month=(month+1)/16;
int second_pos_month=(month+1)%16;
int first_pos_year=year/256;
int second_pos_year=(year-first_pos_year*256)/16;
int third_pos_year=year-first_pos_year*256-second_pos_year*16;
static bool rec_mode;
if (mode==1)
{
copyXPMArea((day_of_week-1)*22,20,22,9,5,39);
copyXPMArea(first_pos_day*7,12,7,9,30,39);
copyXPMArea(second_pos_day*7,12,7,9,37,39);
copyXPMArea(8,30,2,2,45,46);
copyXPMArea(first_pos_month*7,12,7,9,47,39);
copyXPMArea(second_pos_month*7,12,7,9,54,39);
copyXPMArea(first_pos_year*7,12,7,8,34,50);
copyXPMArea(second_pos_year*7,12,7,8,44,50);
copyXPMArea(third_pos_year*7,12,7,8,53,50);
}
else
{
if (seconds%3==0)
rec_mode=!rec_mode;
}
if (rec_mode)
copyXPMArea((day_of_week-1)*31,32,31,12,16,39);
else
{
copyXPMArea(first_pos_day*11,0,11,12,3,36);
copyXPMArea(second_pos_day*11,0,11,12,14,36);
copyXPMArea(180,9,4,3,26,46);
copyXPMArea(first_pos_month*11,0,11,12,32,36);
copyXPMArea(second_pos_month*11,0,11,12,43,36);
copyXPMArea(180,9,4,3,55,46);
copyXPMArea(first_pos_year*7,12,7,8,18,51);
copyXPMArea(second_pos_year*7,12,7,8,28,51);
copyXPMArea(third_pos_year*7,12,7,8,37,51);
}
}