1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-07-02 18:32:20 +03:00
gmenu2x/src/clock.cpp

97 lines
2.0 KiB
C++
Raw Normal View History

2013-07-22 06:54:09 +03:00
#include "clock.h"
2013-07-22 06:54:09 +03:00
#include "debug.h"
#include "inputmanager.h"
#include <sys/time.h>
2013-07-22 06:54:09 +03:00
static void notify()
2013-07-22 06:54:09 +03:00
{
SDL_UserEvent e = {
.type = SDL_USEREVENT,
.code = REPAINT_MENU,
.data1 = NULL,
.data2 = NULL,
};
/* Inject an user event, that will be handled as a "repaint"
* event by the InputManager */
SDL_PushEvent((SDL_Event *) &e);
}
extern "C" Uint32 clockCallbackFunc(Uint32 timeout, void *d);
class Clock::Forwarder {
static unsigned int clockCallbackFunc(Clock *clock)
{
return clock->clockCallback();
}
friend Uint32 clockCallbackFunc(Uint32 timeout, void *d);
};
extern "C" Uint32 clockCallbackFunc(Uint32 timeout, void *d)
2013-07-22 06:54:09 +03:00
{
return Clock::Forwarder::clockCallbackFunc(static_cast<Clock *>(d));
}
2013-07-22 06:54:09 +03:00
unsigned int Clock::clockCallback()
{
unsigned int ms = update();
2013-07-22 06:54:09 +03:00
notify();
return ms;
2013-07-22 06:54:09 +03:00
}
std::string Clock::getTime(bool is24)
2013-07-22 06:54:09 +03:00
{
char buf[9];
int h = hours;
bool pm = hours >= 12;
if (!is24 && pm)
h -= 12;
sprintf(buf, "%02i:%02i%s", h, minutes, is24 ? "" : (pm ? "pm" : "am"));
return std::string(buf);
2013-07-22 06:54:09 +03:00
}
unsigned int Clock::update()
2013-07-22 06:54:09 +03:00
{
struct timeval tv;
struct tm result;
gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &result);
minutes = result.tm_min;
hours = result.tm_hour;
DEBUG("Time updated: %02i:%02i:%02i\n", hours, minutes, result.tm_sec);
// Compute number of milliseconds to next minute boundary.
// We don't need high precision, but it is important that any deviation is
// past the minute mark, so the fetched hour and minute number belong to
// the freshly started minute.
// Clamping it at 1 sec both avoids overloading the system in case our
// computation goes haywire and avoids passing 0 to SDL, which would stop
// the recurring timer.
return std::max(1, (60 - result.tm_sec)) * 1000;
2013-07-22 06:54:09 +03:00
}
void Clock::addTimer(int timeout)
{
timer = SDL_AddTimer(timeout, clockCallbackFunc, this);
2013-07-22 06:54:09 +03:00
if (timer == NULL)
ERROR("Could not initialize SDLTimer: %s\n", SDL_GetError());
}
Clock::Clock()
2013-07-22 06:54:09 +03:00
{
tzset();
unsigned int ms = update();
addTimer(ms);
2013-07-22 06:54:09 +03:00
}
Clock::~Clock()
{
SDL_RemoveTimer(timer);
}