📄 rclock.c
字号:
szHint.width = width + szHint.base_width; szHint.flags |= USSize; } if (flags & HeightValue) { szHint.height = height + szHint.base_height; szHint.flags |= USSize; } if (flags & XValue) { if (flags & XNegative) { x += (DisplayWidth (Xdisplay, Xscreen) - szHint.width); szHint.win_gravity = NorthEastGravity; } szHint.x = x; szHint.flags |= USPosition; } if (flags & YValue) { if (flags & YNegative) { y += (DisplayHeight (Xdisplay, Xscreen) - szHint.height); szHint.win_gravity = (szHint.win_gravity == NorthEastGravity ? SouthEastGravity : SouthWestGravity); } szHint.y = y; szHint.flags |= USPosition; } /* copy out values */ win->width = szHint.width; win->height = szHint.height;}/* * Open and map the windows */static voidCreate_Windows (int argc, char * argv []){ XClassHint classHint; XWMHints wmHint; geometry2sizehint (&Clock, rs_geometry); Clock.win = XCreateSimpleWindow (Xdisplay, Xroot, szHint.x, szHint.y, Clock.width, Clock.height, 0, PixColors [fgColor], PixColors [bgColor]);#ifdef ICONWIN geometry2sizehint (&Icon, rs_iconGeometry); Icon.win = XCreateSimpleWindow (Xdisplay, Xroot, szHint.x, szHint.y, Icon.width, Icon.height, 0, PixColors [fgColor], PixColors [bgColor]); wmHint.initial_state = iconic_state; wmHint.icon_window = Icon.win; wmHint.flags = InputHint | StateHint | IconWindowHint;#else wmHint.flags = InputHint;#endif wmHint.input = True; /* ignore warning about discarded `const' */ classHint.res_name = APL_NAME; classHint.res_class = APL_CLASS; XSetWMProperties (Xdisplay, Clock.win, NULL, NULL, argv, argc, &szHint, &wmHint, &classHint); XSelectInput (Xdisplay, Clock.win, (ExposureMask|StructureNotifyMask|ButtonPressMask));#ifdef ICONWIN XSelectInput (Xdisplay, Icon.win, (ExposureMask|ButtonPressMask));#endif XMapWindow (Xdisplay, Clock.win); /* create, but don't map a window for appointment reminders */#ifdef REMINDERS Msg.win = XCreateSimpleWindow (Xdisplay, Xroot, szHint.x, szHint.y, szHint.width, szHint.height, 0, PixColors [fgColor], PixColors [bgColor]); szHint.flags |= USPosition; /* ignore warning about discarded `const' */ classHint.res_name = MSG_NAME; classHint.res_class = MSG_CLASS; wmHint.input = True; wmHint.flags = InputHint; XSetWMProperties (Xdisplay, Msg.win, NULL, NULL, argv, argc, &szHint, &wmHint, &classHint); { char * str = MSG_NAME; XStoreName (Xdisplay, Msg.win, str); XSetIconName (Xdisplay, Msg.win, str); } XSelectInput (Xdisplay, Msg.win, (ExposureMask|ButtonPressMask|KeyPressMask)); /* font already loaded */ msgButton.width = 4 + 5 * XTextWidth (Xfont, "M", 1); msgButton.height = 4 + FontHeight (); msgButton.Dismiss = XCreateSimpleWindow (Xdisplay, Msg.win, 0, 0, msgButton.width, msgButton.height, 0, PixColors [bgColor], PixColors [fgColor]); XMapWindow (Xdisplay, msgButton.Dismiss); msgButton.Defer = XCreateSimpleWindow (Xdisplay, Msg.win, 0, 0, msgButton.width, msgButton.height, 0, PixColors [bgColor], PixColors [fgColor]); XMapWindow (Xdisplay, msgButton.Defer);#ifndef NO_REMINDER_EXEC msgButton.Start = XCreateSimpleWindow (Xdisplay, Msg.win, 0, 0, msgButton.width, msgButton.height, 0, PixColors [bgColor], PixColors [fgColor]); XMapWindow (Xdisplay, msgButton.Start);#endif /* NO_REMINDER_EXEC */#endif}static time_tmk_time (struct tm * tmval){ return (tmval->tm_min + 60 * (tmval->tm_hour + 24 * (tmval->tm_mday + 31 * ((tmval->tm_mon+1) + 12 * tmval->tm_year))));}#ifdef MAILstatic intMailAvailable(){ struct stat st; if( is_maildir ) { DIR *dirp; struct dirent *d; if( (dirp=opendir( mail_file )) ) { while( (d=readdir(dirp)) ) { if( *d->d_name == '.' ) continue; if( isdigit(*d->d_name) ) { closedir(dirp); return 1; } } closedir(dirp); } return 0; } else return !stat(mail_file, &st) && (st.st_size > 0) && (st.st_mtime >= st.st_atime);}#endif/*----------------------------------------------------------------------* * Redraw the whole window after an exposure or size change. * After a timeout, only redraw the hands. * Provide reminder if needed. *----------------------------------------------------------------------*/static voidDraw_Window (mywindow_t * W, int full_redraw){ /* pre-computed values for sin() x1000, to avoid using floats */ static const short Sin [60] = { 0, 105, 208, 309, 407, 500, 588, 669, 743, 809, 866, 914, 951, 978, 995, 1000, 995, 978, 951, 914, 866, 809, 743, 669, 588, 500, 407, 309, 208, 105, 0, -105, -208, -309, -407, -500, -588, -669, -743, -809, -866, -914, -951, -978, -995, -1000, -995, -978, -951, -914, -866, -809, -743, -669, -588, -500, -407, -309, -208, -105 }; static int savedDay = -1; time_t currentTime; struct tm * tmval; int ctr_x, ctr_y; typedef struct { int h_x, h_y; /* hour */ int m_x, m_y; /* minute */ int s_x, s_y; /* second */ } hands_t; /* hand positions (x,y) */ hands_t HandsNow, * pHandsOld; GC X_gc, X_rvgc; static hands_t HandsOld = { -1 };#ifdef ICONWIN static hands_t HandsOld_icon = { -1 };#endif#ifdef REMINDERS static int lastUpdateTime = -10;#endif#ifdef MAIL static time_t mailTime = 0; static int MailUp = 0, MailUp_rvideo = 0;#ifdef ICONWIN static int MailUp_icon = 0;#endif#endif /* MAIL */ currentTime = time (NULL) + adjustTime; /* get the current time */ tmval = localtime (¤tTime);#ifdef MAIL#ifdef REMINDERS if (W->win != Msg.win)#endif { int * pMailUp = (#ifdef ICONWIN W->win == Icon.win ? &MailUp_icon :#endif &MailUp); if ((currentTime - mailTime) >= mailUpdate) { struct stat st; if (#ifdef ICONWIN MailUp != MailUp_icon ? MailUp :#endif ((mail_file != NULL) && MailAvailable() ) ) { if (!*pMailUp) { *pMailUp = 1; full_redraw = 1; XSetWindowBackground (Xdisplay, W->win, PixColors [fgColor]);#ifdef MAIL_BELL XBell (Xdisplay, 0);#endif } } else { if (*pMailUp) { *pMailUp = 0; full_redraw = 1; XSetWindowBackground (Xdisplay, W->win, PixColors [bgColor]); } }#ifdef ICONWIN if (MailUp == MailUp_icon)#endif mailTime = currentTime; MailUp_rvideo = *pMailUp; } }#endif /* MAIL */ /* once every day, update the window and icon name */ if (tmval->tm_yday != savedDay) { char str [20]; savedDay = tmval->tm_yday; strftime (str, sizeof(str), "%a %h %d", tmval); XStoreName (Xdisplay, Clock.win, str); XSetIconName (Xdisplay, Clock.win, str); } if (full_redraw) XClearWindow (Xdisplay, W->win);#ifdef REMINDERS /* for a message window, just re-draw the message */ if (W->win == Msg.win) { char * beg, * next; int lines; for (beg = message, lines = 0; beg; beg = next, lines++) { char * end; if ((end = strstr (beg, "\\n")) == NULL) { end = beg + strlen (beg); next = NULL; } else { next = end + 2; } XDrawString (Xdisplay, Msg.win, Xgc, (Msg.width - XTextWidth (Xfont, beg, (end-beg))) / 2, 10 + Xfont->ascent + FontHeight () * lines, beg, (end-beg)); } XDrawString (Xdisplay, msgButton.Dismiss, Xrvgc, (msgButton.width - XTextWidth (Xfont, "Done", 4)) / 2, Xfont->ascent + 2, "Done", 4); XDrawString (Xdisplay, msgButton.Defer, Xrvgc, (msgButton.width - XTextWidth (Xfont, "Defer", 5)) / 2, Xfont->ascent + 2, "Defer", 5);# ifndef NO_REMINDER_EXEC XDrawString (Xdisplay, msgButton.Start, Xrvgc, (msgButton.width - XTextWidth (Xfont, "Start", 5)) / 2, Xfont->ascent + 2, "Start", 5); if (strlen (execPrgm) > 1) XMapWindow (Xdisplay, msgButton.Start); else XUnmapWindow (Xdisplay, msgButton.Start);# endif /* NO_REMINDER_EXEC */ return; } /* * Convert multi-field time info to a single integer with a resolution * in minutes. */ currentTime = mk_time (tmval); /* is there a reminder pending? */ if (reminderTime >= 0 && currentTime >= reminderTime) Reminder (); /* every 10 minutes, or at start of day, check for revised entries */ if (!Msg_Mapped && (currentTime > lastUpdateTime + REMINDERS_TIME || (currentTime != lastUpdateTime && tmval->tm_hour == 0 && tmval->tm_min == 0))) { Next_Reminder (UPDATE); lastUpdateTime = currentTime; }#endif /* * draw clock */ ctr_x = (W->width / 2); ctr_y = (W->height / 2);#define XPOS(i,val) (ctr_x + (W->width * Sin[i%60] * (val) + 100000) / 200000)#define YPOS(i,val) (ctr_y - (W->height * Sin[(i+15)%60] * (val) + 100000) / 200000) /* * how to draw the clock face */ /* calculate the positions of the hands */ { int angle = (tmval->tm_hour % 12) * 5 + (tmval->tm_min / 12); HandsNow.h_x = XPOS (angle, 60); HandsNow.h_y = YPOS (angle, 60); } { int angle = tmval->tm_min; HandsNow.m_x = XPOS (angle, 80); HandsNow.m_y = YPOS (angle, 80); } if (clockUpdate == 1) { int angle = tmval->tm_sec; HandsNow.s_x = XPOS (angle, 85); HandsNow.s_y = YPOS (angle, 85); } pHandsOld = (#ifdef ICONWIN W->win == Icon.win ? &HandsOld_icon :#endif &HandsOld);#ifdef MAIL if (MailUp_rvideo) { X_gc = Xrvgc; X_rvgc = Xgc; } else#endif { X_gc = Xgc; X_rvgc = Xrvgc; } /* * Draw the date in the lower half of the clock window. * The code is enclosed in REMINDERS because it uses the same * font as the reminders code. * I believe this should be drawn always so it does not get * "swept away" by the minute hand. */#ifdef REMINDERS && DATE_ON_CLOCK_FACE if( show_date) { char date[10]; currentTime = time (NULL) + adjustTime; /* get the current time */ tmval = localtime (¤tTime); strftime (date, sizeof(date), "%d", tmval); XDrawString (Xdisplay, W->win, X_gc, ctr_x - XTextWidth(Xfont, date, strlen(date))/2, ctr_y + FontHeight() + (ctr_y - FontHeight())/2, date, strlen(date)); }#endif if (full_redraw) { int angle; /* * draw clock face */#ifdef SUBTICKS for (angle = 0; angle < 60; angle++) XDrawPoint (Xdisplay, W->win, X_gc, XPOS (angle, 95), YPOS (angle, 95));#endif for (angle = 0; angle < 60; angle += 5) XDrawLine (Xdisplay, W->win, X_gc, XPOS (angle, 90), YPOS (angle, 90), XPOS (angle, 100), YPOS (angle, 100)); } else if (memcmp (pHandsOld, &HandsNow, sizeof(hands_t))) { int i, j; /* * erase old hands */ for (i = -1; i < 2; i++) for (j = -1; j < 2; j++) { /* hour/minute hands */ XDrawLine (Xdisplay, W->win, X_rvgc, ctr_x + i, ctr_y + j, pHandsOld->h_x, pHandsOld->h_y); XDrawLine (Xdisplay, W->win, X_rvgc, ctr_x + i, ctr_y + j, pHandsOld->m_x, pHandsOld->m_y); } if (clockUpdate == 1) /* seconds hand */ XDrawLine (Xdisplay, W->win, X_rvgc, ctr_x, ctr_y, pHandsOld->s_x, pHandsOld->s_y); } if (full_redraw || memcmp (pHandsOld, &HandsNow, sizeof(hands_t))) { int i, j; /* * draw new hands */ for (i = -1; i < 2; i++) for (j = -1; j < 2; j++) { /* hour/minute hands */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -