Code

const pointers
[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 #ifndef  DISABLE_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;
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);
77         wmove(win.w, YBASE, XBASE - 1);
78         wvline(win.w, ACS_VLINE, YDEPTH);
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 }
94 /* ncmpc screen functions */
96 static void
97 clock_resize(int cols, int rows)
98 {
99         int j;
101         for (j = 0; j < 5; j++)
102                 older[j] = newer[j] = next[j] = 0;
104         win.cols = cols;
105         win.rows = rows;
107         if (cols < 60)
108                 enable_seconds = FALSE;
109         else
110                 enable_seconds = ENABLE_SECONDS;
112         if (enable_seconds)
113                 XLENGTH = 54;
114         else
115                 XLENGTH = 54-18;
118         XBASE = (cols-XLENGTH)/2;
119         YBASE = (rows-YDEPTH)/2-(YDEPTH/2)+2;
122 static void
123 clock_init(WINDOW *w, int cols, int rows)
125         win.w = w;
126         clock_resize(cols, rows);
129 static void
130 clock_exit(void)
134 static void
135 clock_open(screen_t *screen, mpdclient_t *c)
137         int j;
139         for (j = 0; j < 5; j++)
140                 older[j] = newer[j] = next[j] = 0;
144 static void
145 clock_close(void)
149 static const char *
150 clock_title(char *str, size_t size)
152         return _("Clock");
155 static void
156 clock_update(screen_t *screen, mpdclient_t *c)
158         time_t now;
159         struct tm *tm;
160         long t, a;
161         int i, j, s, k;
162         char buf[BUFSIZE];
164         time(&now);
165         tm = localtime(&now);
167         if (win.rows<=YDEPTH+1 || win.cols<=XLENGTH+1) {
168                 strftime(buf, BUFSIZE, "%X ",tm);
169                 mvwaddstr(win.w, win.rows ? win.rows/2:0, (win.cols-strlen(buf))/2, buf);
170                 wrefresh(win.w);
171                 return;
172         }
174         mask = 0;
175         set(tm->tm_sec % 10, 0);
176         set(tm->tm_sec / 10, 4);
177         set(tm->tm_min % 10, 10);
178         set(tm->tm_min / 10, 14);
179         set(tm->tm_hour % 10, 20);
180         set(tm->tm_hour / 10, 24);
181         set(10, 7);
182         set(10, 17);
184         for (k = 0; k < 6; k++) {
185                 newer[k] = (newer[k] & ~mask) | (next[k] & mask);
186                 next[k] = 0;
187                 for (s = 1; s >= 0; s--) {
188                         standt(s);
189                         for (i = 0; i < 6; i++) {
190                                 if ((a = (newer[i] ^ older[i]) & (s ? newer : older)[i])
191                                     != 0) {
192                                         for (j = 0, t = 1 << 26; t; t >>= 1, j++) {
193                                                 if (a & t) {
194                                                         if (!(a & (t << 1))) {
195                                                                 wmove(win.w, YBASE + i, XBASE + 2 * j);
196                                                         }
197                                                         if( enable_seconds || j<18 )
198                                                                 waddstr(win.w, "  ");
199                                                 }
200                                         }
201                                 }
202                                 if (!s) {
203                                         older[i] = newer[i];
204                                 }
205                         }
206                         if (!s) {
207                                 wrefresh(win.w);
208                         }
209                 }
210         }
212 #ifdef HAVE_LOCALE_H
213         strftime(buf, BUFSIZE, "%x", tm);
214 # else
215         /* this depends on the detailed format of ctime(3) */
216         strcpy(buf, ctime(&now));
217         strcpy(buf + 10, buf + 19);
218 #endif
219         mvwaddstr(win.w, YBASE+YDEPTH+1, (win.cols-strlen(buf))/2, buf);
221         wmove(win.w, 6, 0);
222         drawbox();
223         wrefresh(win.w);
226 static void
227 clock_paint(screen_t *screen, mpdclient_t *c)
229         /* this seems to be a better way to clear the window than wclear() ?! */
230         wmove(win.w, 0, 0);
231         wclrtobot(win.w);
232         clock_update(screen, c);
235 static int
236 clock_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
238         return 0;
241 screen_functions_t *
242 get_screen_clock(void)
244         static screen_functions_t functions;
246         memset(&functions, 0, sizeof(screen_functions_t));
247         functions.init = clock_init;
248         functions.exit = clock_exit;
249         functions.open = clock_open;
250         functions.close = clock_close;
251         functions.resize = clock_resize;
252         functions.paint = clock_paint;
253         functions.update = clock_update;
254         functions.cmd = clock_cmd;
255         functions.get_lw = NULL;
256         functions.get_title = clock_title;
258         return &functions;
261 #endif