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