ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rclock.C
(Generate patch)

Comparing rxvt-unicode/src/rclock.C (file contents):
Revision 1.1 by root, Mon May 10 00:36:04 2021 UTC vs.
Revision 1.9 by root, Sun Nov 14 17:26:28 2021 UTC

1/*--------------------------------*-C-*---------------------------------* 1/*--------------------------------*-C-*---------------------------------*
2 * Copyright 2021 Marc Lehmann <schmorp@schmorp.de>
3 * Copyright Wolfgang Pietsch
2 * Copyright 1997 1998 Oezguer Kesim <kesim@math.fu-berlin.de> 4 * Copyright 1997 1998 Oezguer Kesim <kesim@math.fu-berlin.de>
3 * Copyright 1992, 1993 Robert Nation <nation@rocket.sanders.lockheed.com> 5 * Copyright 1992, 1993 Robert Nation <nation@rocket.sanders.lockheed.com>
4 * 6 *
5 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
14 * 16 *
15 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *----------------------------------------------------------------------*/ 20 *----------------------------------------------------------------------*/
19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#else
22/* # define STDC_HEADERS */
23# define HAVE_UNISTD_H
24# define TIME_WITH_SYS_TIME
25# define HAVE_SYS_TIME_H
26# ifdef _AIX
27# define HAVE_SYS_SELECT_H
28# endif
29#endif
30
31#include "../src/version.h"
32#include "feature.h"
33
34#include <ctype.h> 21#include <ctype.h>
35/* #ifdef STDC_HEADERS */ 22
36# include <stdarg.h> 23#include <stdarg.h>
37# include <stdio.h> 24#include <stdio.h>
38# include <stdlib.h> 25#include <stdlib.h>
39# include <string.h> 26#include <string.h>
40/* #endif */
41 27
42#ifdef HAVE_UNISTD_H
43# include <unistd.h> 28#include <unistd.h>
44#endif
45 29
46#ifdef TIME_WITH_SYS_TIME
47# include <sys/time.h> 30#include <sys/types.h>
48# include <time.h>
49#else
50# ifdef HAVE_SYS_TIME_H
51# include <sys/time.h>
52# else
53# include <time.h>
54# endif
55#endif
56
57#if defined (__svr4__)
58# include <sys/resource.h> /* for struct rlimit */
59#endif
60
61#ifdef HAVE_SYS_SELECT_H
62# include <sys/select.h> 31#include <sys/select.h>
63#endif
64#include <sys/stat.h> 32#include <sys/stat.h>
65 33
66#ifdef MAIL 34#include <sys/time.h>
35#include <time.h>
36
67#include <dirent.h> 37#include <dirent.h>
68#endif
69 38
70#include <X11/Intrinsic.h> /* Xlib, Xutil, Xresource, Xfuncproto */ 39#include <X11/Xlib.h>
40#include <X11/Xutil.h>
41
42#include "ecb.h"
71 43
72#define APL_CLASS "Clock" 44#define APL_CLASS "Clock"
73#define APL_NAME "rclock" 45#define APL_NAME "rclock"
74#define MSG_CLASS "Appointment" 46#define MSG_CLASS "Appointment"
75#define MSG_NAME "Appointment" 47#define MSG_NAME "Appointment"
76#define CONFIG_FILE ".rclock" 48#define CONFIG_FILE ".rclock"
77 49
78#ifndef EXIT_SUCCESS /* missed from <stdlib.h> ? */ 50#ifndef EXIT_SUCCESS /* missed from <stdlib.h> ? */
79# define EXIT_SUCCESS 0 51# define EXIT_SUCCESS 0
80# define EXIT_FAILURE 1 52# define EXIT_FAILURE 1
81#endif 53#endif
82 54
55#define VERSION "TODO: fetch from urxvt somehow"
56
57/*--------------------------------*-C-*---------------------------------*
58 * Compile-time configuration.
59 *----------------------------------------------------------------------*
60 * Copyright (C) 1997 1998 mj olesen <olesen@me.QueensU.CA>
61 *
62 * This program is free software; you can redistribute it and/or modify
63 * it under the terms of the GNU General Public License as published by
64 * the Free Software Foundation; either version 2 of the License, or
65 * (at your option) any later version.
66 *
67 * This program is distributed in the hope that it will be useful,
68 * but WITHOUT ANY WARRANTY; without even the implied warranty of
69 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
70 * GNU General Public License for more details.
71 *
72 * You should have received a copy of the GNU General Public License
73 * along with this program; if not, write to the Free Software
74 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
75 *----------------------------------------------------------------------*/
76
77/*----------------------------------------------------------------------*
78 * #define ICONWIN
79 * to enable fancy (active) icon
80 *
81 * #define REMINDERS
82 * to enable the appointment reminder functions
83 *
84 * #define NO_REMINDER_EXEC
85 * to disable the execution of a program on an appointment
86 *
87 * #define DATE_ON_CLOCK_FACE
88 * to display today's date on the face of the clock
89 * Note: this requires REMINDERS since it uses the same font
90 *
91 * #define MAIL
92 * to enable xbiff-type mail reminders
93 *
94 * #define MAIL_BELL
95 * to enable xbiff-type mail reminders with a beep
96 *
97 * #define MAIL_SPAWN "xmh\ -font\ 7x14\&"
98 * to define a mail program to run
99 *
100 * #define MAIL_SPOOL "/var/spool/mail/"
101 * to define the mail spool when the $MAIL variable isn't set
102 *
103 * program size approximately doubles from no options to all options
104 *----------------------------------------------------------------------*/
105#define ICONWIN
106#define REMINDERS
107
108/* #define NO_REMINDER_EXEC */
109#define DATE_ON_CLOCK_FACE
110#define MAIL
111
112/* #define MAIL_BELL */ /* TODO: command line switch */
113
114/* #define MAIL_SPAWN "xmh\ -font\ 7x14\&" */ /* TODO: command line switch */
115#define MAIL_SPOOL "/var/spool/mail/"
116
117/*----------------------------------------------------------------------*
118 * #define CLOCKUPDATE 30
119 * to define the frequency (seconds) to update the clock
120 *
121 * #define MAILUPDATE 60
122 * to define the frequency (seconds) to check for new mail
123 *
124 * #define REMINDERS_TIME 10
125 * to define the frequency (minutes) to check ~/.rclock
126 *
127 * #define DEFER_TIME 3
128 * to define the amount (minutes) to defer a message
129 *
130 * #define ADJUST_TIME
131 * to add -adjust command-line option
132 *
133 * #define CENTURY 2000
134 * to set the base century for 2 digit year short-hand
135 *----------------------------------------------------------------------*/
136#define CLOCKUPDATE 30
137#define MAILUPDATE 60
138#define REMINDERS_TIME 10
139#define DEFER_TIME 3
140#define ADJUST_TIME
141
142#define CENTURY 2000 /* TODO: verify */
143
144/*----------------------------------------------------------------------*
145 * #define FONT_NAME "7x14"
146 * to define the font to be used for appointment reminders
147 *
148 * #define FG_COLOR_NAME "black"
149 * #define BG_COLOR_NAME "white"
150 * to define the foreground/background colors to use
151 *----------------------------------------------------------------------*/
152#define FONT_NAME "7x14"
153#define FG_COLOR_NAME "black"
154#define BG_COLOR_NAME "white"
155
156/*----------------------------------------------------------------------*
157 * #define DAY_NAMES "umtwrfs*"
158 * define this string appropriate for any language.
159 *
160 * It starts with a symbol for Sunday, ends with Saturday, then '*'
161 * NOTE: 8 characters total - 7 days of the week plus '*'
162 *----------------------------------------------------------------------*/
163#define DAY_NAMES "umtwrfs*"
164
165/*----------------------------------------------------------------------*
166 * #define SUBTICKS
167 * to show additional minute/second markings
168 *----------------------------------------------------------------------*/
169#define SUBTICKS
170
171/*----------------------------------------------------------------------*
172 * sort out conflicts
173 *----------------------------------------------------------------------*/
174#if defined (MAIL_BELL) || defined (MAIL_SPAWN) || defined (MAIL_SPOOL)
175# ifndef MAIL
176# define MAIL
177# endif
178#endif
179
83/*----------------------------------------------------------------------*/ 180/*----------------------------------------------------------------------*/
181// fourth-order fixed point sine approximation,
182// adapted from https://www.coranac.com/2009/07/sines/
84 183
184static int32_t
185Sin (int32_t arg)
186{
187 int32_t x = (arg - 360) * 16384 / 360;
188
189 int c, y;
190 static const int qN = 13, qA = 12, B = 19900, C = 3516;
191
192 c = x << (30 - qN); // Semi-circle info into carry.
193 x -= 1 << qN; // sine -> cosine calc
194
195 x = x << (31 - qN); // Mask with PI
196 x = x >> (31 - qN); // Note: SIGNED shift! (to qN)
197 x = x * x >> (2 * qN - 14); // x=x^2 To Q14
198
199 y = B - (x * C >> 14); // B - x^2*C
200 y = (1 << qA) - (x * y >> 16); // A - x^2*(B-x^2*C)
201
202 x = c < 0 ? y : -y;
203
204 return x;
205}
206
207/*----------------------------------------------------------------------*/
208
85static Display* Xdisplay; /* X display */ 209static Display *Xdisplay; /* X display */
86static int Xfd; /* file descriptor of server connection */ 210static int Xfd; /* file descriptor of server connection */
87static GC Xgc, Xrvgc; /* normal, reverse video GC */ 211static GC Xgc, Xrvgc; /* normal, reverse video GC */
88 212
89#define Xscreen DefaultScreen (Xdisplay) 213#define Xscreen DefaultScreen (Xdisplay)
90#define Xcmap DefaultColormap (Xdisplay, Xscreen) 214#define Xcmap DefaultColormap (Xdisplay, Xscreen)
91#define Xroot DefaultRootWindow (Xdisplay) 215#define Xroot DefaultRootWindow (Xdisplay)
92 216
93/* windows and their sizes */ 217/* windows and their sizes */
94typedef struct { 218typedef struct
219{
95 Window win; 220 Window win;
96 int width, height; 221 int width, height;
97} mywindow_t; 222} mywindow_t;
98 223
99static mywindow_t Clock = {None, 80, 80}; /* parent window */ 224static mywindow_t Clock = { None, 80, 80 }; /* parent window */
100 225
101#define fgColor 0 226#define fgColor 0
102#define bgColor 1 227#define bgColor 1
103static const char * rs_color [2] = { FG_COLOR_NAME, BG_COLOR_NAME }; 228static const char *rs_color[2] = { FG_COLOR_NAME, BG_COLOR_NAME };
104static Pixel PixColors [2]; 229
230static unsigned long PixColors[2];
105static const char * rs_geometry = NULL; 231static const char *rs_geometry = NULL;
106 232
107#ifdef ICONWIN 233#ifdef ICONWIN
108static const char * rs_iconGeometry = NULL; 234static const char *rs_iconGeometry = NULL;
109static mywindow_t Icon = {None, 65, 65}; /* icon window */ 235static mywindow_t Icon = { None, 65, 65 }; /* icon window */
236
110static int iconic_state = NormalState; /* iconic startup? */ 237static int iconic_state = NormalState; /* iconic startup? */
111#endif 238#endif
112 239
113#ifdef REMINDERS 240#ifdef REMINDERS
114static mywindow_t Msg = {0, 0, 0}; /* message window */ 241static mywindow_t Msg = { 0, 0, 0 }; /* message window */
242
115static struct { 243static struct
244{
116 Window 245 Window
117# ifndef NO_REMINDER_EXEC 246# ifndef NO_REMINDER_EXEC
118 Start, 247 Start,
119# endif 248# endif
120 Dismiss, 249 Dismiss, Defer;
121 Defer;
122 int width, height; 250 int width, height;
123} msgButton; 251} msgButton;
124 252
125static XFontStruct * Xfont; 253static XFontStruct *Xfont;
254
126#define FontHeight() (Xfont->ascent + Xfont->descent) 255# define FontHeight() (Xfont->ascent + Xfont->descent)
127static int Msg_Mapped = 0; /* message window mapped? */ 256static int Msg_Mapped = 0; /* message window mapped? */
128static int reminderTime = -1; 257static int reminderTime = -1;
129static char message [256] = ""; 258static char message[256] = "";
259
130#ifndef NO_REMINDER_EXEC 260# ifndef NO_REMINDER_EXEC
131static char execPrgm [256] = ""; 261static char execPrgm[256] = "";
132#endif 262# endif
133static const char * reminders_file = NULL; /* name of ~/.rclock file */ 263static const char *reminders_file = NULL; /* name of ~/.rclock file */
264
134#ifdef DATE_ON_CLOCK_FACE 265# ifdef DATE_ON_CLOCK_FACE
135static int show_date = 1; /* show date on face of clock */ 266static int show_date = 1; /* show date on face of clock */
136#endif 267# endif
137#endif 268#endif
138 269
139#ifdef ADJUST_TIME 270#ifdef ADJUST_TIME
140static int adjustTime = 0; 271static int adjustTime = 0;
141#else 272#else
142# define adjustTime 0 273# define adjustTime 0
143#endif 274#endif
144 275
145#ifdef CENTURY 276#ifdef CENTURY
146# if (CENTURY < 1900) 277# if (CENTURY < 1900)
147Error, Cenury incorrectly set. 278Error, Century incorrectly set.
148# endif 279# endif
149#else 280#else
150# define CENTURY 1900 281# define CENTURY 1900
151#endif 282#endif
152 283
153static int clockUpdate = CLOCKUPDATE; 284static int clockUpdate = CLOCKUPDATE;
154 285
155#ifdef MAIL 286#ifdef MAIL
156static int mailUpdate = MAILUPDATE; 287static int mailUpdate = MAILUPDATE;
157static char * mail_file = NULL; 288static char *mail_file = NULL;
289
158#ifndef MAIL_SPAWN 290# ifndef MAIL_SPAWN
159static char * mail_spawn = NULL; 291static char *mail_spawn = NULL;
160#endif 292# endif
161static int is_maildir = 0; 293static int is_maildir = 0;
162#endif 294#endif
163 295
164static XSizeHints szHint = { 296static XSizeHints szHint = {
165 PMinSize | PResizeInc | PBaseSize | PWinGravity, 297 PMinSize | PResizeInc | PBaseSize | PWinGravity,
166 0, 0, 80, 80, /* x, y, width and height */ 298 0, 0, 80, 80, /* x, y, width and height */
167 1, 1, /* Min width and height */ 299 1, 1, /* Min width and height */
168 0, 0, /* Max width and height */ 300 0, 0, /* Max width and height */
169 1, 1, /* Width and height increments */ 301 1, 1, /* Width and height increments */
170 {1, 1}, /* x, y increments */ 302 {1, 1}, /* x, y increments */
171 {1, 1}, /* Aspect ratio - not used */ 303 {1, 1}, /* Aspect ratio - not used */
172 0, 0, /* base size */ 304 0, 0, /* base size */
173 NorthWestGravity /* gravity */ 305 NorthWestGravity /* gravity */
174}; 306};
175 307
176/* subroutine declarations */ 308/* subroutine declarations */
177static void geometry2sizehint (mywindow_t * /* win */, 309static void geometry2sizehint (mywindow_t *win, const char *geom);
178 const char * /* geom */);
179static void Create_Windows (int /* argc */, 310static void Create_Windows (int argc, char *argv[]);
180 char * /* argv */ []);
181static void getXevent (void); 311static void getXevent ();
182static void print_error (const char * /* fmt */, ...); 312static void print_error (const char *fmt, ...);
183 313
184static void Draw_Window (mywindow_t * /* this_win */, 314static void Draw_Window (mywindow_t *this_win, int full_redraw);
185 int /* full_redraw */);
186static void Reminder (void); 315static void Reminder ();
187static void Next_Reminder (int /* update_only */); 316static void Next_Reminder (int update_only);
188 317
189/* Arguments for Next_Reminder() */ 318/* Arguments for Next_Reminder() */
190#define REPLACE 0 319#define REPLACE 0
191#define UPDATE 1 320#define UPDATE 1
192 321
193/*----------------------------------------------------------------------*/ 322/*----------------------------------------------------------------------*/
194 323
195static void 324static void
196usage (void) 325usage ()
197{ 326{
198 int i; 327 int i;
199 struct { 328 struct
329 {
200 const char * const opt; 330 const char *const opt;
201 const char * const desc; 331 const char *const desc;
202 } optList[] = { 332 } optList[] = {
203#define optList_size() (sizeof(optList)/sizeof(optList[0])) 333#define optList_size() (sizeof (optList) / sizeof (optList[0]))
204 { "-display displayname", "X server to contact" }, 334 {"-display displayname", "X server to contact"},
205 { "-geometry geom", "size (in pixels) and position" }, 335 {"-geometry geom", "size (in pixels) and position"},
206 { "-bg color", "background color" }, 336 {"-bg color", "background color"},
207 { "-fg color", "foreground color" }, 337 {"-fg color", "foreground color"},
208#ifdef REMINDERS 338#ifdef REMINDERS
209 { "-fn fontname", "normal font for messages" }, 339 {"-fn fontname", "normal font for messages"},
210#ifdef DATE_ON_CLOCK_FACE 340# ifdef DATE_ON_CLOCK_FACE
211 { "-nodate", "do not display date on the clock face" }, 341 {"-nodate", "do not display date on the clock face"},
212#endif 342# endif
213#endif 343#endif
214#ifdef ICONWIN 344#ifdef ICONWIN
215 { "-iconic", "start iconic" }, 345 {"-iconic", "start iconic"},
216#endif 346#endif
217#ifdef ADJUST_TIME 347#ifdef ADJUST_TIME
218 { "-adjust +/-ddhhmm", "adjust clock time" }, 348 {"-adjust +/-ddhhmm", "adjust clock time"},
219#endif 349#endif
220 { "-update seconds", "clock update interval" }, 350 {"-update seconds", "clock update interval"},
221#ifdef MAIL 351#ifdef MAIL
222 { "-mail seconds", "check $MAIL interval" }, 352 {"-mail seconds", "check $MAIL interval"},
223 { "-mailfile file", "file to use for mail checking" }, 353 {"-mailfile file", "file to use for mail checking"},
224#ifndef MAIL_SPAWN 354# ifndef MAIL_SPAWN
225 { "-mailspawn cmd", "execute `cmd` when clock is clicked" }, 355 {"-mailspawn cmd", "execute `cmd` when clock is clicked"},
226#endif 356# endif
227#endif 357#endif
228 { "#geom", "icon window geometry" } 358 {"#geom", "icon window geometry"}
229 }; 359 };
230 360
231 fprintf (stderr, "\nUsage v" VERSION ":\n " APL_NAME " [options]\n\n" 361 fprintf (stderr, "\nUsage v" VERSION ":\n " APL_NAME " [options]\n\n" "where options include:\n");
232 "where options include:\n");
233 362
234 for (i = 0; i < optList_size(); i++) 363 for (i = 0; i < (int)optList_size (); i++)
235 fprintf (stderr, " %-29s%s\n", optList[i].opt, optList[i].desc); 364 fprintf (stderr, " %-29s%s\n", optList[i].opt, optList[i].desc);
236} 365}
237 366
238 367
239/**************** 368/****************
240 * Check out if we are using a maildir drop (qmail) 369 * Check out if we are using a maildir drop (qmail)
241 * Note: this changes mail_dir to hold the "new" diretory 370 * Note: this changes mail_dir to hold the "new" diretory
242 */ 371 */
243#ifdef MAIL 372#ifdef MAIL
244static void 373static void
245CheckMaildir() 374CheckMaildir ()
246{ 375{
247 struct stat st; 376 struct stat st;
248 char *buf, *p; 377 char *buf, *p;
249 378
250 if( !*mail_file || stat(mail_file, &st) || !S_ISDIR(st.st_mode) ) 379 if (!*mail_file || stat (mail_file, &st) || !S_ISDIR (st.st_mode))
251 return; /* no */ 380 return; /* no */
252 381
253 if( !(buf = malloc(strlen(mail_file)+5)) ) { 382 if (!(buf = (char *) malloc (strlen (mail_file) + 5)))
383 {
254 print_error ("malloc error"); 384 print_error ("malloc error");
255 exit( EXIT_FAILURE ); 385 exit (EXIT_FAILURE);
256 } 386 }
257 strcpy(buf,mail_file); 387 strcpy (buf, mail_file);
258 p = buf+strlen(buf); 388 p = buf + strlen (buf);
259 if( p[-1] != '/' ) 389 if (p[-1] != '/')
260 *p++ = '/'; 390 *p++ = '/';
261 391
262 strcpy(p, "tmp" ); 392 strcpy (p, "tmp");
263 if( stat(buf, &st) || !S_ISDIR(st.st_mode ) ) 393 if (stat (buf, &st) || !S_ISDIR (st.st_mode))
264 goto leave; 394 goto leave;
265 strcpy(p, "cur" ); 395 strcpy (p, "cur");
266 if( stat(buf, &st) || !S_ISDIR(st.st_mode ) ) 396 if (stat (buf, &st) || !S_ISDIR (st.st_mode))
267 goto leave; 397 goto leave;
268 strcpy(p, "new" ); 398 strcpy (p, "new");
269 if( stat(buf, &st) || !S_ISDIR(st.st_mode ) ) 399 if (stat (buf, &st) || !S_ISDIR (st.st_mode))
270 goto leave; 400 goto leave;
271 401
272 mail_file = buf; 402 mail_file = buf;
273 is_maildir = 1; 403 is_maildir = 1;
274 return; 404 return;
275 leave: 405leave:
276 free(buf); 406 free (buf);
277} 407}
278#endif 408#endif
279 409
280/*----------------------------------------------------------------------* 410/*----------------------------------------------------------------------*
281 * rclock - Rob's clock 411 * rclock - Rob's clock
282 * simple X windows clock with appointment reminder 412 * simple X windows clock with appointment reminder
283 *----------------------------------------------------------------------*/ 413 *----------------------------------------------------------------------*/
284int 414int
285main (int argc, char * argv []) 415main (int argc, char *argv[])
286{ 416{
287 int i; 417 int i;
288 char * opt, * val; 418 char *opt, *val;
289 const char * display_name = NULL; 419 const char *display_name = NULL;
290 XGCValues gcv; 420 XGCValues gcv;
291 421
292#ifdef REMINDERS 422#ifdef REMINDERS
293 const char * rs_font = FONT_NAME; 423 const char *rs_font = FONT_NAME;
294 424
295 /* find the ~/.rclock file */ 425 /* find the ~/.rclock file */
296 if ((val = getenv ("HOME")) != NULL) 426 if ((val = getenv ("HOME")) != NULL)
297 { 427 {
298 char * p = malloc (strlen (CONFIG_FILE) + strlen (val) + 2); 428 char *p = (char *) malloc (strlen (CONFIG_FILE) + strlen (val) + 2);
429
299 if (p == NULL) 430 if (p == NULL)
300 goto Malloc_Error; 431 goto Malloc_Error;
301 432
302 strcpy (p, val); 433 strcpy (p, val);
303 strcat (p, "/" CONFIG_FILE); 434 strcat (p, "/" CONFIG_FILE);
304 435
305 reminders_file = p; 436 reminders_file = p;
306 } 437 }
307#endif 438#endif
308#ifdef MAIL 439#ifdef MAIL
309 val = getenv ("MAIL"); /* get the mail spool file name */ 440 val = getenv ("MAIL"); /* get the mail spool file name */
310#ifdef MAIL_SPOOL 441# ifdef MAIL_SPOOL
311 if (val == NULL) /* csh doesn't set $MAIL */ 442 if (val == NULL) /* csh doesn't set $MAIL */
312 { 443 {
313 const char * spool = MAIL_SPOOL; 444 const char *spool = MAIL_SPOOL;
314 char * user = getenv ("USER"); /* assume this works */ 445 char *user = getenv ("USER"); /* assume this works */
446
447 if (user != NULL)
448 {
315 val = malloc (strlen (spool) + strlen (user) + 1); 449 val = (char *) malloc (strlen (spool) + strlen (user) + 1);
316 if (val == NULL) 450 if (val == NULL)
317 goto Malloc_Error; 451 goto Malloc_Error;
318 strcpy (val, spool); 452 strcpy (val, spool);
319 strcat (val, user); 453 strcat (val, user);
454 }
320 } 455 }
321#endif 456# endif
322 mail_file = val; 457 mail_file = val;
323 if( mail_file ) 458 if (mail_file)
324 CheckMaildir(); 459 CheckMaildir ();
325#endif 460#endif
326 461
327 if ((display_name = getenv ("DISPLAY")) == NULL)
328 display_name = ":0";
329
330 /* parse the command line */ 462 /* parse the command line */
331 for (i = 1; i < argc; i += 2) 463 for (i = 1; i < argc; i += 2)
332 { 464 {
333 opt = argv [i]; 465 opt = argv[i];
334 val = argv [i+1]; 466 val = argv[i + 1];
335 467
336 switch (*opt++) { 468 switch (*opt++)
337 case '-': 469 {
338 break; 470 case '-':
471 break;
339 472
340 case '#': 473 case '#':
341#ifdef ICONWIN 474#ifdef ICONWIN
342 rs_iconGeometry = opt; /* drop */ 475 rs_iconGeometry = opt; /* drop */
343#endif 476#endif
344 default: 477 default:
345 continue; 478 continue;
346 break; 479 break;
347 } 480 }
348 481
349 if (*opt == 'd' && val) display_name = val; /* "d", "display" */ 482 if (*opt == 'd' && val)
350 else if (*opt == 'g' && val) rs_geometry = val; /* "g", "geometry" */ 483 display_name = val; /* "d", "display" */
484 else if (*opt == 'g' && val)
485 rs_geometry = val; /* "g", "geometry" */
351#ifdef ICONWIN 486#ifdef ICONWIN
352 else if (*opt == 'i') /* "ic", "iconic" */ 487 else if (*opt == 'i') /* "ic", "iconic" */
353 { 488 {
354 iconic_state = IconicState; 489 iconic_state = IconicState;
355 i--; /* no argument */ 490 i--; /* no argument */
356 } 491 }
357#endif 492#endif
358 else if (!strcmp (opt, "fg") && val) rs_color [fgColor] = val; 493 else if (!strcmp (opt, "fg") && val)
359 else if (!strcmp (opt, "bg") && val) rs_color [bgColor] = val; 494 rs_color[fgColor] = val;
495 else if (!strcmp (opt, "bg") && val)
496 rs_color[bgColor] = val;
360#ifdef REMINDERS 497#ifdef REMINDERS
361 else if (!strcmp (opt, "fn") && val) rs_font = val; 498 else if (!strcmp (opt, "fn") && val)
499 rs_font = val;
362#ifdef DATE_ON_CLOCK_FACE 500# ifdef DATE_ON_CLOCK_FACE
363 else if (!strcmp (opt, "nodate")) 501 else if (!strcmp (opt, "nodate"))
364 { 502 {
365 show_date = 0; 503 show_date = 0;
366 i--; /* no argument */ 504 i--; /* no argument */
367 } 505 }
368#endif 506# endif
369#endif 507#endif
370 else if (!strcmp (opt, "update") && val) 508 else if (!strcmp (opt, "update") && val)
371 { 509 {
372 int x = atoi (val); 510 int x = atoi (val);
511
373 if (x < 1 || x > 60) 512 if (x < 1 || x > 60)
374 print_error ("update: %d sec", clockUpdate); 513 print_error ("update: %d sec", clockUpdate);
375 else 514 else
376 clockUpdate = x; 515 clockUpdate = x;
377 } 516 }
378#ifdef MAIL 517#ifdef MAIL
379 else if (!strcmp (opt, "mail") && val) 518 else if (!strcmp (opt, "mail") && val)
380 { 519 {
381 int x = atoi (val); 520 int x = atoi (val);
521
382 if (x < 1) 522 if (x < 1)
383 print_error ("mail update: %d sec", mailUpdate); 523 print_error ("mail update: %d sec", mailUpdate);
384 else 524 else
385 mailUpdate = x; 525 mailUpdate = x;
386 } 526 }
387 else if (!strcmp (opt, "mailfile") && val) 527 else if (!strcmp (opt, "mailfile") && val)
388 { 528 {
389 /* If the mail environment is not set, then mail_file was created 529 /* If the mail environment is not set, then mail_file was created
390 * with a malloc. We need to free it. 530 * with a malloc. We need to free it.
391 */ 531 */
392 if( getenv ("MAIL") == NULL) 532 if (getenv ("MAIL") == NULL)
393 free( mail_file); 533 free (mail_file);
394 /* assume user knows what he's doing, don't check that file is valid...*/ 534 /* assume user knows what he's doing, don't check that file is valid... */
395 mail_file = val; 535 mail_file = val;
396 } 536 }
397#ifndef MAIL_SPAWN 537# ifndef MAIL_SPAWN
398 else if (!strcmp (opt, "mailspawn") && val) 538 else if (!strcmp (opt, "mailspawn") && val)
399 { 539 {
400 mail_spawn = val; 540 mail_spawn = val;
401 } 541 }
402#endif 542# endif
403#endif /* MAIL */ 543#endif /* MAIL */
404#ifdef ADJUST_TIME 544#ifdef ADJUST_TIME
405 else if (!strcmp (opt, "adjust") && val) 545 else if (!strcmp (opt, "adjust") && val)
406 { 546 {
407 /* convert ddhhmm to seconds, minimal error checking */ 547 /* convert ddhhmm to seconds, minimal error checking */
408 int x = atoi (val); 548 int x = atoi (val);
549
409 adjustTime = ((((abs (x) / 10000) % 100) * 24 /* days */ 550 adjustTime = ((((abs (x) / 10000) % 100) * 24 /* days */
410 + ((abs (x) / 100) % 100)) * 60 /* hours */ 551 + ((abs (x) / 100) % 100)) * 60 /* hours */
411 + (abs (x) % 100)) * 60; /* minutes */ 552 + (abs (x) % 100)) * 60; /* minutes */
412 if (x < 0) 553 if (x < 0)
413 adjustTime = -adjustTime; 554 adjustTime = -adjustTime;
414 } 555 }
415#endif /* ADJUST_TIME */ 556#endif /* ADJUST_TIME */
416 else 557 else
417 { 558 {
418 usage (); 559 usage ();
419 goto Abort; 560 goto Abort;
420 } 561 }
421 } 562 }
422 563
423 /* open display */ 564 /* open display */
424 Xdisplay = XOpenDisplay (display_name); 565 Xdisplay = XOpenDisplay (display_name);
425 if (!Xdisplay) 566 if (!Xdisplay)
426 { 567 {
427 print_error ("can't open display %s", display_name); 568 print_error ("can't open display %s", display_name ? display_name :
569 getenv ("DISPLAY") ? getenv ("DISPLAY") : "as no -d given and DISPLAY not set");
428 goto Abort; 570 goto Abort;
429 } 571 }
430 572
431 /* get display info */ 573 /* get display info */
432 Xfd = XConnectionNumber (Xdisplay); 574 Xfd = XConnectionNumber (Xdisplay);
433 { 575 {
434 const char * const color_msg = "can't load color \"%s\""; 576 const char *const color_msg = "can't load color \"%s\"";
435 XColor xcol; 577 XColor xcol;
436 578
437 /* allocate foreground/background colors */ 579 /* allocate foreground/background colors */
438 if (!XParseColor (Xdisplay, Xcmap, rs_color [fgColor], &xcol) || 580 if (!XParseColor (Xdisplay, Xcmap, rs_color[fgColor], &xcol) || !XAllocColor (Xdisplay, Xcmap, &xcol))
439 !XAllocColor (Xdisplay, Xcmap, &xcol)) 581 {
440 {
441 print_error (color_msg, rs_color [fgColor]); 582 print_error (color_msg, rs_color[fgColor]);
442 goto Abort; 583 goto Abort;
443 } 584 }
444 PixColors [fgColor] = xcol.pixel; 585 PixColors[fgColor] = xcol.pixel;
445 586
446 if (!XParseColor (Xdisplay, Xcmap, rs_color [bgColor], &xcol) || 587 if (!XParseColor (Xdisplay, Xcmap, rs_color[bgColor], &xcol) || !XAllocColor (Xdisplay, Xcmap, &xcol))
447 !XAllocColor (Xdisplay, Xcmap, &xcol)) 588 {
448 {
449 print_error (color_msg, rs_color [bgColor]); 589 print_error (color_msg, rs_color[bgColor]);
450 goto Abort; 590 goto Abort;
451 }
452 PixColors [bgColor] = xcol.pixel;
453 } 591 }
592 PixColors[bgColor] = xcol.pixel;
593 }
454 594
455#ifdef REMINDERS 595#ifdef REMINDERS
456 /* load the font for messages */ 596 /* load the font for messages */
457 if ((Xfont = XLoadQueryFont (Xdisplay, rs_font)) == NULL) 597 if ((Xfont = XLoadQueryFont (Xdisplay, rs_font)) == NULL)
458 { 598 {
459 print_error ("can't load font \"%s\"", rs_font); 599 print_error ("can't load font \"%s\"", rs_font);
460 goto Abort; 600 goto Abort;
461 } 601 }
462 gcv.font = Xfont->fid; 602 gcv.font = Xfont->fid;
463#endif 603#endif
464 604
465 Create_Windows (argc, argv); 605 Create_Windows (argc, argv);
466 /* Create the graphics contexts */ 606 /* Create the graphics contexts */
467 gcv.foreground = PixColors [fgColor]; 607 gcv.foreground = PixColors[fgColor];
468 gcv.background = PixColors [bgColor]; 608 gcv.background = PixColors[bgColor];
469 609
470 Xgc = XCreateGC (Xdisplay, Clock.win, 610 Xgc = XCreateGC (Xdisplay, Clock.win,
471#ifdef REMINDERS 611#ifdef REMINDERS
472 GCFont | 612 GCFont |
473#endif 613#endif
474 GCForeground | GCBackground, &gcv); 614 GCForeground | GCBackground, &gcv);
475 615
476 gcv.foreground = PixColors [bgColor]; 616 gcv.foreground = PixColors[bgColor];
477 gcv.background = PixColors [fgColor]; 617 gcv.background = PixColors[fgColor];
478 Xrvgc = XCreateGC (Xdisplay, Clock.win, 618 Xrvgc = XCreateGC (Xdisplay, Clock.win,
479#ifdef REMINDERS 619#ifdef REMINDERS
480 GCFont | 620 GCFont |
481#endif 621#endif
482 GCForeground | GCBackground, &gcv); 622 GCForeground | GCBackground, &gcv);
483 623
484 getXevent (); 624 getXevent ();
485 return EXIT_SUCCESS; 625 return EXIT_SUCCESS;
486 626
487 Malloc_Error: 627Malloc_Error:
488 print_error ("malloc error"); 628 print_error ("malloc error");
489 Abort: 629Abort:
490 print_error ("aborting"); 630 print_error ("aborting");
491 return EXIT_FAILURE; 631 return EXIT_FAILURE;
492} 632}
493 633
494/* 634/*
495 * translate geometry string to appropriate sizehint 635 * translate geometry string to appropriate sizehint
496 */ 636 */
497static void 637static void
498geometry2sizehint (mywindow_t * win, const char * geom) 638geometry2sizehint (mywindow_t *win, const char *geom)
499{ 639{
500 int x, y, flags; 640 int x, y, flags;
501 unsigned int width, height; 641 unsigned int width, height;
502 642
503 /* copy in values */ 643 /* copy in values */
504 szHint.width = win->width; 644 szHint.width = win->width;
505 szHint.height = win->height; 645 szHint.height = win->height;
506 646
507 if (geom == NULL) 647 if (geom == NULL)
508 return; 648 return;
509 649
510 flags = XParseGeometry (geom, &x, &y, &width, &height); 650 flags = XParseGeometry (geom, &x, &y, &width, &height);
511 651
512 if (flags & WidthValue) 652 if (flags & WidthValue)
513 { 653 {
514 szHint.width = width + szHint.base_width; 654 szHint.width = width + szHint.base_width;
515 szHint.flags |= USSize; 655 szHint.flags |= USSize;
516 } 656 }
517 if (flags & HeightValue) 657 if (flags & HeightValue)
518 { 658 {
519 szHint.height = height + szHint.base_height; 659 szHint.height = height + szHint.base_height;
520 szHint.flags |= USSize; 660 szHint.flags |= USSize;
521 } 661 }
522 662
523 if (flags & XValue) 663 if (flags & XValue)
524 { 664 {
525 if (flags & XNegative) 665 if (flags & XNegative)
526 { 666 {
527 x += (DisplayWidth (Xdisplay, Xscreen) - szHint.width); 667 x += (DisplayWidth (Xdisplay, Xscreen) - szHint.width);
528 szHint.win_gravity = NorthEastGravity; 668 szHint.win_gravity = NorthEastGravity;
529 } 669 }
530 szHint.x = x; 670 szHint.x = x;
531 szHint.flags |= USPosition; 671 szHint.flags |= USPosition;
532 } 672 }
533 if (flags & YValue) 673 if (flags & YValue)
534 { 674 {
535 if (flags & YNegative) 675 if (flags & YNegative)
536 { 676 {
537 y += (DisplayHeight (Xdisplay, Xscreen) - szHint.height); 677 y += (DisplayHeight (Xdisplay, Xscreen) - szHint.height);
538 szHint.win_gravity = (szHint.win_gravity == NorthEastGravity ? 678 szHint.win_gravity = (szHint.win_gravity == NorthEastGravity ? SouthEastGravity : SouthWestGravity);
539 SouthEastGravity : SouthWestGravity); 679 }
540 }
541 szHint.y = y; 680 szHint.y = y;
542 szHint.flags |= USPosition; 681 szHint.flags |= USPosition;
543 } 682 }
544 683
545 /* copy out values */ 684 /* copy out values */
546 win->width = szHint.width; 685 win->width = szHint.width;
547 win->height = szHint.height; 686 win->height = szHint.height;
548} 687}
549 688
550/* 689/*
551 * Open and map the windows 690 * Open and map the windows
552 */ 691 */
553static void 692static void
554Create_Windows (int argc, char * argv []) 693Create_Windows (int argc, char *argv[])
555{ 694{
556 XClassHint classHint; 695 XClassHint classHint;
557 XWMHints wmHint; 696 XWMHints wmHint;
558 697
559 geometry2sizehint (&Clock, rs_geometry); 698 geometry2sizehint (&Clock, rs_geometry);
560 Clock.win = XCreateSimpleWindow (Xdisplay, Xroot, 699 Clock.win = XCreateSimpleWindow (Xdisplay, Xroot,
561 szHint.x, szHint.y, 700 szHint.x, szHint.y, Clock.width, Clock.height, 0, PixColors[fgColor], PixColors[bgColor]);
562 Clock.width, Clock.height,
563 0,
564 PixColors [fgColor],
565 PixColors [bgColor]);
566 701
567#ifdef ICONWIN 702#ifdef ICONWIN
568 geometry2sizehint (&Icon, rs_iconGeometry); 703 geometry2sizehint (&Icon, rs_iconGeometry);
569 Icon.win = XCreateSimpleWindow (Xdisplay, Xroot, 704 Icon.win = XCreateSimpleWindow (Xdisplay, Xroot, szHint.x, szHint.y, Icon.width, Icon.height, 0, PixColors[fgColor], PixColors[bgColor]);
570 szHint.x, szHint.y,
571 Icon.width, Icon.height,
572 0,
573 PixColors [fgColor],
574 PixColors [bgColor]);
575 wmHint.initial_state = iconic_state; 705 wmHint.initial_state = iconic_state;
576 wmHint.icon_window = Icon.win; 706 wmHint.icon_window = Icon.win;
577 wmHint.flags = InputHint | StateHint | IconWindowHint; 707 wmHint.flags = InputHint | StateHint | IconWindowHint;
578#else 708#else
579 wmHint.flags = InputHint; 709 wmHint.flags = InputHint;
580#endif 710#endif
581 wmHint.input = True; 711 wmHint.input = True;
582 712
583 /* ignore warning about discarded `const' */
584 classHint.res_name = APL_NAME; 713 classHint.res_name = (char *)APL_NAME;
585 classHint.res_class = APL_CLASS; 714 classHint.res_class = (char *)APL_CLASS;
586 XSetWMProperties (Xdisplay, Clock.win, NULL, NULL, argv, argc, 715 XSetWMProperties (Xdisplay, Clock.win, NULL, NULL, argv, argc, &szHint, &wmHint, &classHint);
587 &szHint, &wmHint, &classHint);
588 716
589 XSelectInput (Xdisplay, Clock.win, 717 XSelectInput (Xdisplay, Clock.win, (ExposureMask | StructureNotifyMask | ButtonPressMask));
590 (ExposureMask|StructureNotifyMask|ButtonPressMask));
591 718
592#ifdef ICONWIN 719#ifdef ICONWIN
593 XSelectInput (Xdisplay, Icon.win, 720 XSelectInput (Xdisplay, Icon.win, (ExposureMask | ButtonPressMask));
594 (ExposureMask|ButtonPressMask));
595#endif 721#endif
596 XMapWindow (Xdisplay, Clock.win); 722 XMapWindow (Xdisplay, Clock.win);
597 723
598 /* create, but don't map a window for appointment reminders */ 724 /* create, but don't map a window for appointment reminders */
599#ifdef REMINDERS 725#ifdef REMINDERS
600 Msg.win = XCreateSimpleWindow (Xdisplay, Xroot, 726 Msg.win = XCreateSimpleWindow (Xdisplay, Xroot,
601 szHint.x, szHint.y, 727 szHint.x, szHint.y, szHint.width, szHint.height, 0, PixColors[fgColor], PixColors[bgColor]);
602 szHint.width, szHint.height,
603 0,
604 PixColors [fgColor],
605 PixColors [bgColor]);
606 728
607 szHint.flags |= USPosition; 729 szHint.flags |= USPosition;
608 /* ignore warning about discarded `const' */ 730 /* ignore warning about discarded `const' */
609 classHint.res_name = MSG_NAME; 731 classHint.res_name = (char *)MSG_NAME;
610 classHint.res_class = MSG_CLASS; 732 classHint.res_class = (char *)MSG_CLASS;
611 wmHint.input = True; 733 wmHint.input = True;
612 wmHint.flags = InputHint; 734 wmHint.flags = InputHint;
613 735
614 XSetWMProperties (Xdisplay, Msg.win, NULL, NULL, argv, argc, 736 XSetWMProperties (Xdisplay, Msg.win, NULL, NULL, argv, argc, &szHint, &wmHint, &classHint);
615 &szHint, &wmHint, &classHint); 737
616 { 738 {
617 char * str = MSG_NAME; 739 const char *str = MSG_NAME;
740
618 XStoreName (Xdisplay, Msg.win, str); 741 XStoreName (Xdisplay, Msg.win, str);
619 XSetIconName (Xdisplay, Msg.win, str); 742 XSetIconName (Xdisplay, Msg.win, str);
620 } 743 }
621 744
622 XSelectInput (Xdisplay, Msg.win, 745 XSelectInput (Xdisplay, Msg.win, (ExposureMask | ButtonPressMask | KeyPressMask));
623 (ExposureMask|ButtonPressMask|KeyPressMask));
624 746
625 /* font already loaded */ 747 /* font already loaded */
626 748
627 msgButton.width = 4 + 5 * XTextWidth (Xfont, "M", 1); 749 msgButton.width = 4 + 5 * XTextWidth (Xfont, "M", 1);
628 msgButton.height = 4 + FontHeight (); 750 msgButton.height = 4 + FontHeight ();
629 751
630 msgButton.Dismiss = XCreateSimpleWindow (Xdisplay, Msg.win, 752 msgButton.Dismiss = XCreateSimpleWindow (Xdisplay, Msg.win,
631 0, 0, 753 0, 0, msgButton.width, msgButton.height, 0, PixColors[bgColor], PixColors[fgColor]);
632 msgButton.width, msgButton.height,
633 0,
634 PixColors [bgColor],
635 PixColors [fgColor]);
636 754
637 XMapWindow (Xdisplay, msgButton.Dismiss); 755 XMapWindow (Xdisplay, msgButton.Dismiss);
638 756
639 msgButton.Defer = XCreateSimpleWindow (Xdisplay, Msg.win, 757 msgButton.Defer = XCreateSimpleWindow (Xdisplay, Msg.win,
640 0, 0, 758 0, 0, msgButton.width, msgButton.height, 0, PixColors[bgColor], PixColors[fgColor]);
641 msgButton.width, msgButton.height,
642 0,
643 PixColors [bgColor],
644 PixColors [fgColor]);
645 XMapWindow (Xdisplay, msgButton.Defer); 759 XMapWindow (Xdisplay, msgButton.Defer);
646 760
647#ifndef NO_REMINDER_EXEC 761# ifndef NO_REMINDER_EXEC
648 msgButton.Start = XCreateSimpleWindow (Xdisplay, Msg.win, 762 msgButton.Start = XCreateSimpleWindow (Xdisplay, Msg.win,
649 0, 0, 763 0, 0, msgButton.width, msgButton.height, 0, PixColors[bgColor], PixColors[fgColor]);
650 msgButton.width, msgButton.height,
651 0,
652 PixColors [bgColor],
653 PixColors [fgColor]);
654 XMapWindow (Xdisplay, msgButton.Start); 764 XMapWindow (Xdisplay, msgButton.Start);
655#endif /* NO_REMINDER_EXEC */ 765# endif/* NO_REMINDER_EXEC */
656#endif 766#endif
657} 767}
658 768
659static time_t 769static time_t
660mk_time (struct tm * tmval) 770mk_time (struct tm *tmval)
661{ 771{
662 return (tmval->tm_min 772 return (tmval->tm_min
663 + 60 * (tmval->tm_hour 773 + 60 * (tmval->tm_hour
664 + 24 * (tmval->tm_mday 774 + 24 * (tmval->tm_mday
665 + 31 * ((tmval->tm_mon+1) 775 + 31 * ((tmval->tm_mon + 1)
666 + 12 * tmval->tm_year)))); 776 + 12 * tmval->tm_year))));
667} 777}
668
669 778
670#ifdef MAIL 779#ifdef MAIL
671static int 780static int
672MailAvailable() 781MailAvailable ()
673{ 782{
674 struct stat st; 783 struct stat st;
675 784
676 if( is_maildir ) { 785 if (is_maildir)
677 DIR *dirp; 786 {
787 DIR *dirp;
678 struct dirent *d; 788 struct dirent *d;
679 789
680 if( (dirp=opendir( mail_file )) ) { 790 if ((dirp = opendir (mail_file)))
791 {
681 while( (d=readdir(dirp)) ) { 792 while ((d = readdir (dirp)))
682 if( *d->d_name == '.' ) 793 {
683 continue; 794 if (*d->d_name == '.')
684 if( isdigit(*d->d_name) ) { 795 continue;
796 if (isdigit (*d->d_name))
797 {
798 closedir (dirp);
799 return 1;
800 }
801 }
685 closedir(dirp); 802 closedir (dirp);
803 }
686 return 1; 804 return 0;
687 }
688 } 805 }
689 closedir(dirp);
690 }
691 return 0;
692 }
693 else 806 else
694 return !stat(mail_file, &st) && 807 return !stat (mail_file, &st) && (st.st_size > 0) && (st.st_mtime >= st.st_atime);
695 (st.st_size > 0) && (st.st_mtime >= st.st_atime);
696} 808}
697#endif 809#endif
698 810
699/*----------------------------------------------------------------------* 811/*----------------------------------------------------------------------*
700 * Redraw the whole window after an exposure or size change. 812 * Redraw the whole window after an exposure or size change.
701 * After a timeout, only redraw the hands. 813 * After a timeout, only redraw the hands.
702 * Provide reminder if needed. 814 * Provide reminder if needed.
703 *----------------------------------------------------------------------*/ 815 *----------------------------------------------------------------------*/
704static void 816static void
705Draw_Window (mywindow_t * W, int full_redraw) 817Draw_Window (mywindow_t *W, int full_redraw)
706{ 818{
707 /* pre-computed values for sin() x1000, to avoid using floats */
708 static const short Sin [60] = {
709 0,
710 105, 208, 309, 407, 500, 588, 669,
711 743, 809, 866, 914, 951, 978, 995,
712 1000,
713 995, 978, 951, 914, 866, 809, 743,
714 669, 588, 500, 407, 309, 208, 105,
715 0,
716 -105, -208, -309, -407, -500, -588, -669,
717 -743, -809, -866, -914, -951, -978, -995,
718 -1000,
719 -995, -978, -951, -914, -866, -809, -743,
720 -669, -588, -500, -407, -309, -208, -105
721 };
722
723 static int savedDay = -1; 819 static int savedDay = -1;
724 820
725 time_t currentTime; 821 time_t currentTime;
726 struct tm * tmval; 822 struct tm *tmval;
727 int ctr_x, ctr_y; 823 int ctr_x, ctr_y;
728 824
729 typedef struct { 825 typedef struct
730 int h_x, h_y; /* hour */ 826 {
827 int h_x, h_y; /* hour */
731 int m_x, m_y; /* minute */ 828 int m_x, m_y; /* minute */
732 int s_x, s_y; /* second */ 829 int s_x, s_y; /* second */
733 } hands_t; /* hand positions (x,y) */ 830 } hands_t; /* hand positions (x,y) */
734 831
735 hands_t HandsNow, * pHandsOld; 832 hands_t HandsNow, *pHandsOld;
736 833
737 GC X_gc, X_rvgc; 834 GC X_gc, X_rvgc;
738 835
739 static hands_t HandsOld = { -1 }; 836 static hands_t HandsOld = { -1 };
740#ifdef ICONWIN 837#ifdef ICONWIN
741 static hands_t HandsOld_icon = { -1 }; 838 static hands_t HandsOld_icon = { -1 };
742#endif 839#endif
743#ifdef REMINDERS 840#ifdef REMINDERS
744 static int lastUpdateTime = -10; 841 static int lastUpdateTime = -10;
745#endif 842#endif
746 843
747#ifdef MAIL 844#ifdef MAIL
748 static time_t mailTime = 0; 845 static time_t mailTime = 0;
749 static int MailUp = 0, MailUp_rvideo = 0; 846 static int MailUp = 0, MailUp_rvideo = 0;
847
848# ifdef ICONWIN
849 static int MailUp_icon = 0;
850# endif
851#endif /* MAIL */
852
853 currentTime = time (NULL) + adjustTime; /* get the current time */
854 tmval = localtime (&currentTime);
855
856#ifdef MAIL
857# ifdef REMINDERS
858 if (W->win != Msg.win)
859# endif
860 {
861 int *pMailUp = (
862# ifdef ICONWIN
863 W->win == Icon.win ? &MailUp_icon :
864# endif
865 &MailUp);
866
867 if ((currentTime - mailTime) >= mailUpdate)
868 {
869 if (
870# ifdef ICONWIN
871 MailUp != MailUp_icon ? MailUp :
872# endif
873 ((mail_file != NULL) && MailAvailable ()))
874 {
875 if (!*pMailUp)
876 {
877 *pMailUp = 1;
878 full_redraw = 1;
879 XSetWindowBackground (Xdisplay, W->win, PixColors[fgColor]);
880# ifdef MAIL_BELL
881 XBell (Xdisplay, 0);
882# endif
883 }
884 }
885 else
886 {
887 if (*pMailUp)
888 {
889 *pMailUp = 0;
890 full_redraw = 1;
891 XSetWindowBackground (Xdisplay, W->win, PixColors[bgColor]);
892 }
893 }
894# ifdef ICONWIN
895 if (MailUp == MailUp_icon)
896# endif
897 mailTime = currentTime;
898
899 MailUp_rvideo = *pMailUp;
900 }
901 }
902#endif /* MAIL */
903
904 /* once every day, update the window and icon name */
905 if (tmval->tm_yday != savedDay)
906 {
907 char str[20];
908
909 savedDay = tmval->tm_yday;
910 strftime (str, sizeof (str), "%a %h %d", tmval);
911 XStoreName (Xdisplay, Clock.win, str);
912 XSetIconName (Xdisplay, Clock.win, str);
913 }
914
915 if (full_redraw)
916 XClearWindow (Xdisplay, W->win);
917
918#ifdef REMINDERS
919 /* for a message window, just re-draw the message */
920 if (W->win == Msg.win)
921 {
922 char *beg, *next;
923 int lines;
924
925 for (beg = message, lines = 0; beg; beg = next, lines++)
926 {
927 char *end;
928
929 if ((end = strstr (beg, "\\n")) == NULL)
930 {
931 end = beg + strlen (beg);
932 next = NULL;
933 }
934 else
935 {
936 next = end + 2;
937 }
938
939 XDrawString (Xdisplay, Msg.win,
940 Xgc,
941 (Msg.width -
942 XTextWidth (Xfont, beg, (end - beg))) / 2, 10 + Xfont->ascent + FontHeight () * lines, beg, (end - beg));
943 }
944
945 XDrawString (Xdisplay, msgButton.Dismiss, Xrvgc, (msgButton.width - XTextWidth (Xfont, "Done" , 4)) / 2, Xfont->ascent + 2, "Done", 4);
946
947 XDrawString (Xdisplay, msgButton.Defer , Xrvgc, (msgButton.width - XTextWidth (Xfont, "Defer", 5)) / 2, Xfont->ascent + 2, "Defer", 5);
948
949# ifndef NO_REMINDER_EXEC
950 XDrawString (Xdisplay, msgButton.Start , Xrvgc, (msgButton.width - XTextWidth (Xfont, "Start", 5)) / 2, Xfont->ascent + 2, "Start", 5);
951
952 if (strlen (execPrgm) > 1)
953 XMapWindow (Xdisplay, msgButton.Start);
954 else
955 XUnmapWindow (Xdisplay, msgButton.Start);
956# endif /* NO_REMINDER_EXEC */
957 return;
958 }
959
960 /*
961 * Convert multi-field time info to a single integer with a resolution
962 * in minutes.
963 */
964 currentTime = mk_time (tmval);
965
966 /* is there a reminder pending? */
967 if (reminderTime >= 0 && currentTime >= reminderTime)
968 Reminder ();
969
970 /* every 10 minutes, or at start of day, check for revised entries */
971 if (!Msg_Mapped &&
972 (currentTime > lastUpdateTime + REMINDERS_TIME || (currentTime != lastUpdateTime && tmval->tm_hour == 0 && tmval->tm_min == 0)))
973 {
974 Next_Reminder (UPDATE);
975 lastUpdateTime = currentTime;
976 }
977#endif
978
979 /*
980 * draw clock
981 */
982
983 ctr_x = W->width / 2;
984 ctr_y = W->height / 2;
985
986#define XPOS(i,val) (ctr_x + (W->width * Sin (i ) + 4096) / (819200 / (val)))
987#define YPOS(i,val) (ctr_y - (W->height * Sin (i + 180) + 4096) / (819200 / (val)))
988 /*
989 * how to draw the clock face
990 */
991
992 /* calculate the positions of the hands */
993 {
994 int angle = (tmval->tm_hour % 12) * 60 + tmval->tm_min;
995
996 HandsNow.h_x = XPOS (angle, 60);
997 HandsNow.h_y = YPOS (angle, 60);
998 }
999 {
1000 int angle = (tmval->tm_min * 12);
1001
1002 HandsNow.m_x = XPOS (angle, 80);
1003 HandsNow.m_y = YPOS (angle, 80);
1004 }
1005 if (clockUpdate == 1)
1006 {
1007 int angle = (tmval->tm_sec * 12);
1008
1009 HandsNow.s_x = XPOS (angle, 85);
1010 HandsNow.s_y = YPOS (angle, 85);
1011 }
1012
1013 pHandsOld = (
750#ifdef ICONWIN 1014#ifdef ICONWIN
751 static int MailUp_icon = 0; 1015 W->win == Icon.win ? &HandsOld_icon :
752#endif 1016#endif
753#endif /* MAIL */ 1017 &HandsOld);
754
755 currentTime = time (NULL) + adjustTime; /* get the current time */
756 tmval = localtime (&currentTime);
757 1018
758#ifdef MAIL 1019#ifdef MAIL
1020 if (MailUp_rvideo)
1021 {
1022 X_gc = Xrvgc;
1023 X_rvgc = Xgc;
1024 }
1025 else
1026#endif
1027 {
1028 X_gc = Xgc;
1029 X_rvgc = Xrvgc;
1030 }
1031
1032 /*
1033 * Draw the date in the lower half of the clock window.
1034 * The code is enclosed in REMINDERS because it uses the same
1035 * font as the reminders code.
1036 * I believe this should be drawn always so it does not get
1037 * "swept away" by the minute hand.
1038 */
1039#if defined(REMINDERS) && defined(DATE_ON_CLOCK_FACE)
1040 if (show_date)
1041 {
1042 char date[10];
1043
1044 currentTime = time (NULL) + adjustTime; /* get the current time */
1045 tmval = localtime (&currentTime);
1046 strftime (date, sizeof (date), "%d", tmval);
1047 XDrawString (Xdisplay, W->win, X_gc,
1048 ctr_x - XTextWidth (Xfont, date, strlen (date)) / 2,
1049 ctr_y + FontHeight () + (ctr_y - FontHeight ()) / 2, date, strlen (date));
1050 }
1051#endif
1052
1053 if (full_redraw)
1054 {
1055 int mintick;
1056
1057 /*
1058 * draw clock face
1059 */
1060#ifdef SUBTICKS
1061 for (mintick = 0; mintick < 60; mintick++)
1062 XDrawPoint (Xdisplay, W->win, X_gc, XPOS ((mintick * 12), 95), YPOS ((mintick * 12), 95));
1063#endif
1064 for (mintick = 0; mintick < 60; mintick += 5)
1065 XDrawLine (Xdisplay, W->win, X_gc,
1066 XPOS ((mintick * 12), 90), YPOS ((mintick * 12), 90), XPOS ((mintick * 12), 100), YPOS ((mintick * 12), 100));
1067 }
1068 else if (memcmp (pHandsOld, &HandsNow, sizeof (hands_t)))
1069 {
1070 int i, j;
1071
1072 /*
1073 * erase old hands
1074 */
1075 for (i = -1; i < 2; i++)
1076 for (j = -1; j < 2; j++)
1077 {
1078 /* hour/minute hands */
1079 XDrawLine (Xdisplay, W->win, X_rvgc, ctr_x + i, ctr_y + j, pHandsOld->h_x, pHandsOld->h_y);
1080 XDrawLine (Xdisplay, W->win, X_rvgc, ctr_x + i, ctr_y + j, pHandsOld->m_x, pHandsOld->m_y);
1081 }
1082
1083 if (clockUpdate == 1) /* seconds hand */
1084 XDrawLine (Xdisplay, W->win, X_rvgc, ctr_x, ctr_y, pHandsOld->s_x, pHandsOld->s_y);
1085 }
1086
1087 if (full_redraw || memcmp (pHandsOld, &HandsNow, sizeof (hands_t)))
1088 {
1089 int i, j;
1090
1091 /*
1092 * draw new hands
1093 */
1094 for (i = -1; i < 2; i++)
1095 for (j = -1; j < 2; j++)
1096 {
1097 /* hour/minute hands */
1098 XDrawLine (Xdisplay, W->win, X_gc, ctr_x + i, ctr_y + j, HandsNow.h_x, HandsNow.h_y);
1099
1100 XDrawLine (Xdisplay, W->win, X_gc, ctr_x + i, ctr_y + j, HandsNow.m_x, HandsNow.m_y);
1101 }
1102 if (clockUpdate == 1) /* seconds hand */
1103 XDrawLine (Xdisplay, W->win, X_gc, ctr_x, ctr_y, HandsNow.s_x, HandsNow.s_y);
1104
1105 *pHandsOld = HandsNow;
1106 }
1107}
1108
759#ifdef REMINDERS 1109#ifdef REMINDERS
760 if (W->win != Msg.win)
761#endif
762 {
763 int * pMailUp = (
764#ifdef ICONWIN
765 W->win == Icon.win ? &MailUp_icon :
766#endif
767 &MailUp);
768 1110
769 if ((currentTime - mailTime) >= mailUpdate)
770 {
771 struct stat st;
772
773 if (
774#ifdef ICONWIN
775 MailUp != MailUp_icon ? MailUp :
776#endif
777 ((mail_file != NULL) && MailAvailable() ) )
778 {
779 if (!*pMailUp)
780 {
781 *pMailUp = 1;
782 full_redraw = 1;
783 XSetWindowBackground (Xdisplay, W->win,
784 PixColors [fgColor]);
785#ifdef MAIL_BELL
786 XBell (Xdisplay, 0);
787#endif
788 }
789 }
790 else
791 {
792 if (*pMailUp)
793 {
794 *pMailUp = 0;
795 full_redraw = 1;
796 XSetWindowBackground (Xdisplay, W->win,
797 PixColors [bgColor]);
798 }
799 }
800#ifdef ICONWIN
801 if (MailUp == MailUp_icon)
802#endif
803 mailTime = currentTime;
804
805 MailUp_rvideo = *pMailUp;
806 }
807 }
808#endif /* MAIL */
809
810 /* once every day, update the window and icon name */
811 if (tmval->tm_yday != savedDay)
812 {
813 char str [20];
814
815 savedDay = tmval->tm_yday;
816 strftime (str, sizeof(str), "%a %h %d", tmval);
817 XStoreName (Xdisplay, Clock.win, str);
818 XSetIconName (Xdisplay, Clock.win, str);
819 }
820
821 if (full_redraw)
822 XClearWindow (Xdisplay, W->win);
823
824#ifdef REMINDERS
825 /* for a message window, just re-draw the message */
826 if (W->win == Msg.win)
827 {
828 char * beg, * next;
829 int lines;
830
831 for (beg = message, lines = 0; beg; beg = next, lines++)
832 {
833 char * end;
834
835 if ((end = strstr (beg, "\\n")) == NULL)
836 {
837 end = beg + strlen (beg);
838 next = NULL;
839 }
840 else
841 {
842 next = end + 2;
843 }
844
845 XDrawString (Xdisplay, Msg.win,
846 Xgc,
847 (Msg.width -
848 XTextWidth (Xfont, beg, (end-beg))) / 2,
849 10 + Xfont->ascent + FontHeight () * lines,
850 beg, (end-beg));
851 }
852
853 XDrawString (Xdisplay, msgButton.Dismiss,
854 Xrvgc,
855 (msgButton.width - XTextWidth (Xfont, "Done", 4)) / 2,
856 Xfont->ascent + 2,
857 "Done", 4);
858
859 XDrawString (Xdisplay, msgButton.Defer,
860 Xrvgc,
861 (msgButton.width - XTextWidth (Xfont, "Defer", 5)) / 2,
862 Xfont->ascent + 2,
863 "Defer", 5);
864
865# ifndef NO_REMINDER_EXEC
866 XDrawString (Xdisplay, msgButton.Start,
867 Xrvgc,
868 (msgButton.width - XTextWidth (Xfont, "Start", 5)) / 2,
869 Xfont->ascent + 2,
870 "Start", 5);
871
872 if (strlen (execPrgm) > 1)
873 XMapWindow (Xdisplay, msgButton.Start);
874 else
875 XUnmapWindow (Xdisplay, msgButton.Start);
876# endif /* NO_REMINDER_EXEC */
877 return;
878 }
879
880 /*
881 * Convert multi-field time info to a single integer with a resolution
882 * in minutes.
883 */
884 currentTime = mk_time (tmval);
885
886 /* is there a reminder pending? */
887 if (reminderTime >= 0 && currentTime >= reminderTime)
888 Reminder ();
889
890 /* every 10 minutes, or at start of day, check for revised entries */
891 if (!Msg_Mapped &&
892 (currentTime > lastUpdateTime + REMINDERS_TIME ||
893 (currentTime != lastUpdateTime &&
894 tmval->tm_hour == 0 && tmval->tm_min == 0)))
895 {
896 Next_Reminder (UPDATE);
897 lastUpdateTime = currentTime;
898 }
899#endif
900
901 /*
902 * draw clock
903 */
904
905 ctr_x = (W->width / 2);
906 ctr_y = (W->height / 2);
907
908#define XPOS(i,val) (ctr_x + (W->width * Sin[i%60] * (val) + 100000) / 200000)
909#define YPOS(i,val) (ctr_y - (W->height * Sin[(i+15)%60] * (val) + 100000) / 200000)
910 /*
911 * how to draw the clock face
912 */
913
914 /* calculate the positions of the hands */
915 {
916 int angle = (tmval->tm_hour % 12) * 5 + (tmval->tm_min / 12);
917 HandsNow.h_x = XPOS (angle, 60);
918 HandsNow.h_y = YPOS (angle, 60);
919 }
920 {
921 int angle = tmval->tm_min;
922 HandsNow.m_x = XPOS (angle, 80);
923 HandsNow.m_y = YPOS (angle, 80);
924 }
925 if (clockUpdate == 1)
926 {
927 int angle = tmval->tm_sec;
928 HandsNow.s_x = XPOS (angle, 85);
929 HandsNow.s_y = YPOS (angle, 85);
930 }
931
932 pHandsOld = (
933#ifdef ICONWIN
934 W->win == Icon.win ? &HandsOld_icon :
935#endif
936 &HandsOld);
937
938#ifdef MAIL
939 if (MailUp_rvideo)
940 {
941 X_gc = Xrvgc;
942 X_rvgc = Xgc;
943 }
944 else
945#endif
946 {
947 X_gc = Xgc;
948 X_rvgc = Xrvgc;
949 }
950
951 /*
952 * Draw the date in the lower half of the clock window.
953 * The code is enclosed in REMINDERS because it uses the same
954 * font as the reminders code.
955 * I believe this should be drawn always so it does not get
956 * "swept away" by the minute hand.
957 */
958#ifdef REMINDERS && DATE_ON_CLOCK_FACE
959 if( show_date)
960 {
961 char date[10];
962 currentTime = time (NULL) + adjustTime; /* get the current time */
963 tmval = localtime (&currentTime);
964 strftime (date, sizeof(date), "%d", tmval);
965 XDrawString (Xdisplay, W->win, X_gc,
966 ctr_x - XTextWidth(Xfont, date, strlen(date))/2,
967 ctr_y + FontHeight() + (ctr_y - FontHeight())/2,
968 date, strlen(date));
969 }
970#endif
971
972 if (full_redraw)
973 {
974 int angle;
975 /*
976 * draw clock face
977 */
978#ifdef SUBTICKS
979 for (angle = 0; angle < 60; angle++)
980 XDrawPoint (Xdisplay, W->win, X_gc,
981 XPOS (angle, 95),
982 YPOS (angle, 95));
983#endif
984 for (angle = 0; angle < 60; angle += 5)
985 XDrawLine (Xdisplay, W->win, X_gc,
986 XPOS (angle, 90),
987 YPOS (angle, 90),
988 XPOS (angle, 100),
989 YPOS (angle, 100));
990 }
991 else if (memcmp (pHandsOld, &HandsNow, sizeof(hands_t)))
992 {
993 int i, j;
994 /*
995 * erase old hands
996 */
997 for (i = -1; i < 2; i++) for (j = -1; j < 2; j++)
998 {
999 /* hour/minute hands */
1000 XDrawLine (Xdisplay, W->win, X_rvgc,
1001 ctr_x + i,
1002 ctr_y + j,
1003 pHandsOld->h_x, pHandsOld->h_y);
1004 XDrawLine (Xdisplay, W->win, X_rvgc,
1005 ctr_x + i,
1006 ctr_y + j,
1007 pHandsOld->m_x, pHandsOld->m_y);
1008 }
1009
1010 if (clockUpdate == 1) /* seconds hand */
1011 XDrawLine (Xdisplay,
1012 W->win, X_rvgc,
1013 ctr_x,
1014 ctr_y,
1015 pHandsOld->s_x, pHandsOld->s_y);
1016 }
1017
1018 if (full_redraw || memcmp (pHandsOld, &HandsNow, sizeof(hands_t)))
1019 {
1020 int i, j;
1021 /*
1022 * draw new hands
1023 */
1024 for (i = -1; i < 2; i++) for (j = -1; j < 2; j++)
1025 {
1026 /* hour/minute hands */
1027 XDrawLine (Xdisplay, W->win, X_gc,
1028 ctr_x + i,
1029 ctr_y + j,
1030 HandsNow.h_x, HandsNow.h_y);
1031
1032 XDrawLine (Xdisplay, W->win, X_gc,
1033 ctr_x + i,
1034 ctr_y + j,
1035 HandsNow.m_x, HandsNow.m_y);
1036 }
1037 if (clockUpdate == 1) /* seconds hand */
1038 XDrawLine (Xdisplay, W->win, X_gc,
1039 ctr_x,
1040 ctr_y,
1041 HandsNow.s_x, HandsNow.s_y);
1042
1043 *pHandsOld = HandsNow;
1044 }
1045}
1046
1047#ifdef REMINDERS
1048/* 1111/*
1049 * Read a single integer from *pstr, returns default value if it finds "*" 1112 * Read a single integer from *pstr, returns default value if it finds "*"
1050 * DELIM = trailing delimiter to skip 1113 * DELIM = trailing delimiter to skip
1051 */ 1114 */
1052static int 1115static int
1053GetOneNum (char ** pstr, int def) 1116GetOneNum (char **pstr, int def)
1054{ 1117{
1055 int num, hit = 0; 1118 int num, hit = 0;
1056 1119
1057 for (num = 0; isdigit (**pstr); (*pstr)++) 1120 for (num = 0; isdigit (**pstr); (*pstr)++)
1058 { 1121 {
1059 num = num * 10 + (**pstr - '0'); 1122 num = num * 10 + (**pstr - '0');
1060 hit = 1; 1123 hit = 1;
1061 } 1124 }
1062 if (!hit) 1125 if (!hit)
1063 { 1126 {
1064 num = def; 1127 num = def;
1065 while (**pstr == '*') (*pstr)++; 1128 while (**pstr == '*')
1129 (*pstr)++;
1066 } 1130 }
1067 return num; 1131 return num;
1068} 1132}
1069 1133
1070/* 1134/*
1071 * find if TODAY is found in PSTR 1135 * find if TODAY is found in PSTR
1072 */ 1136 */
1073static int 1137static int
1074isToday (char ** pstr, int wday) 1138isToday (char **pstr, int wday)
1075{ 1139{
1076 const char * dayNames = DAY_NAMES; 1140 const char *dayNames = DAY_NAMES;
1077 int rval, today; 1141 int rval, today;
1078 1142
1079 today = dayNames [wday]; 1143 today = dayNames[wday];
1080 /* no day specified is same as wildcard */ 1144 /* no day specified is same as wildcard */
1081 if (!strchr (dayNames, tolower (**pstr))) 1145 if (!strchr (dayNames, tolower (**pstr)))
1082 return 1; 1146 return 1;
1083 1147
1084 for (rval = 0; strchr (dayNames, tolower (**pstr)); (*pstr)++) 1148 for (rval = 0; strchr (dayNames, tolower (**pstr)); (*pstr)++)
1085 { 1149 {
1086 if (today == tolower (**pstr) || **pstr == '*') 1150 if (today == tolower (**pstr) || **pstr == '*')
1087 rval = 1; /* found it */ 1151 rval = 1; /* found it */
1088 } 1152 }
1089 return rval; 1153 return rval;
1090} 1154}
1091 1155
1092static char * 1156static char *
1093trim_string (char * str) 1157trim_string (char *str)
1094{ 1158{
1095 if (str && *str) 1159 if (str && *str)
1096 { 1160 {
1097 int n; 1161 int n;
1162
1098 while (*str && isspace (*str)) str++; 1163 while (*str && isspace (*str))
1164 str++;
1099 1165
1100 n = strlen (str) - 1; 1166 n = strlen (str) - 1;
1101 while (n > 0 && isspace (str [n])) n--; 1167 while (n > 0 && isspace (str[n]))
1168 n--;
1102 str [n+1] = '\0'; 1169 str[n + 1] = '\0';
1103 } 1170 }
1104 return str; 1171 return str;
1105} 1172}
1106 1173
1107# ifndef NO_REMINDER_EXEC 1174# ifndef NO_REMINDER_EXEC
1108static char * 1175static char *
1109extract_program (char * text) 1176extract_program (char *text)
1110{ 1177{
1111 char * prgm = text; 1178 char *prgm = text;
1179
1112 while ((prgm = strchr (prgm, ';')) != NULL) 1180 while ((prgm = strchr (prgm, ';')) != NULL)
1113 { 1181 {
1114 if (*(prgm-1) == '\\') /* backslash escaped */ 1182 if (*(prgm - 1) == '\\') /* backslash escaped */
1115 { 1183 {
1116 /* remove backslash - avoid memmove() */ 1184 /* remove backslash - avoid memmove() */
1117 int i, n = strlen (prgm); 1185 int i, n = strlen (prgm);
1186
1118 for (i = 0; i <= n; i++) 1187 for (i = 0; i <= n; i++)
1119 prgm [i - 1] = prgm [i]; 1188 prgm[i - 1] = prgm[i];
1120 } 1189 }
1121 else 1190 else
1122 { 1191 {
1123 *prgm++ = '\0'; 1192 *prgm++ = '\0';
1124 /* remove leading/trailing space */ 1193 /* remove leading/trailing space */
1125 prgm = trim_string (prgm); 1194 prgm = trim_string (prgm);
1126 break; 1195 break;
1127 } 1196 }
1128 } 1197 }
1129 return prgm; 1198 return prgm;
1130} 1199}
1131# endif /* NO_REMINDER_EXEC */ 1200# endif /* NO_REMINDER_EXEC */
1132 1201
1133/* 1202/*
1134 * Read the ~/.rclock file and find the next reminder 1203 * Read the ~/.rclock file and find the next reminder
1135 * 1204 *
1136 * update_only = 1 1205 * update_only = 1
1142 * just went off 1211 * just went off
1143 */ 1212 */
1144static void 1213static void
1145Next_Reminder (int update_only) 1214Next_Reminder (int update_only)
1146{ 1215{
1147 struct tm * tmval; 1216 struct tm *tmval;
1148 char buffer [256]; 1217 char buffer[256];
1218
1149#ifndef INT_MAX 1219# ifndef INT_MAX
1150# define INT_MAX 1e8 1220# define INT_MAX 1e8
1151#endif 1221# endif
1152 time_t currentTime; 1222 time_t currentTime;
1153 int savedTime = INT_MAX; 1223 int savedTime = INT_MAX;
1154 FILE * fd; 1224 FILE *fd;
1155 1225
1156 if (reminders_file == NULL || (fd = fopen (reminders_file, "r")) == NULL) 1226 if (reminders_file == NULL || (fd = fopen (reminders_file, "r")) == NULL)
1157 { 1227 {
1158 reminderTime = -1; /* no config file, no reminders */ 1228 reminderTime = -1; /* no config file, no reminders */
1159 return; 1229 return;
1160 } 1230 }
1161 1231
1162 currentTime = time (NULL) + adjustTime; /* get the current time */ 1232 currentTime = time (NULL) + adjustTime; /* get the current time */
1163 tmval = localtime (&currentTime); 1233 tmval = localtime (&currentTime);
1164 currentTime = mk_time (tmval); 1234 currentTime = mk_time (tmval);
1165 1235
1166 /* initial startup*/ 1236 /* initial startup */
1167 if (reminderTime < 0) 1237 if (reminderTime < 0)
1168 { 1238 {
1169 /* ignore reminders that have already occurred */ 1239 /* ignore reminders that have already occurred */
1170 reminderTime = currentTime; 1240 reminderTime = currentTime;
1171# ifndef NO_REMINDER_EXEC 1241# ifndef NO_REMINDER_EXEC
1172 /* scan for programs run on start-up */ 1242 /* scan for programs run on start-up */
1173 while (fgets (buffer, sizeof(buffer), fd)) 1243 while (fgets (buffer, sizeof (buffer), fd))
1174 { 1244 {
1175 char * prgm, * text; 1245 char *prgm, *text;
1176 1246
1177 text = trim_string (buffer); 1247 text = trim_string (buffer);
1178 if (*text != ';') continue; 1248 if (*text != ';')
1249 continue;
1179 1250
1180 prgm = extract_program (text); 1251 prgm = extract_program (text);
1181 if (prgm != NULL && strlen (prgm) > 1) 1252 if (prgm != NULL && strlen (prgm) > 1)
1182 system (prgm); 1253 system (prgm);
1183 } 1254 }
1184 rewind (fd); 1255 rewind (fd);
1185# endif /* NO_REMINDER_EXEC */ 1256# endif /* NO_REMINDER_EXEC */
1186 } 1257 }
1187 1258
1188 /* now scan for next reminder */ 1259 /* now scan for next reminder */
1189 while (fgets (buffer, sizeof(buffer), fd)) 1260 while (fgets (buffer, sizeof (buffer), fd))
1190 { 1261 {
1191 int testTime, hh, mm, mo, dd, yy; 1262 int testTime, hh, mm, mo, dd, yy;
1192 char * text; 1263 char *text;
1193 1264
1194 text = trim_string (buffer); 1265 text = trim_string (buffer);
1195 if (*text == '#') continue; /* comment */ 1266 if (*text == '#')
1196 if (*text == ';') continue; /* program run on startup */ 1267 continue; /* comment */
1197 /* 1268 if (*text == ';')
1269 continue; /* program run on startup */
1270 /*
1198 * parse the line, format is hh:mm mo/dd/yr message; program 1271 * parse the line, format is hh:mm mo/dd/yr message; program
1199 * any of hh, mm, mo, dd, yr could be a wildcard `*' 1272 * any of hh, mm, mo, dd, yr could be a wildcard `*'
1200 */ 1273 */
1201 hh = GetOneNum (&text, tmval->tm_hour); if (*text == ':') text++; 1274 hh = GetOneNum (&text, tmval->tm_hour);
1275 if (*text == ':')
1276 text++;
1202 mm = GetOneNum (&text, 0); 1277 mm = GetOneNum (&text, 0);
1203 1278
1204 while (isspace (*text)) text++; 1279 while (isspace (*text))
1280 text++;
1205 if (!isToday (&text, tmval->tm_wday)) continue; 1281 if (!isToday (&text, tmval->tm_wday))
1282 continue;
1206 while (isspace (*text)) text++; 1283 while (isspace (*text))
1284 text++;
1207 1285
1208 mo = GetOneNum (&text, tmval->tm_mon+1); if (*text == '/') text++; 1286 mo = GetOneNum (&text, tmval->tm_mon + 1);
1209 dd = GetOneNum (&text, tmval->tm_mday); if (*text == '/') text++; 1287 if (*text == '/')
1288 text++;
1289 dd = GetOneNum (&text, tmval->tm_mday);
1290 if (*text == '/')
1291 text++;
1210 yy = GetOneNum (&text, tmval->tm_year); 1292 yy = GetOneNum (&text, tmval->tm_year);
1211 1293
1212 /* handle 20th/21st centuries */ 1294 /* handle 20th/21st centuries */
1213 if (yy > CENTURY) 1295 if (yy > CENTURY)
1214 yy -= 1900; 1296 yy -= 1900;
1215 else if (yy < CENTURY) 1297 else if (yy < CENTURY)
1216 yy += (CENTURY - 1900); 1298 yy += (CENTURY - 1900);
1217 1299
1218 while (isspace (*text)) text++; 1300 while (isspace (*text))
1219 if (!*text) continue; 1301 text++;
1302 if (!*text)
1303 continue;
1220 1304
1221 testTime = (mm + 60 * (hh + 24 * (dd + 31 * (mo + 12 * yy)))); 1305 testTime = (mm + 60 * (hh + 24 * (dd + 31 * (mo + 12 * yy))));
1222 1306
1223 if (testTime > (update_only ? currentTime : reminderTime)) 1307 if (testTime > (update_only ? currentTime : reminderTime))
1224 { 1308 {
1225#ifndef NO_REMINDER_EXEC 1309# ifndef NO_REMINDER_EXEC
1226 char * prgm = extract_program (text); 1310 char *prgm = extract_program (text);
1227#endif /* NO_REMINDER_EXEC */ 1311# endif/* NO_REMINDER_EXEC */
1228 /* trim leading/trailing space */ 1312 /* trim leading/trailing space */
1229 text = trim_string (text); 1313 text = trim_string (text);
1230 1314
1231 /* 1315 /*
1232 * have a reminder whose time is greater than the last 1316 * have a reminder whose time is greater than the last
1233 * reminder, now make sure it is the smallest available 1317 * reminder, now make sure it is the smallest available
1234 */ 1318 */
1235 if (testTime < savedTime) 1319 if (testTime < savedTime)
1236 { 1320 {
1237 savedTime = testTime; 1321 savedTime = testTime;
1238 strncpy (message, text, sizeof(message)); 1322 strncpy (message, text, sizeof (message));
1239#ifndef NO_REMINDER_EXEC 1323# ifndef NO_REMINDER_EXEC
1240 strncpy (execPrgm, (prgm ? prgm : ""), sizeof(execPrgm)); 1324 strncpy (execPrgm, (prgm ? prgm : ""), sizeof (execPrgm));
1241#endif 1325# endif
1242 } 1326 }
1243 else if (testTime == savedTime) 1327 else if (testTime == savedTime)
1244 { 1328 {
1245 if (strlen (text)) 1329 if (strlen (text))
1246 { 1330 {
1247 int n = (sizeof(message) - strlen (message) - 3); 1331 int n = (sizeof (message) - strlen (message) - 3);
1248 if (n > 0) 1332
1249 { 1333 if (n > 0)
1334 {
1250 /* for co-occurring events */ 1335 /* for co-occurring events */
1251 strcat (message, "\\n"); 1336 strcat (message, "\\n");
1252 strncat (message, text, n); 1337 strncat (message, text, n);
1253 } 1338 }
1254 } 1339 }
1255#ifndef NO_REMINDER_EXEC 1340# ifndef NO_REMINDER_EXEC
1256 if (prgm != NULL) 1341 if (prgm != NULL)
1257 { 1342 {
1258 int n = (sizeof(execPrgm) - strlen (execPrgm) - 2); 1343 int n = (sizeof (execPrgm) - strlen (execPrgm) - 2);
1344
1259 if ((n > 0) && (n >= strlen (prgm))) 1345 if ((n > 0) && (n >= strlen (prgm)))
1260 { 1346 {
1261 /* for co-occurring programs */ 1347 /* for co-occurring programs */
1262 strcat (execPrgm, ";"); 1348 switch (execPrgm[strlen (execPrgm) - 1])
1349 {
1350 case '&':
1351 case ';':
1352 break;
1353 default:
1354 strcat (execPrgm, ";");
1355 break;
1356 }
1263 strncat (execPrgm, prgm, n); 1357 strncat (execPrgm, prgm, n);
1264 } 1358 }
1265 } 1359 }
1266#endif /* NO_REMINDER_EXEC */ 1360# endif/* NO_REMINDER_EXEC */
1361 }
1267 } 1362 }
1268 }
1269 } 1363 }
1270 1364
1271 reminderTime = (savedTime < INT_MAX) ? savedTime : -1; 1365 reminderTime = (savedTime < INT_MAX) ? savedTime : -1;
1272 fclose (fd); 1366 fclose (fd);
1273} 1367}
1274 1368
1275/* 1369/*
1276 * Provide reminder by mapping the message window 1370 * Provide reminder by mapping the message window
1277 */ 1371 */
1278static void 1372static void
1279Reminder (void) 1373Reminder ()
1280{ 1374{
1281 char * beg, * next; 1375 char *beg, *next;
1282 int lines; 1376 int lines;
1283 1377
1284 if (Msg_Mapped) 1378 if (Msg_Mapped)
1285 return; 1379 return;
1286 1380
1287#ifndef NO_REMINDER_EXEC 1381# ifndef NO_REMINDER_EXEC
1288 if (strlen (message) == 0) 1382 if (strlen (message) == 0)
1289 { 1383 {
1290 if (strlen (execPrgm) > 1) 1384 if (strlen (execPrgm) > 1)
1291 { 1385 {
1292 system (execPrgm); 1386 system (execPrgm);
1293 Next_Reminder (REPLACE); 1387 Next_Reminder (REPLACE);
1294 } 1388 }
1295 return; /* some sort of error */ 1389 return; /* some sort of error */
1296 } 1390 }
1297#endif 1391# endif
1298 1392
1299 /* compute the window size */ 1393 /* compute the window size */
1300#ifdef NO_REMINDER_EXEC 1394# ifdef NO_REMINDER_EXEC
1301 Msg.width = 10 * XTextWidth (Xfont, "M", 1); 1395 Msg.width = 10 * XTextWidth (Xfont, "M", 1);
1302#else 1396# else
1303 Msg.width = 18 * XTextWidth (Xfont, "M", 1); 1397 Msg.width = 18 * XTextWidth (Xfont, "M", 1);
1304#endif 1398# endif
1305 1399
1306 for (beg = message, lines = 1; beg; beg = next, lines++) 1400 for (beg = message, lines = 1; beg; beg = next, lines++)
1307 { 1401 {
1308 int width; 1402 int width;
1309 char * end; 1403 char *end;
1310 1404
1311 if ((end = strstr (beg, "\\n")) == NULL) 1405 if ((end = strstr (beg, "\\n")) == NULL)
1312 { 1406 {
1313 end = beg + strlen (beg); 1407 end = beg + strlen (beg);
1314 next = NULL; 1408 next = NULL;
1315 } 1409 }
1316 else 1410 else
1317 { 1411 {
1318 next = end + 2; 1412 next = end + 2;
1319 } 1413 }
1320 1414
1321 width = XTextWidth (Xfont, beg, (end-beg)); 1415 width = XTextWidth (Xfont, beg, (end - beg));
1322 if (Msg.width < width) 1416 if (Msg.width < width)
1323 Msg.width = width; 1417 Msg.width = width;
1324 } 1418 }
1325 1419
1326 Msg.width += 30; 1420 Msg.width += 30;
1327 Msg.height = (lines+1) * FontHeight () + 30; 1421 Msg.height = (lines + 1) * FontHeight () + 30;
1328 1422
1329 /* resize and centre the window */ 1423 /* resize and centre the window */
1330 XMoveResizeWindow (Xdisplay, Msg.win, 1424 XMoveResizeWindow (Xdisplay, Msg.win,
1331 (DisplayWidth (Xdisplay, Xscreen) - Msg.width ) / 2, 1425 (DisplayWidth (Xdisplay, Xscreen) - Msg.width) / 2,
1332 (DisplayHeight (Xdisplay, Xscreen) - Msg.height) / 2, 1426 (DisplayHeight (Xdisplay, Xscreen) - Msg.height) / 2, Msg.width, Msg.height);
1333 Msg.width, Msg.height);
1334 1427
1335#define BUTTON_MARGIN 8 1428# define BUTTON_MARGIN 8
1336 1429
1337 XMoveWindow (Xdisplay, msgButton.Dismiss, 1430 XMoveWindow (Xdisplay, msgButton.Dismiss, BUTTON_MARGIN, (Msg.height - msgButton.height - BUTTON_MARGIN));
1338 BUTTON_MARGIN, 1431 XMoveWindow (Xdisplay, msgButton.Defer, (Msg.width - msgButton.width - BUTTON_MARGIN), (Msg.height - msgButton.height - BUTTON_MARGIN));
1339 (Msg.height - msgButton.height - BUTTON_MARGIN));
1340 XMoveWindow (Xdisplay, msgButton.Defer,
1341 (Msg.width - msgButton.width - BUTTON_MARGIN),
1342 (Msg.height - msgButton.height - BUTTON_MARGIN));
1343#ifndef NO_REMINDER_EXEC 1432# ifndef NO_REMINDER_EXEC
1344 XMoveWindow (Xdisplay, msgButton.Start, 1433 XMoveWindow (Xdisplay, msgButton.Start, (Msg.width - msgButton.width) / 2, (Msg.height - msgButton.height - BUTTON_MARGIN));
1345 (Msg.width - msgButton.width) / 2,
1346 (Msg.height - msgButton.height - BUTTON_MARGIN));
1347#endif 1434# endif
1348 1435
1349 XMapRaised (Xdisplay, Msg.win); 1436 XMapRaised (Xdisplay, Msg.win);
1350 XBell (Xdisplay, 0); 1437 XBell (Xdisplay, 0);
1351 Msg_Mapped = 1; 1438 Msg_Mapped = 1;
1352} 1439}
1353#endif /* REMINDERS */ 1440#endif /* REMINDERS */
1354
1355#ifndef _POSIX_VERSION
1356# if defined (__svr4__)
1357static int
1358getdtablesize (void)
1359{
1360 struct rlimit rlim;
1361 getrlimit (RLIMIT_NOFILE, &rlim);
1362 return rlim.rlim_cur;
1363}
1364# endif
1365#endif
1366 1441
1367/* 1442/*
1368 * Loops forever, looking for stuff to do. Sleeps 1 minute if nothing to do 1443 * Loops forever, looking for stuff to do. Sleeps 1 minute if nothing to do
1369 */ 1444 */
1370static void 1445static void
1371getXevent (void) 1446getXevent ()
1372{ 1447{
1373 XEvent ev; 1448 XEvent ev;
1374 int num_fds; /* number of file descriptors being used */ 1449 int num_fds; /* number of file descriptors being used */
1375 struct timeval tm; 1450 struct timeval tm;
1376 struct tm * tmval; 1451 struct tm *tmval;
1377 Atom wmDeleteWindow; 1452 Atom wmDeleteWindow;
1378 fd_set in_fdset; 1453 fd_set in_fdset;
1379 1454
1380 /* Enable delete window protocol */ 1455 /* Enable delete window protocol */
1381 wmDeleteWindow = XInternAtom (Xdisplay, "WM_DELETE_WINDOW", False); 1456 wmDeleteWindow = XInternAtom (Xdisplay, "WM_DELETE_WINDOW", False);
1382 XSetWMProtocols (Xdisplay, Clock.win, &wmDeleteWindow, 1); 1457 XSetWMProtocols (Xdisplay, Clock.win, &wmDeleteWindow, 1);
1383#ifdef ICONWIN 1458#ifdef ICONWIN
1384 XSetWMProtocols (Xdisplay, Icon.win, &wmDeleteWindow, 1); 1459 XSetWMProtocols (Xdisplay, Icon.win, &wmDeleteWindow, 1);
1385#endif 1460#endif
1386#ifdef REMINDERS 1461#ifdef REMINDERS
1387 XSetWMProtocols (Xdisplay, Msg.win, &wmDeleteWindow, 1); 1462 XSetWMProtocols (Xdisplay, Msg.win, &wmDeleteWindow, 1);
1388#endif 1463#endif
1389 1464
1390#ifdef _POSIX_VERSION
1391 num_fds = sysconf (_SC_OPEN_MAX); 1465 num_fds = sysconf (_SC_OPEN_MAX);
1392#else
1393 num_fds = getdtablesize ();
1394#endif
1395#ifdef FD_SETSIZE 1466#ifdef FD_SETSIZE
1396 if (num_fds > FD_SETSIZE) 1467 if (num_fds > FD_SETSIZE)
1397 num_fds = FD_SETSIZE; 1468 num_fds = FD_SETSIZE;
1398#endif 1469#endif
1399 1470
1400 while (1) { 1471 while (1)
1472 {
1401 /* take care of all pending X events */ 1473 /* take care of all pending X events */
1402 while (XPending (Xdisplay)) { 1474 while (XPending (Xdisplay))
1475 {
1403 XNextEvent (Xdisplay, &ev); 1476 XNextEvent (Xdisplay, &ev);
1404 switch (ev.type) { 1477 switch (ev.type)
1478 {
1405 case ClientMessage: 1479 case ClientMessage:
1406 /* check for delete window requests */ 1480 /* check for delete window requests */
1407 if ((ev.xclient.format == 32) && 1481 if ((ev.xclient.format == 32) && (ev.xclient.data.l[0] == (long)wmDeleteWindow))
1408 (ev.xclient.data.l[0] == wmDeleteWindow)) 1482 {
1409 {
1410#ifdef REMINDERS 1483#ifdef REMINDERS
1411 if (ev.xany.window == Msg.win) 1484 if (ev.xany.window == Msg.win)
1412 { 1485 {
1413 XUnmapWindow (Xdisplay, Msg.win); 1486 XUnmapWindow (Xdisplay, Msg.win);
1414 Msg_Mapped = 0; 1487 Msg_Mapped = 0;
1415 Next_Reminder (REPLACE); 1488 Next_Reminder (REPLACE);
1416 } 1489 }
1417 else 1490 else
1418#endif 1491#endif
1419 return; /* delete window is how this terminates */ 1492 return; /* delete window is how this terminates */
1420 } 1493 }
1421 break; 1494 break;
1422 1495
1423 case Expose: 1496 case Expose:
1424 case GraphicsExpose: 1497 case GraphicsExpose:
1425 /* need to re-draw a window */ 1498 /* need to re-draw a window */
1426 if (ev.xany.window == Clock.win) 1499 if (ev.xany.window == Clock.win)
1427 Draw_Window (&Clock, 1); 1500 Draw_Window (&Clock, 1);
1428#ifdef ICONWIN 1501#ifdef ICONWIN
1429 else if (ev.xany.window == Icon.win) 1502 else if (ev.xany.window == Icon.win)
1430 Draw_Window (&Icon, 1); 1503 Draw_Window (&Icon, 1);
1431#endif 1504#endif
1432#ifdef REMINDERS 1505#ifdef REMINDERS
1433 else 1506 else
1434 Draw_Window (&Msg, 1); 1507 Draw_Window (&Msg, 1);
1435#endif 1508#endif
1436 break; 1509 break;
1437 1510
1438 case ConfigureNotify: 1511 case ConfigureNotify:
1439 /* window has been re-sized */ 1512 /* window has been re-sized */
1440 if (ev.xany.window == Clock.win) 1513 if (ev.xany.window == Clock.win)
1441 { 1514 {
1442 Clock.width = ev.xconfigure.width; 1515 Clock.width = ev.xconfigure.width;
1443 Clock.height = ev.xconfigure.height; 1516 Clock.height = ev.xconfigure.height;
1444 } 1517 }
1445 break; 1518 break;
1446 1519
1447#ifdef REMINDERS 1520#ifdef REMINDERS
1448 case KeyPress: 1521 case KeyPress:
1449 /* any key press to dismiss message window */ 1522 /* any key press to dismiss message window */
1450 if (ev.xany.window == Msg.win) 1523 if (ev.xany.window == Msg.win)
1451 { 1524 {
1452 Next_Reminder (REPLACE); 1525 Next_Reminder (REPLACE);
1453 Msg_Mapped = 0; 1526 Msg_Mapped = 0;
1454 XUnmapWindow (Xdisplay, Msg.win); 1527 XUnmapWindow (Xdisplay, Msg.win);
1455 } 1528 }
1456 break; 1529 break;
1457#endif 1530#endif
1458 1531
1459 case ButtonPress: 1532 case ButtonPress:
1460#ifdef REMINDERS 1533#ifdef REMINDERS
1461 /* button press to dismiss message window */ 1534 /* button press to dismiss message window */
1462 if (ev.xany.window == Msg.win) 1535 if (ev.xany.window == Msg.win)
1463 {
1464 if (ev.xbutton.subwindow == msgButton.Dismiss)
1465 {
1466 Next_Reminder (REPLACE);
1467 Msg_Mapped = 0;
1468 XUnmapWindow (Xdisplay, Msg.win);
1469 }
1470 else if (ev.xbutton.subwindow == msgButton.Defer)
1471 {
1472 time_t t = time (NULL) + adjustTime;
1473 tmval = localtime (&t);
1474 reminderTime = mk_time (tmval) + DEFER_TIME;
1475 Msg_Mapped = 0;
1476 XUnmapWindow (Xdisplay, Msg.win);
1477 }
1478#ifndef NO_REMINDER_EXEC
1479 else if (ev.xbutton.subwindow == msgButton.Start)
1480 { 1536 {
1481 system (execPrgm); 1537 if (ev.xbutton.subwindow == msgButton.Dismiss)
1538 {
1482 Next_Reminder (REPLACE); 1539 Next_Reminder (REPLACE);
1483 Msg_Mapped = 0; 1540 Msg_Mapped = 0;
1484 XUnmapWindow (Xdisplay, Msg.win); 1541 XUnmapWindow (Xdisplay, Msg.win);
1542 }
1543 else if (ev.xbutton.subwindow == msgButton.Defer)
1544 {
1545 time_t t = time (NULL) + adjustTime;
1546
1547 tmval = localtime (&t);
1548 reminderTime = mk_time (tmval) + DEFER_TIME;
1549 Msg_Mapped = 0;
1550 XUnmapWindow (Xdisplay, Msg.win);
1551 }
1552# ifndef NO_REMINDER_EXEC
1553 else if (ev.xbutton.subwindow == msgButton.Start)
1554 {
1555 system (execPrgm);
1556 Next_Reminder (REPLACE);
1557 Msg_Mapped = 0;
1558 XUnmapWindow (Xdisplay, Msg.win);
1559 }
1560# endif/* NO_REMINDER_EXEC */
1485 } 1561 }
1486#endif /* NO_REMINDER_EXEC */
1487 }
1488#endif 1562#endif
1489#ifdef MAIL 1563#ifdef MAIL
1490 if (ev.xany.window == Clock.win) 1564 if (ev.xany.window == Clock.win)
1491 { 1565 {
1492#ifdef MAIL_SPAWN 1566# ifdef MAIL_SPAWN
1493 /* left button action - spawn a mail reader */ 1567 /* left button action - spawn a mail reader */
1494 if (ev.xbutton.button == Button1) 1568 if (ev.xbutton.button == Button1)
1495 system (MAIL_SPAWN); 1569 system (MAIL_SPAWN);
1496#else 1570# else
1497 if ( (ev.xbutton.button == Button1) && (mail_spawn != NULL) ) 1571 if ((ev.xbutton.button == Button1) && (mail_spawn != NULL))
1498 system(mail_spawn); 1572 system (mail_spawn);
1499#endif 1573# endif
1500 /* redraw the window */ 1574 /* redraw the window */
1501 Draw_Window (&Clock, 1); 1575 Draw_Window (&Clock, 1);
1502 } 1576 }
1503#endif 1577#endif
1504 break; 1578 break;
1505 } 1579 }
1506 } 1580 }
1507 1581
1508 /* Now wait for time out or new X event */ 1582 /* Now wait for time out or new X event */
1509 FD_ZERO (&in_fdset); 1583 FD_ZERO (&in_fdset);
1510 FD_SET (Xfd, &in_fdset); 1584 FD_SET (Xfd, &in_fdset);
1511 tm.tv_sec = clockUpdate; 1585 tm.tv_sec = clockUpdate;
1514 1588
1515 Draw_Window (&Clock, 0); 1589 Draw_Window (&Clock, 0);
1516#ifdef ICONWIN 1590#ifdef ICONWIN
1517 Draw_Window (&Icon, 0); 1591 Draw_Window (&Icon, 0);
1518#endif 1592#endif
1519 } 1593 }
1520} 1594}
1521 1595
1522/* 1596/*
1523 * Print an error message. 1597 * Print an error message.
1524 */ 1598 */
1525static void 1599static void
1526print_error (const char * fmt, ...) 1600print_error (const char *fmt, ...)
1527{ 1601{
1528 va_list arg_ptr; 1602 va_list arg_ptr;
1529 1603
1530 va_start (arg_ptr, fmt); 1604 va_start (arg_ptr, fmt);
1531 fprintf (stderr, APL_NAME ": "); 1605 fprintf (stderr, APL_NAME ": ");
1532 vfprintf (stderr, fmt, arg_ptr); 1606 vfprintf (stderr, fmt, arg_ptr);
1533 fprintf (stderr,"\n"); 1607 fprintf (stderr, "\n");
1534 va_end (arg_ptr); 1608 va_end (arg_ptr);
1535} 1609}
1610
1536/*----------------------- end-of-file (C source) -----------------------*/ 1611/*----------------------- end-of-file (C source) -----------------------*/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines