static void ok_button_clicked(GtkButton *b, gpointer d) { UINT8 calendar_buf[8]; const gchar *entryp; BOOL renewal; UINT8 val; int i; renewal = FALSE; if (np2cfg.calendar != calendar_kind) { renewal = TRUE; } if (!np2cfg.calendar) { memset(calendar_buf, 0, sizeof(calendar_buf)); for (i = 0; i < NELEMENTS(vircal); i++) { entryp = gtk_entry_get_text(GTK_ENTRY(vircal[i].entry)); val = getbcd(entryp, 2); if (val >= vircal[i].min && val <= vircal[i].max) { if (i == 1) { val = ((val & 0x10) * 10) + (val << 4); } calendar_buf[i] = (UINT8)val; } else { break; } } if (i == NELEMENTS(vircal)) { calendar_set(calendar_buf); } else { renewal = FALSE; } } if (renewal) { np2cfg.calendar = calendar_kind; sysmng_update(SYS_UPDATECFG); } gtk_widget_destroy((GtkWidget *)d); }
LRESULT CALLBACK ClndDialogProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { TCHAR work[32]; UINT8 b; int i; HWND subwnd; switch (msg) { case WM_INITDIALOG: // 時間をセット。 calendar_getvir(cbuf); set_cal2dlg(hWnd, cbuf); if (np2cfg.calendar) { vircalendar(hWnd, FALSE); subwnd = GetDlgItem(hWnd, IDC_CLNDREAL); } else { vircalendar(hWnd, TRUE); subwnd = GetDlgItem(hWnd, IDC_CLNDVIR); } SendMessage(subwnd, BM_SETCHECK, TRUE, 0); SetFocus(subwnd); return(FALSE); case WM_COMMAND: switch(LOWORD(wp)) { case IDOK: b = (UINT8)GetDlgItemCheck(hWnd, IDC_CLNDREAL); if (np2cfg.calendar != b) { np2cfg.calendar = b; sysmng_update(SYS_UPDATECFG); } for (i=0; i<6; i++) { GetDlgItemText(hWnd, vircal[i].res, work, NELEMENTS(work)); b = getbcd(work, 2); if ((b >= vircal[i].min) && (b <= vircal[i].max)) { if (i == 1) { b = ((b & 0x10) * 10) + (b << 4); } cbuf[i] = b; } } calendar_set(cbuf); EndDialog(hWnd, IDOK); break; case IDCANCEL: EndDialog(hWnd, IDCANCEL); break; case IDC_CLNDVIR: vircalendar(hWnd, TRUE); return(FALSE); case IDC_CLNDREAL: vircalendar(hWnd, FALSE); return(FALSE); case IDC_SETNOW: calendar_getreal(cbuf); set_cal2dlg(hWnd, cbuf); return(FALSE); default: return(FALSE); } break; case WM_CLOSE: PostMessage(hWnd, WM_COMMAND, IDCANCEL, 0); break; default: return(FALSE); } return(TRUE); }
uint32_t decode_time(uint8_t init_min, uint8_t minlen, uint32_t acc_minlen, const uint8_t * const buffer, struct tm * const time) { struct tm newtime; uint32_t rval = 0; int16_t increase, i; uint8_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, utchour; int8_t centofs; bool generr, p1, p2, p3, ok; static uint32_t acc_minlen_partial, old_acc_minlen; static bool olderr, prev_toolong; memset(&newtime, 0, sizeof(newtime)); /* Initially, set time offset to unknown */ if (init_min == 2) time->tm_isdst = -1; newtime.tm_isdst = time->tm_isdst; /* save DST value */ if (minlen < 59) rval |= DT_SHORT; if (minlen > 60) rval |= DT_LONG; if (buffer[0] == 1) rval |= DT_B0; if (buffer[20] == 0) rval |= DT_B20; if (buffer[17] == buffer[18]) rval |= DT_DSTERR; generr = (rval != 0); /* do not decode if set */ if (buffer[15] == 1) rval |= DT_XMIT; /* See if there are any partial / split minutes to be combined: */ if (acc_minlen <= 59000) { acc_minlen_partial += acc_minlen; if (acc_minlen_partial >= 60000) { acc_minlen = acc_minlen_partial; acc_minlen_partial %= 60000; } } /* Calculate number of minutes to increase time with: */ if (prev_toolong) increase = (int16_t)((acc_minlen - old_acc_minlen) / 60000); else increase = (int16_t)(acc_minlen / 60000); if (acc_minlen >= 60000) acc_minlen_partial %= 60000; /* Account for complete minutes with a short acc_minlen: */ if (acc_minlen % 60000 > 59000) { increase++; acc_minlen_partial %= 60000; } prev_toolong = (minlen == 0xff); old_acc_minlen = acc_minlen - (acc_minlen % 60000); /* There is no previous time on the very first (partial) minute: */ if (init_min < 2) { for (i = increase; increase > 0 && i > 0; i--) add_minute(time, true); for (i = increase; increase < 0 && i < 0; i++) substract_minute(time, false); } p1 = getpar(buffer, 21, 28); tmp0 = getbcd(buffer, 21, 24); tmp1 = getbcd(buffer, 25, 27); if (!p1 || tmp0 > 9 || tmp1 > 5) { rval |= DT_MIN; p1 = false; } if ((init_min == 2 || increase != 0) && p1 && !generr) { newtime.tm_min = (int)(tmp0 + 10 * tmp1); if (init_min == 0 && time->tm_min != newtime.tm_min) rval |= DT_MINJUMP; } p2 = getpar(buffer, 29, 35); tmp0 = getbcd(buffer, 29, 32); tmp1 = getbcd(buffer, 33, 34); if (!p2 || tmp0 > 9 || tmp1 > 2 || tmp0 + 10 * tmp1 > 23) { rval |= DT_HOUR; p2 = false; } if ((init_min == 2 || increase != 0) && p2 && !generr) { newtime.tm_hour = (int)(tmp0 + 10 * tmp1); if (init_min == 0 && time->tm_hour != newtime.tm_hour) rval |= DT_HOURJUMP; } p3 = getpar(buffer, 36, 58); tmp0 = getbcd(buffer, 36, 39); tmp1 = getbcd(buffer, 40, 41); tmp2 = getbcd(buffer, 42, 44); tmp3 = getbcd(buffer, 45, 48); tmp4 = getbcd(buffer, 50, 53); tmp5 = getbcd(buffer, 54, 57); if (!p3 || tmp0 > 9 || tmp0 + 10 * tmp1 == 0 || tmp0 + 10 * tmp1 > 31 || tmp2 == 0 || tmp3 > 9 || tmp3 + 10 * buffer[49] == 0 || tmp3 + 10 * buffer[49] > 12 || tmp4 > 9 || tmp5 > 9) { rval |= DT_DATE; p3 = false; } if ((init_min == 2 || increase != 0) && p3 && !generr) { newtime.tm_mday = (int)(tmp0 + 10 * tmp1); newtime.tm_mon = (int)(tmp3 + 10 * buffer[49]); newtime.tm_year = (int)(tmp4 + 10 * tmp5); newtime.tm_wday = (int)tmp2; if (init_min == 0 && time->tm_mday != newtime.tm_mday) rval |= DT_MDAYJUMP; if (init_min == 0 && time->tm_wday != newtime.tm_wday) rval |= DT_WDAYJUMP; if (init_min == 0 && time->tm_mon != newtime.tm_mon) rval |= DT_MONTHJUMP; centofs = century_offset(newtime); if (centofs == -1) { rval |= DT_DATE; p3 = false; } else { if (init_min == 0 && time->tm_year != (int)(BASEYEAR + 100 * centofs + newtime.tm_year)) rval |= DT_YEARJUMP; newtime.tm_year += BASEYEAR + 100 * centofs; if (newtime.tm_mday > (int)lastday(newtime)) { rval |= DT_DATE; p3 = false; } } } ok = !generr && p1 && p2 && p3; /* shorthand */ utchour = get_utchour(*time); /* * h==23, last day of month (UTC) or h==0, first day of next month (UTC) * according to IERS Bulletin C * flag still set at 00:00 UTC, prevent DT_LEAPERR */ if (buffer[19] == 1 && ok) { if (time->tm_mday == 1 && is_leapsecmonth(*time) && ((time->tm_min > 0 && utchour == 23) || (time->tm_min == 0 && utchour == 0))) announce |= ANN_LEAP; else { announce &= ~ANN_LEAP; rval |= DT_LEAPERR; } } /* process possible leap second, always reset announcement at hh:00 */ if (((announce & ANN_LEAP) == ANN_LEAP) && time->tm_min == 0) { announce &= ~ANN_LEAP; rval |= DT_LEAP; if (minlen == 59) { /* leap second processed, but missing */ rval |= DT_SHORT; ok = false; generr = true; } else if (minlen == 60 && buffer[59] == 1) rval |= DT_LEAPONE; } if ((minlen == 60) && ((rval & DT_LEAP) == 0)) { /* leap second not processed, so bad minute */ rval |= DT_LONG; ok = false; generr = true; } /* h==0 (UTC) because sz->wz -> h==2 and wz->sz -> h==1, * last Sunday of month (reference?) */ if (buffer[16] == 1 && ok) { if ((time->tm_wday == 7 && time->tm_mday > (int)(lastday(*time) - 7) && (time->tm_mon == (int)summermonth || time->tm_mon == (int)wintermonth)) && ((time->tm_min > 0 && utchour == 0) || (time->tm_min == 0 && utchour == 1 + buffer[17] - buffer[18]))) announce |= ANN_CHDST; /* time zone just changed */ else { announce &= ~ANN_CHDST; rval |= DT_CHDSTERR; } } if ((int)buffer[17] != time->tm_isdst || (int)buffer[18] == time->tm_isdst) { /* Time offset change is OK if: * announced and time is Sunday, lastday, 01:00 UTC * there was an error but not any more (needed if decoding at * startup is problematic) * initial state (otherwise DST would never be valid) */ if ((((announce & ANN_CHDST) == ANN_CHDST) && time->tm_min == 0) || (olderr && ok) || ((rval & DT_DSTERR) == 0 && time->tm_isdst == -1)) newtime.tm_isdst = (int)buffer[17]; /* expected change */ else { if ((rval & DT_DSTERR) == 0) rval |= DT_DSTJUMP; /* sudden change, ignore */ ok = false; } } /* check if DST is within expected date range */ if ((time->tm_mon > (int)summermonth && time->tm_mon < (int)wintermonth) || (time->tm_mon == (int)summermonth && time->tm_wday < 7 && (int)(lastday(*time)) - time->tm_mday < 7) || (time->tm_mon == (int)summermonth && time->tm_wday == 7 && (int)(lastday(*time)) - time->tm_mday < 7 && utchour > 0) || (time->tm_mon == (int)wintermonth && time->tm_wday < 7 && (int)(lastday(*time)) - time->tm_mday >= 7) || (time->tm_mon == (int)wintermonth && time->tm_wday == 7 && (int)(lastday(*time)) - time->tm_mday < 7 && (utchour >= 22 /* previous day */ || utchour == 0))) { /* expect DST */ if (newtime.tm_isdst == 0 && (announce & ANN_CHDST) == 0 && utchour < 24) { rval |= DT_DSTJUMP; /* sudden change */ ok = false; } } else { /* expect non-DST */ if (newtime.tm_isdst == 1 && (announce & ANN_CHDST) == 0 && utchour < 24) { rval |= DT_DSTJUMP; /* sudden change */ ok = false; } } /* done with DST */ if (((announce & ANN_CHDST) == ANN_CHDST) && time->tm_min == 0) { announce &= ~ANN_CHDST; rval |= DT_CHDST; } newtime.tm_gmtoff = 3600 * (newtime.tm_isdst + 1); if (olderr && ok) olderr = false; if (!generr) { if (p1) time->tm_min = newtime.tm_min; if (p2) time->tm_hour = newtime.tm_hour; if (p3) { time->tm_mday = newtime.tm_mday; time->tm_mon = newtime.tm_mon; time->tm_year = newtime.tm_year; time->tm_wday = newtime.tm_wday; } if ((rval & DT_DSTJUMP) == 0) { time->tm_isdst = newtime.tm_isdst; time->tm_gmtoff = newtime.tm_gmtoff; } } if (!ok) olderr = true; return rval | announce; }