286 lines
6 KiB
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);
|
|
}
|
|
|
|
}
|