~ubuntu-branches/ubuntu/karmic/gnash/karmic

« back to all changes in this revision

Viewing changes to libbase/ClockTime.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2008-10-13 14:29:49 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20081013142949-f6qdvnu4mn05ltdc
Tags: 0.8.4~~bzr9980-0ubuntu1
* new upstream release 0.8.4 (LP: #240325)
* ship new lib usr/lib/gnash/libmozsdk.so.* in mozilla-plugin-gnash
  - update debian/mozilla-plugin-gnash.install
* ship new lib usr/lib/gnash/libgnashnet.so.* in gnash-common
  - update debian/gnash-common.install
* add basic debian/build_head script to build latest CVS head packages.
  - add debian/build_head
* new sound architecture requires build depend on libsdl1.2-dev
  - update debian/control
* head build script now has been completely migrated to bzr (upstream +
  ubuntu)
  - update debian/build_head
* disable kde gui until klash/qt4 has been fixed; keep kde packages as empty
  packages for now.
  - update debian/rules
  - debian/klash.install
  - debian/klash.links
  - debian/klash.manpages
  - debian/konqueror-plugin-gnash.install
* drop libkonq5-dev build dependency accordingly
  - update debian/control
* don't install headers manually anymore. gnash doesnt provide a -dev
  package after all
  - update debian/rules
* update libs installed in gnash-common; libgnashserver-*.so is not available
  anymore (removed); in turn we add the new libgnashcore-*.so
  - update debian/gnash-common.install
* use -Os for optimization and properly pass CXXFLAGS=$(CFLAGS) to configure
  - update debian/rules
* touch firefox .autoreg in postinst of mozilla plugin
  - update debian/mozilla-plugin-gnash.postinst
* link gnash in ubufox plugins directory for the plugin alternative switcher
  - add debian/mozilla-plugin-gnash.links
* suggest ubufox accordingly
  - update debian/control
* add new required build-depends on libgif-dev
  - update debian/control
* add Xb-Npp-Description and Xb-Npp-File as new plugin database meta data
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Time.cpp: clock and local time functions for Gnash
 
2
// 
 
3
//   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
4
// 
 
5
// 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
 
7
// the Free Software Foundation; either version 3 of the License, or
 
8
// (at your option) any later version.
 
9
// 
 
10
// This program is distributed in the hope that it will be useful,
 
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
// GNU General Public License for more details.
 
14
// 
 
15
// You should have received a copy of the GNU General Public License
 
16
// along with this program; if not, write to the Free Software
 
17
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 
 
19
/// \page
 
20
/// Gnash has three time implementations: one using boost::date_time,
 
21
/// which handles portability itself, one for POSIX systems and one for 
 
22
/// Win32.
 
23
///
 
24
/// Namespace clocktime contains a unified source for wall clock time: this
 
25
/// is used mainly for the timing of movie advances and in the ActionScript
 
26
/// Date class. FPS profiling also uses clocktime:: for a relatively high resolution,
 
27
/// robust timer.
 
28
///
 
29
/// The boost::date_time has the great advantage of handling portability itself,
 
30
/// as well as being able to handle a much larger range of true dates. Its
 
31
/// disadvantage is that date_time requires not only header files, but also
 
32
/// a run-time library, and thus increases the requirements.
 
33
 
 
34
#include <boost/cstdint.hpp>
 
35
#include "ClockTime.h"
 
36
#include "log.h"
 
37
 
 
38
// Define USE_BOOST_DATE_TIME to use boost as the basis for all
 
39
// clock time functions. The function getTimeZoneOffset() is not
 
40
// yet implemented for boost, but will only affect the Date class.
 
41
#undef USE_BOOST_DATE_TIME
 
42
 
 
43
#ifdef USE_BOOST_DATE_TIME
 
44
 
 
45
#include <boost/date_time/posix_time/posix_time.hpp>
 
46
#include <boost/date_time/microsec_time_clock.hpp>
 
47
 
 
48
using namespace boost::posix_time;
 
49
 
 
50
boost::uint64_t
 
51
clocktime::getTicks()
 
52
{
 
53
 
 
54
    // Midnight, 1st January 1970: the Epoch.
 
55
    static const posix_time::ptime epoch (from_time_t(0));
 
56
    
 
57
    // Time between now and the Epoch.
 
58
    posix_time::time_duration elapsed = (microsec_clock::local_time() - epoch);
 
59
    
 
60
    // Divisor to convert ticks to milliseconds
 
61
    const int denominator = time_duration::ticks_per_second() / 1000.0;
 
62
    
 
63
        return elapsed.ticks() / denominator;
 
64
}
 
65
 
 
66
boost::int32_t
 
67
clocktime::getTimeZoneOffset()
 
68
{
 
69
    // Obviously this doesn't work yet. Using this method
 
70
    // may come up against the problem that boost won't handle
 
71
    // dates outside its limits. However, ActionScript seems
 
72
    // not to regard dates later than 2037 as having dst (this
 
73
    // may depend on a machine-specific tz database) and there
 
74
    // could also be a lower limit.
 
75
 
 
76
    return 0;
 
77
}
 
78
 
 
79
#else // not using boost::date_time
 
80
 
 
81
#include <ctime> // for time_t, localtime
 
82
 
 
83
#if !defined(HAVE_GETTIMEOFDAY) || (!defined(HAVE_TM_GMTOFF) && !defined(HAVE_TZSET))
 
84
#ifdef HAVE_FTIME
 
85
extern "C" {
 
86
#  include <sys/types.h>    // for ftime()
 
87
#  include <sys/timeb.h>    // for ftime()
 
88
}
 
89
#endif
 
90
#endif
 
91
 
 
92
#if !defined(HAVE_TM_GMTOFF)
 
93
# ifdef HAVE_LONG_TIMEZONE
 
94
extern long timezone;   // for tzset()/long timezone;
 
95
# endif
 
96
#endif
 
97
 
 
98
/// Win32 implementation for getTicks
 
99
# if defined(_WIN32) || defined(WIN32)
 
100
#  include <windows.h>
 
101
#  include <mmsystem.h>
 
102
 
 
103
 
 
104
boost::uint64_t
 
105
clocktime::getTicks()
 
106
{
 
107
    // This needs to return milliseconds. Does it?
 
108
        return timeGetTime();
 
109
}
 
110
 
 
111
# else // not _WIN32
 
112
#  include <sys/time.h>
 
113
 
 
114
boost::uint64_t
 
115
clocktime::getTicks()
 
116
{
 
117
 
 
118
        struct timeval tv;
 
119
        
 
120
        gettimeofday(&tv, 0);
 
121
 
 
122
        boost::uint64_t result = static_cast<boost::uint64_t>(tv.tv_sec) * 1000000L;
 
123
 
 
124
        // Time Unit: microsecond
 
125
        result += tv.tv_usec;
 
126
 
 
127
        return static_cast<boost::uint64_t>(result / 1000.0);
 
128
}
 
129
 
 
130
# endif // not WIN32
 
131
 
 
132
/// Common non-boost function to return the present time offset.
 
133
/// This all seems like a terrible hack. It was moved from Date.cpp,
 
134
/// whence the following explanation also comes.
 
135
///
 
136
/// If the real mktime() sees isdst == 0 with a DST date, it sets
 
137
/// t_isdst and modifies the hour fields, but we need to set the
 
138
/// specified hour in the localtime in force at that time.
 
139
///
 
140
/// To do this we set tm_isdst to the correct value for that moment in time
 
141
/// by doing an initial conversion of the time to find out is_dst for that
 
142
/// moment without DST, then do the real conversion.
 
143
/// This may still get things wrong around the hour when the clocks go back
 
144
///
 
145
/// It also gets things wrong for very high or low time values, when the
 
146
/// localtime implementation fills the gmtoff element with 53 minutes (on
 
147
/// at least one machine, anyway).
 
148
boost::int32_t
 
149
clocktime::getTimeZoneOffset(double time)
 
150
{
 
151
    
 
152
    time_t tt = static_cast<time_t>(time / 1000.0);
 
153
 
 
154
    struct tm tm;
 
155
 
 
156
#ifdef HAVE_LOCALTIME_R
 
157
    localtime_r(&tt, &tm);
 
158
#else
 
159
    struct tm *tmp = NULL;
 
160
    tmp = localtime(&tt);
 
161
    if (!tmp) return 0; // We failed.
 
162
    memcpy(&tm, tmp, sizeof(struct tm));
 
163
#endif
 
164
 
 
165
    struct tm tm2 = tm;
 
166
    tm2.tm_isdst = 0;
 
167
 
 
168
    time_t ttmp = 0;
 
169
    
 
170
    ttmp = mktime(&tm2);
 
171
 
 
172
#ifdef HAVE_LOCALTIME_R
 
173
    localtime_r(&ttmp, &tm2);  // find out whether DST is in force
 
174
#else
 
175
    struct tm *tmp2 = NULL;
 
176
    tmp2 = localtime(&ttmp);
 
177
    if (!tmp2) return 0; // We failed.
 
178
    memcpy(&tm2, tmp2, sizeof(struct tm));
 
179
#endif
 
180
 
 
181
    // If mktime or localtime fail, tm2.tm_isdst should be unchanged,
 
182
    // so 0. That's why we don't make any checks on their success.
 
183
 
 
184
    tm.tm_isdst = tm2.tm_isdst;
 
185
 
 
186
#ifdef HAVE_TM_GMTOFF
 
187
 
 
188
    int offset;
 
189
 
 
190
    // tm_gmtoff is in seconds east of GMT; convert to minutes.
 
191
    offset = tm.tm_gmtoff / 60;
 
192
    //gnash::log_debug("Using tm.tm_gmtoff. Offset is %d", offset);
 
193
    return offset;
 
194
 
 
195
#else
 
196
 
 
197
  // Find the geographical system timezone offset and add an hour if
 
198
  // DST applies to the date.
 
199
  // To get it really right I guess we should call both gmtime()
 
200
  // and localtime() and look at the difference.
 
201
  //
 
202
  // The range of standard time is GMT-11 to GMT+14.
 
203
  // The most extreme with DST is Chatham Island GMT+12:45 +1DST
 
204
 
 
205
  int offset;
 
206
 
 
207
# if defined(HAVE_TZSET) && defined(HAVE_LONG_TIMEZONE)
 
208
 
 
209
    tzset();
 
210
    // timezone is seconds west of GMT
 
211
    offset = -timezone / 60;
 
212
    //gnash::log_debug("Using tzset. Offset is %d", offset);
 
213
 
 
214
# elif defined(HAVE_GETTIMEOFDAY)
 
215
 
 
216
    // gettimeofday(3):
 
217
    // "The use of the timezone structure is obsolete; the tz argument
 
218
    // should normally be specified as NULL. The tz_dsttime field has
 
219
    // never been used under Linux; it has not been and will not be
 
220
    // supported by libc or glibc."
 
221
    // Still, mancansa d'asu, t'acuma i buoi (Mangels Esel, Ochsen einspannen...)
 
222
    //
 
223
    // In practice this appears to return the present time offset including dst,
 
224
    // so adding the dst of the time specified (we do this a couple of lines down)
 
225
    // gives the correct result when it's not presently dst, the wrong one when
 
226
    // it is.
 
227
    struct timeval tv;
 
228
    struct timezone tz;
 
229
    gettimeofday(&tv, &tz);
 
230
    offset = -tz.tz_minuteswest;
 
231
    //gnash::log_debug("Using gettimeofday. Offset is %d", offset);
 
232
 
 
233
# elif defined(HAVE_FTIME)
 
234
    // ftime(3): "These days the contents of the timezone and dstflag
 
235
    // fields are undefined."
 
236
    // In practice, timezone is -120 in Italy when it should be -60.
 
237
    // The problem here as for gettimeofday: the offset also includes dst.
 
238
    struct timeb tb;
 
239
    
 
240
    ftime (&tb);
 
241
    // tb.timezone is number of minutes west of GMT
 
242
    offset = -tb.timezone;
 
243
    //gnash::log_debug("Using ftime. Offset is %d", offset);
 
244
 
 
245
# else
 
246
 
 
247
    offset = 0; // No idea.
 
248
    //gnash::log_debug("Cannot find offset. Offset is %d", offset);
 
249
 
 
250
# endif
 
251
 
 
252
  // Adjust by one hour if DST was in force at that time.
 
253
  //
 
254
  // According to http://www.timeanddate.com/time/, the only place that
 
255
  // uses DST != +1 hour is Lord Howe Island with half an hour. Tough.
 
256
 
 
257
    if (tm.tm_isdst == 0) {
 
258
        // DST exists and is not in effect
 
259
    }
 
260
    else if (tm.tm_isdst > 0) {
 
261
        // DST exists and was in effect
 
262
        offset += 60;
 
263
    }
 
264
    else {
 
265
        // tm_isdst is negative: cannot get TZ info.
 
266
        // Convert and print in UTC instead.
 
267
        LOG_ONCE(
 
268
            gnash::log_error(_("Cannot get requested timezone information"));
 
269
        );
 
270
        offset = 0;
 
271
    }
 
272
 
 
273
    return offset;
 
274
 
 
275
#endif // No gmoff
 
276
}
 
277
 
 
278
 
 
279
 
 
280
#endif // Not using boost::date_time