Code

Modified %shortfile% format to not shorten urls
[ncmpc.git] / src / screen_clock.c
1 /*
2  * $Id$
3  *
4  * This file is based on the 'Grand digital clock' (gdc.c) shipped with 
5  * ncurses. 
6  */
8 #include <time.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <glib.h>
12 #include <ncurses.h>
14 #include "config.h"
16 #ifdef  ENABLE_CLOCK_SCREEN
17 #include "ncmpc.h"
18 #include "mpdclient.h"
19 #include "options.h"
20 #include "command.h"
21 #include "screen.h"
22 #include "screen_utils.h"
24 #define YDEPTH  5
25 #define BUFSIZE 64
27 #define ENABLE_SECONDS 0
29 static window_t win = { NULL, 0, 0 };
30 static gboolean enable_seconds = ENABLE_SECONDS;
32 /* orginal variables from gdc.c */
33 static short disp[11] =
34 {
35     075557, 011111, 071747, 071717, 055711,
36     074717, 074757, 071111, 075757, 075717, 002020
37 };
39 static long older[6], next[6], newer[6], mask;
41 static int YBASE = 10;
42 static int XBASE = 10;
43 static int XLENGTH = 54;
45 /* orginal functions */
46 static void
47 set(int t, int n)
48 {
49   int i, m;
51   m = 7 << n;
52   for (i = 0; i < 5; i++) {
53     next[i] |= ((disp[t] >> ((4 - i) * 3)) & 07) << n;
54     mask |= (next[i] ^ older[i]) & m;
55   }
56   if (mask & m)
57     mask |= m;
58 }
60 static void
61 drawbox(void)
62 {
63   chtype bottom[XLENGTH + 1];
64   int n;
66   mvwaddch(win.w, YBASE - 1, XBASE - 1, ACS_ULCORNER);
67   whline(win.w, ACS_HLINE, XLENGTH);
68   mvwaddch(win.w, YBASE - 1, XBASE + XLENGTH, ACS_URCORNER);
70   mvwaddch(win.w, YBASE + YDEPTH, XBASE - 1, ACS_LLCORNER);
71   mvwinchnstr(win.w, YBASE + YDEPTH, XBASE, bottom, XLENGTH);
72   for (n = 0; n < XLENGTH; n++)
73     bottom[n] = ACS_HLINE | (bottom[n] & (A_ATTRIBUTES | A_COLOR));
74   mvwaddchnstr(win.w, YBASE + YDEPTH, XBASE, bottom, XLENGTH);
75   mvwaddch(win.w, YBASE + YDEPTH, XBASE + XLENGTH, ACS_LRCORNER);
76   
77   wmove(win.w, YBASE, XBASE - 1);
78   wvline(win.w, ACS_VLINE, YDEPTH);
79   
80   wmove(win.w, YBASE, XBASE + XLENGTH);
81   wvline(win.w, ACS_VLINE, YDEPTH);
82 }
85 static void
86 standt(int on)
87 {
88   if(on)
89     wattron(win.w, A_REVERSE);
90   else
91     wattroff(win.w, A_REVERSE);
92 }
96 /* ncmpc screen functions */
98 static void
99 clock_resize(int cols, int rows)
101   int j;
102   
103   for (j = 0; j < 5; j++)
104     older[j] = newer[j] = next[j] = 0;
106   win.cols = cols;
107   win.rows = rows;
108   
109   if( cols<60 )
110     enable_seconds = FALSE;
111   else
112     enable_seconds = ENABLE_SECONDS;
114   if( enable_seconds )
115     XLENGTH = 54;
116   else
117     XLENGTH = 54-18;
119   
120   XBASE = (cols-XLENGTH)/2;
121   YBASE = (rows-YDEPTH)/2-(YDEPTH/2)+2;
124 static void 
125 clock_init(WINDOW *w, int cols, int rows)
127   win.w = w;
128   clock_resize(cols, rows);
131 static void 
132 clock_exit(void)
136 static void 
137 clock_open(screen_t *screen, mpdclient_t *c)
139   int j;
141   for (j = 0; j < 5; j++)
142     older[j] = newer[j] = next[j] = 0;
146 static void 
147 clock_close(void)
151 static char *
152 clock_title(char *str, size_t size)
154   return _("Clock");
157 static void 
158 clock_update(screen_t *screen, mpdclient_t *c)
159 {  
160   time_t now;
161   struct tm *tm;
162   long t, a;
163   int i, j, s, k;
164   char buf[BUFSIZE];
166   time(&now);
167   tm = localtime(&now);
169   if( win.rows<=YDEPTH+1 || win.cols<=XLENGTH+1 )
170     {
171       strftime(buf, BUFSIZE, "%X ",tm);
172       mvwaddstr(win.w, win.rows ? win.rows/2:0, (win.cols-strlen(buf))/2, buf);
173       wrefresh(win.w);
174       return;
175     }
176   
178   
179   mask = 0;
180   set(tm->tm_sec % 10, 0);
181   set(tm->tm_sec / 10, 4);
182   set(tm->tm_min % 10, 10);
183   set(tm->tm_min / 10, 14);
184   set(tm->tm_hour % 10, 20);
185   set(tm->tm_hour / 10, 24);
186   set(10, 7);
187   set(10, 17);
189   for (k = 0; k < 6; k++) {
190     newer[k] = (newer[k] & ~mask) | (next[k] & mask);
191     next[k] = 0;
192     for (s = 1; s >= 0; s--) {
193       standt(s);
194       for (i = 0; i < 6; i++) {
195         if ((a = (newer[i] ^ older[i]) & (s ? newer : older)[i])
196             != 0) {
197           for (j = 0, t = 1 << 26; t; t >>= 1, j++) {
198             if (a & t) {
199               if (!(a & (t << 1))) {
200                 wmove(win.w, YBASE + i, XBASE + 2 * j);
201               }
202               if( enable_seconds || j<18 )
203                 waddstr(win.w, "  ");
204             }
205           }
206         }
207         if (!s) {
208           older[i] = newer[i];
209         }
210       }
211       if (!s) {
212         wrefresh(win.w);
213       }
214     }
215   }
216   
217 #ifdef HAVE_LOCALE_H
218   strftime(buf, BUFSIZE, "%x", tm);
219 # else
220   /* this depends on the detailed format of ctime(3) */
221   strcpy(buf, ctime(&now));
222   strcpy(buf + 10, buf + 19);
223 #endif
224   mvwaddstr(win.w, YBASE+YDEPTH+1, (win.cols-strlen(buf))/2, buf);
225   
226   wmove(win.w, 6, 0);
227   drawbox();
228   wrefresh(win.w);
231 static void 
232 clock_paint(screen_t *screen, mpdclient_t *c)
234   /* this seems to be a better way to clear the window than wclear() ?! */
235   wmove(win.w, 0, 0);
236   wclrtobot(win.w);
237   clock_update(screen, c);
242 static int 
243 clock_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
245   return 0;
249 screen_functions_t *
250 get_screen_clock(void)
252   static screen_functions_t functions;
254   memset(&functions, 0, sizeof(screen_functions_t));
255   functions.init   = clock_init;
256   functions.exit   = clock_exit;
257   functions.open   = clock_open;
258   functions.close  = clock_close;
259   functions.resize = clock_resize;
260   functions.paint  = clock_paint;
261   functions.update = clock_update;
262   functions.cmd    = clock_cmd;
263   functions.get_lw = NULL;
264   functions.get_title = clock_title;
266   return &functions;
270 #endif