a small clock for X11 that displays time as pixels
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 4fff8c3a7fb621998213bf738a2f1ce863739c1a 248 lines 5.4 kB view raw
1/* vim:ts=8 2 * $Id: pixelclock.c,v 1.2 2005/06/28 21:07:37 jcs Exp $ 3 * 4 * pixelclock 5 * a different way of looking at time 6 * 7 * Copyright (c) 2005 joshua stein <jcs@jcs.org> 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <err.h> 34#include <getopt.h> 35#include <signal.h> 36#include <stdio.h> 37#include <stdlib.h> 38#include <string.h> 39#include <time.h> 40#include <unistd.h> 41#include <sys/types.h> 42 43#include <X11/Xlib.h> 44#include <X11/Xutil.h> 45 46/* default clock width */ 47#define DEFWIDTH 3 48 49/* so our window manager knows us */ 50char* win_name = "pixelclock"; 51 52/* hours to highlight (start work, lunch, etc.) */ 53int hihours[] = { 9, 12, 17 }; 54 55struct xinfo { 56 Display* dpy; 57 int dpy_width, dpy_height; 58 59 int screen; 60 61 Window win; 62 63 int width; 64 65 GC gc; 66 67 Colormap win_colormap; 68} x; 69 70const struct option longopts[] = { 71 { "display", required_argument, NULL, 'd' }, 72 { "width", required_argument, NULL, 'w' }, 73 74 { NULL, 0, NULL, 0 } 75}; 76 77extern char *__progname; 78 79long getcolor(const char *); 80void handler(int sig); 81void init_x(const char *); 82void usage(void); 83 84int 85main(int argc, char* argv[]) 86{ 87 char *display = NULL, *p; 88 int c, hi, y, z; 89 int hourtick, lastpos = -1, newpos = 0; 90 struct timeval tv[2]; 91 time_t now; 92 struct tm *t; 93 94 bzero(&x, sizeof(struct xinfo)); 95 96 x.width = DEFWIDTH; 97 98 while ((c = getopt_long_only(argc, argv, "", longopts, NULL)) != -1) { 99 switch (c) { 100 case 'd': 101 display = optarg; 102 break; 103 104 case 'w': 105 x.width = strtol(optarg, &p, 10); 106 if (*p || x.width < 1) 107 errx(1, "illegal value -- %s", optarg); 108 /* NOTREACHED */ 109 break; 110 111 default: 112 usage(); 113 /* NOTREACHED */ 114 } 115 } 116 117 init_x(display); 118 119 signal(SIGINT, handler); 120 signal(SIGTERM, handler); 121 122 /* each hour will be this many pixels away */ 123 hourtick = x.dpy_height / 24; 124 125 for (;;) { 126 if (gettimeofday(&tv[0], NULL)) 127 errx(1, "gettimeofday"); 128 /* NOTREACHED */ 129 130 now = tv[0].tv_sec; 131 if ((t = localtime(&now)) == NULL) 132 errx(1, "localtime"); 133 /* NOTREACHED */ 134 135 newpos = (hourtick * t->tm_hour) + 136 (float)(((float)t->tm_min / 60.0) * hourtick) - 3; 137 138 if (newpos != lastpos) { 139 XClearWindow(x.dpy, x.win); 140 141 XSetForeground(x.dpy, x.gc, getcolor("yellow")); 142 XFillRectangle(x.dpy, x.win, x.gc, 143 0, newpos, 144 x.width, 6); 145 146 /* draw the hour marks */ 147 for (y = 1; y <= 23; y++) { 148 hi = 0; 149 for (z = 0; z < sizeof(&hihours); z++) 150 if (y == hihours[z]) { 151 hi = 1; 152 break; 153 } 154 155 if (hi) 156 XSetForeground(x.dpy, x.gc, 157 getcolor("green")); 158 else 159 XSetForeground(x.dpy, x.gc, 160 getcolor("blue")); 161 162 XFillRectangle(x.dpy, x.win, x.gc, 163 0, (y * hourtick), 164 x.width, 2); 165 } 166 167 lastpos = newpos; 168 169 XFlush(x.dpy); 170 } 171 172 sleep(1); 173 } 174 175 exit(1); 176} 177 178void 179init_x(const char *display) 180{ 181 int rc; 182 XGCValues values; 183 XTextProperty win_name_prop; 184 185 if (!(x.dpy = XOpenDisplay(display))) 186 errx(1, "Unable to open display %s", XDisplayName(display)); 187 /* NOTREACHED */ 188 189 x.screen = DefaultScreen(x.dpy); 190 191 x.dpy_width = DisplayWidth(x.dpy, x.screen); 192 x.dpy_height = DisplayHeight(x.dpy, x.screen); 193 194 x.win_colormap = DefaultColormap(x.dpy, DefaultScreen(x.dpy)); 195 196 x.win = XCreateSimpleWindow(x.dpy, RootWindow(x.dpy, x.screen), 197 x.dpy_width - x.width, 0, 198 x.width, x.dpy_height, 199 0, 200 BlackPixel(x.dpy, x.screen), 201 BlackPixel(x.dpy, x.screen)); 202 203 if (!(x.gc = XCreateGC(x.dpy, x.win, 0, &values))) 204 errx(1, "XCreateGC"); 205 /* NOTREACHED */ 206 207 if (!(rc = XStringListToTextProperty(&win_name, 1, &win_name_prop))) 208 errx(1, "XStringListToTextProperty"); 209 /* NOTREACHED */ 210 211 XSetWMName(x.dpy, x.win, &win_name_prop); 212 213 XMapWindow(x.dpy, x.win); 214 215 XFlush(x.dpy); 216 XSync(x.dpy, False); 217} 218 219long 220getcolor(const char *color) 221{ 222 int rc; 223 224 XColor tcolor; 225 226 if (!(rc = XAllocNamedColor(x.dpy, x.win_colormap, color, &tcolor, 227 &tcolor))) 228 errx(1, "can't allocate %s", color); 229 230 return tcolor.pixel; 231} 232 233void 234handler(int sig) 235{ 236 XCloseDisplay(x.dpy); 237 238 exit(0); 239 /* NOTREACHED */ 240} 241 242void 243usage(void) 244{ 245 fprintf(stderr, "usage: %s %s\n", __progname, 246 "[-display host:dpy] [-width]"); 247 exit(1); 248}