📄 rclock.c
字号:
XDrawLine (Xdisplay, W->win, X_gc, ctr_x + i, ctr_y + j, HandsNow.h_x, HandsNow.h_y); XDrawLine (Xdisplay, W->win, X_gc, ctr_x + i, ctr_y + j, HandsNow.m_x, HandsNow.m_y); } if (clockUpdate == 1) /* seconds hand */ XDrawLine (Xdisplay, W->win, X_gc, ctr_x, ctr_y, HandsNow.s_x, HandsNow.s_y); *pHandsOld = HandsNow; }}#ifdef REMINDERS/* * Read a single integer from *pstr, returns default value if it finds "*" * DELIM = trailing delimiter to skip */static intGetOneNum (char ** pstr, int def){ int num, hit = 0; for (num = 0; isdigit (**pstr); (*pstr)++) { num = num * 10 + (**pstr - '0'); hit = 1; } if (!hit) { num = def; while (**pstr == '*') (*pstr)++; } return num;}/* * find if TODAY is found in PSTR */static intisToday (char ** pstr, int wday){ const char * dayNames = DAY_NAMES; int rval, today; today = dayNames [wday]; /* no day specified is same as wildcard */ if (!strchr (dayNames, tolower (**pstr))) return 1; for (rval = 0; strchr (dayNames, tolower (**pstr)); (*pstr)++) { if (today == tolower (**pstr) || **pstr == '*') rval = 1; /* found it */ } return rval;}static char *trim_string (char * str){ if (str && *str) { int n; while (*str && isspace (*str)) str++; n = strlen (str) - 1; while (n > 0 && isspace (str [n])) n--; str [n+1] = '\0'; } return str;}# ifndef NO_REMINDER_EXECstatic char *extract_program (char * text){ char * prgm = text; while ((prgm = strchr (prgm, ';')) != NULL) { if (*(prgm-1) == '\\') /* backslash escaped */ { /* remove backslash - avoid memmove() */ int i, n = strlen (prgm); for (i = 0; i <= n; i++) prgm [i - 1] = prgm [i]; } else { *prgm++ = '\0'; /* remove leading/trailing space */ prgm = trim_string (prgm); break; } } return prgm;}# endif /* NO_REMINDER_EXEC *//* * Read the ~/.rclock file and find the next reminder * * update_only = 1 * look for a reminder whose time is greater than the current time, * but less than the currently set reminder time * * update_only = 0 * look for a reminder whose time is greater than the reminder that * just went off */static voidNext_Reminder (int update_only){ struct tm * tmval; char buffer [256];#ifndef INT_MAX# define INT_MAX 1e8#endif time_t currentTime; int savedTime = INT_MAX; FILE * fd; if (reminders_file == NULL || (fd = fopen (reminders_file, "r")) == NULL) { reminderTime = -1; /* no config file, no reminders */ return; } currentTime = time (NULL) + adjustTime; /* get the current time */ tmval = localtime (¤tTime); currentTime = mk_time (tmval); /* initial startup*/ if (reminderTime < 0) { /* ignore reminders that have already occurred */ reminderTime = currentTime;# ifndef NO_REMINDER_EXEC /* scan for programs run on start-up */ while (fgets (buffer, sizeof(buffer), fd)) { char * prgm, * text; text = trim_string (buffer); if (*text != ';') continue; prgm = extract_program (text); if (prgm != NULL && strlen (prgm) > 1) system (prgm); } rewind (fd);# endif /* NO_REMINDER_EXEC */ } /* now scan for next reminder */ while (fgets (buffer, sizeof(buffer), fd)) { int testTime, hh, mm, mo, dd, yy; char * text; text = trim_string (buffer); if (*text == '#') continue; /* comment */ if (*text == ';') continue; /* program run on startup */ /* * parse the line, format is hh:mm mo/dd/yr message; program * any of hh, mm, mo, dd, yr could be a wildcard `*' */ hh = GetOneNum (&text, tmval->tm_hour); if (*text == ':') text++; mm = GetOneNum (&text, 0); while (isspace (*text)) text++; if (!isToday (&text, tmval->tm_wday)) continue; while (isspace (*text)) text++; mo = GetOneNum (&text, tmval->tm_mon+1); if (*text == '/') text++; dd = GetOneNum (&text, tmval->tm_mday); if (*text == '/') text++; yy = GetOneNum (&text, tmval->tm_year); /* handle 20th/21st centuries */ if (yy > CENTURY) yy -= 1900; else if (yy < CENTURY) yy += (CENTURY - 1900); while (isspace (*text)) text++; if (!*text) continue; testTime = (mm + 60 * (hh + 24 * (dd + 31 * (mo + 12 * yy)))); if (testTime > (update_only ? currentTime : reminderTime)) {#ifndef NO_REMINDER_EXEC char * prgm = extract_program (text);#endif /* NO_REMINDER_EXEC */ /* trim leading/trailing space */ text = trim_string (text); /* * have a reminder whose time is greater than the last * reminder, now make sure it is the smallest available */ if (testTime < savedTime) { savedTime = testTime; strncpy (message, text, sizeof(message));#ifndef NO_REMINDER_EXEC strncpy (execPrgm, (prgm ? prgm : ""), sizeof(execPrgm));#endif } else if (testTime == savedTime) { if (strlen (text)) { int n = (sizeof(message) - strlen (message) - 3); if (n > 0) { /* for co-occurring events */ strcat (message, "\\n"); strncat (message, text, n); } }#ifndef NO_REMINDER_EXEC if (prgm != NULL) { int n = (sizeof(execPrgm) - strlen (execPrgm) - 2); if ((n > 0) && (n >= strlen (prgm))) { /* for co-occurring programs */ strcat (execPrgm, ";"); strncat (execPrgm, prgm, n); } }#endif /* NO_REMINDER_EXEC */ } } } reminderTime = (savedTime < INT_MAX) ? savedTime : -1; fclose (fd);}/* * Provide reminder by mapping the message window */static voidReminder (void){ char * beg, * next; int lines; if (Msg_Mapped) return;#ifndef NO_REMINDER_EXEC if (strlen (message) == 0) { if (strlen (execPrgm) > 1) { system (execPrgm); Next_Reminder (REPLACE); } return; /* some sort of error */ }#endif /* compute the window size */#ifdef NO_REMINDER_EXEC Msg.width = 10 * XTextWidth (Xfont, "M", 1);#else Msg.width = 18 * XTextWidth (Xfont, "M", 1);#endif for (beg = message, lines = 1; beg; beg = next, lines++) { int width; char * end; if ((end = strstr (beg, "\\n")) == NULL) { end = beg + strlen (beg); next = NULL; } else { next = end + 2; } width = XTextWidth (Xfont, beg, (end-beg)); if (Msg.width < width) Msg.width = width; } Msg.width += 30; Msg.height = (lines+1) * FontHeight () + 30; /* resize and centre the window */ XMoveResizeWindow (Xdisplay, Msg.win, (DisplayWidth (Xdisplay, Xscreen) - Msg.width ) / 2, (DisplayHeight (Xdisplay, Xscreen) - Msg.height) / 2, Msg.width, Msg.height);#define BUTTON_MARGIN 8 XMoveWindow (Xdisplay, msgButton.Dismiss, BUTTON_MARGIN, (Msg.height - msgButton.height - BUTTON_MARGIN)); XMoveWindow (Xdisplay, msgButton.Defer, (Msg.width - msgButton.width - BUTTON_MARGIN), (Msg.height - msgButton.height - BUTTON_MARGIN));#ifndef NO_REMINDER_EXEC XMoveWindow (Xdisplay, msgButton.Start, (Msg.width - msgButton.width) / 2, (Msg.height - msgButton.height - BUTTON_MARGIN));#endif XMapRaised (Xdisplay, Msg.win); XBell (Xdisplay, 0); Msg_Mapped = 1;}#endif /* REMINDERS */#ifndef _POSIX_VERSION# if defined (__svr4__)static intgetdtablesize (void){ struct rlimit rlim; getrlimit (RLIMIT_NOFILE, &rlim); return rlim.rlim_cur;}# endif#endif/* * Loops forever, looking for stuff to do. Sleeps 1 minute if nothing to do */static voidgetXevent (void){ XEvent ev; int num_fds; /* number of file descriptors being used */ struct timeval tm; struct tm * tmval; Atom wmDeleteWindow; fd_set in_fdset; /* Enable delete window protocol */ wmDeleteWindow = XInternAtom (Xdisplay, "WM_DELETE_WINDOW", False); XSetWMProtocols (Xdisplay, Clock.win, &wmDeleteWindow, 1);#ifdef ICONWIN XSetWMProtocols (Xdisplay, Icon.win, &wmDeleteWindow, 1);#endif#ifdef REMINDERS XSetWMProtocols (Xdisplay, Msg.win, &wmDeleteWindow, 1);#endif#ifdef _POSIX_VERSION num_fds = sysconf (_SC_OPEN_MAX);#else num_fds = getdtablesize ();#endif#ifdef FD_SETSIZE if (num_fds > FD_SETSIZE) num_fds = FD_SETSIZE;#endif while (1) { /* take care of all pending X events */ while (XPending (Xdisplay)) { XNextEvent (Xdisplay, &ev); switch (ev.type) { case ClientMessage: /* check for delete window requests */ if ((ev.xclient.format == 32) && (ev.xclient.data.l[0] == wmDeleteWindow)) {#ifdef REMINDERS if (ev.xany.window == Msg.win) { XUnmapWindow (Xdisplay, Msg.win); Msg_Mapped = 0; Next_Reminder (REPLACE); } else#endif return; /* delete window is how this terminates */ } break; case Expose: case GraphicsExpose: /* need to re-draw a window */ if (ev.xany.window == Clock.win) Draw_Window (&Clock, 1);#ifdef ICONWIN else if (ev.xany.window == Icon.win) Draw_Window (&Icon, 1);#endif#ifdef REMINDERS else Draw_Window (&Msg, 1);#endif break; case ConfigureNotify: /* window has been re-sized */ if (ev.xany.window == Clock.win) { Clock.width = ev.xconfigure.width; Clock.height = ev.xconfigure.height; } break;#ifdef REMINDERS case KeyPress: /* any key press to dismiss message window */ if (ev.xany.window == Msg.win) { Next_Reminder (REPLACE); Msg_Mapped = 0; XUnmapWindow (Xdisplay, Msg.win); } break;#endif case ButtonPress:#ifdef REMINDERS /* button press to dismiss message window */ if (ev.xany.window == Msg.win) { if (ev.xbutton.subwindow == msgButton.Dismiss) { Next_Reminder (REPLACE); Msg_Mapped = 0; XUnmapWindow (Xdisplay, Msg.win); } else if (ev.xbutton.subwindow == msgButton.Defer) { time_t t = time (NULL) + adjustTime; tmval = localtime (&t); reminderTime = mk_time (tmval) + DEFER_TIME; Msg_Mapped = 0; XUnmapWindow (Xdisplay, Msg.win); }#ifndef NO_REMINDER_EXEC else if (ev.xbutton.subwindow == msgButton.Start) { system (execPrgm); Next_Reminder (REPLACE); Msg_Mapped = 0; XUnmapWindow (Xdisplay, Msg.win); }#endif /* NO_REMINDER_EXEC */ }#endif#ifdef MAIL if (ev.xany.window == Clock.win) {#ifdef MAIL_SPAWN /* left button action - spawn a mail reader */ if (ev.xbutton.button == Button1) system (MAIL_SPAWN);#else if ( (ev.xbutton.button == Button1) && (mail_spawn != NULL) ) system(mail_spawn);#endif /* redraw the window */ Draw_Window (&Clock, 1); }#endif break; } } /* Now wait for time out or new X event */ FD_ZERO (&in_fdset); FD_SET (Xfd, &in_fdset); tm.tv_sec = clockUpdate; tm.tv_usec = 0; select (num_fds, &in_fdset, NULL, NULL, &tm); Draw_Window (&Clock, 0);#ifdef ICONWIN Draw_Window (&Icon, 0);#endif }}/* * Print an error message. */static voidprint_error (const char * fmt, ...){ va_list arg_ptr; va_start (arg_ptr, fmt); fprintf (stderr, APL_NAME ": "); vfprintf (stderr, fmt, arg_ptr); fprintf (stderr,"\n"); va_end (arg_ptr);}/*----------------------- end-of-file (C source) -----------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -