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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines