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