Handle WM_CHARs and pass them to TREEVIEW_ProcessLetterKeys. See also
[wine] / dlls / kernel / time.c
1 /*
2  * Win32 kernel functions
3  *
4  * Copyright 1995 Martin von Loewis and Cameron Heide
5  */
6
7 #include <string.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <sys/time.h>
11 #include <sys/times.h>
12 #include "file.h"
13 #include "ntddk.h"
14 #include "winerror.h"
15 #include "debugtools.h"
16
17 DEFAULT_DEBUG_CHANNEL(win32);
18
19 /* maximum time adjustment in seconds for SetLocalTime and SetSystemTime */
20 #define SETTIME_MAX_ADJUST 120
21
22 /* TIME_GetBias: helper function calculates delta local time from UTC */
23 static int TIME_GetBias( time_t utc, int *pdaylight)
24 {
25     struct tm *ptm = localtime(&utc);
26     *pdaylight = ptm->tm_isdst; /* daylight for local timezone */
27     ptm = gmtime(&utc);
28     ptm->tm_isdst = *pdaylight; /* use local daylight, not that of Greenwich */
29     return (int)(utc-mktime(ptm));
30 }
31
32
33 /***********************************************************************
34  *              SetLocalTime            (KERNEL32.655)
35  *
36  *  Sets the local time using current time zone and daylight
37  *  savings settings.
38  *
39  * RETURNS
40  *
41  *  True if the time was set, false if the time was invalid or the
42  *  necessary permissions were not held.
43  */
44 BOOL WINAPI SetLocalTime(
45     const SYSTEMTIME *systime) /* [in] The desired local time. */
46 {
47     struct timeval tv;
48     struct tm t;
49     time_t sec;
50     time_t oldsec=time(NULL);
51     int err;
52
53     /* get the number of seconds */
54     t.tm_sec = systime->wSecond;
55     t.tm_min = systime->wMinute;
56     t.tm_hour = systime->wHour;
57     t.tm_mday = systime->wDay;
58     t.tm_mon = systime->wMonth - 1;
59     t.tm_year = systime->wYear - 1900;
60     t.tm_isdst = -1;
61     sec = mktime (&t);
62
63     /* set the new time */
64     tv.tv_sec = sec;
65     tv.tv_usec = systime->wMilliseconds * 1000;
66
67     /* error and sanity check*/
68     if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
69         err = 1;
70         SetLastError(ERROR_INVALID_PARAMETER);
71     } else {
72         err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
73         if(err == 0)
74             return TRUE;
75         SetLastError(ERROR_PRIVILEGE_NOT_HELD);
76     }
77     ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
78             systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
79             systime->wMinute, systime->wSecond,
80             sec-oldsec, err == -1 ? "No Permission" : 
81                 sec==(time_t)-1 ? "" : "is too large." );
82     return FALSE;
83 }
84
85
86 /***********************************************************************
87  *           GetSystemTimeAdjustment     (KERNEL32.407)
88  *
89  *  Indicates the period between clock interrupt and the amount the clock
90  *  is adjusted each interrupt so as to keep it insync with an external source.
91  *
92  * RETURNS
93  *
94  *  Always returns true.
95  *
96  * BUGS
97  *
98  *  Only the special case of disabled time adjustments is supported.
99  *  (also the signature is wrong it should have a return type of BOOL)
100  */
101 DWORD WINAPI GetSystemTimeAdjustment(
102     LPDWORD lpTimeAdjustment,         /* [out] The clock adjustment per interupt in 100's of nanoseconds. */
103     LPDWORD lpTimeIncrement,          /* [out] The time between clock interupts in 100's of nanoseconds. */
104     LPBOOL  lpTimeAdjustmentDisabled) /* [out] The clock synchonisation has been disabled. */
105 {
106     *lpTimeAdjustment = 0;
107     *lpTimeIncrement = 0;
108     *lpTimeAdjustmentDisabled = TRUE;
109     return TRUE;
110 }
111
112
113 /***********************************************************************
114  *              SetSystemTime            (KERNEL32.665)
115  *
116  *  Sets the system time (utc).
117  *
118  * RETURNS
119  *
120  *  True if the time was set, false if the time was invalid or the
121  *  necessary permissions were not held.
122  */
123 BOOL WINAPI SetSystemTime(
124     const SYSTEMTIME *systime) /* [in] The desired system time. */
125 {
126     struct timeval tv;
127     struct timezone tz;
128     struct tm t;
129     time_t sec, oldsec;
130     int dst, bias;
131     int err;
132
133     /* call gettimeofday to get the current timezone */
134     gettimeofday(&tv, &tz);
135     oldsec=tv.tv_sec;
136     /* get delta local time from utc */
137     bias=TIME_GetBias(oldsec,&dst);
138
139     /* get the number of seconds */
140     t.tm_sec = systime->wSecond;
141     t.tm_min = systime->wMinute;
142     t.tm_hour = systime->wHour;
143     t.tm_mday = systime->wDay;
144     t.tm_mon = systime->wMonth - 1;
145     t.tm_year = systime->wYear - 1900;
146     t.tm_isdst = dst;
147     sec = mktime (&t);
148     /* correct for timezone and daylight */
149     sec += bias;
150
151     /* set the new time */
152     tv.tv_sec = sec;
153     tv.tv_usec = systime->wMilliseconds * 1000;
154
155     /* error and sanity check*/
156     if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
157         err = 1;
158         SetLastError(ERROR_INVALID_PARAMETER);
159     } else {
160         err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
161         if(err == 0)
162             return TRUE;
163         SetLastError(ERROR_PRIVILEGE_NOT_HELD);
164     }
165     ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
166             systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
167             systime->wMinute, systime->wSecond,
168             sec-oldsec, err == -1 ? "No Permission" :
169                 sec==(time_t)-1 ? "" : "is too large." );
170     return FALSE;
171 }
172
173
174 /***********************************************************************
175  *              GetTimeZoneInformation  (KERNEL32.424)
176  *
177  *  Fills in the a time zone information structure with values based on
178  *  the current local time.
179  *
180  * RETURNS
181  *
182  *  The daylight savings time standard or TIME_ZONE_ID_INVALID if the call failed.
183  */
184 DWORD WINAPI GetTimeZoneInformation(
185     LPTIME_ZONE_INFORMATION tzinfo) /* [out] The time zone structure to be filled in. */
186 {
187     time_t gmt;
188     int bias, daylight;
189
190     memset(tzinfo, 0, sizeof(TIME_ZONE_INFORMATION));
191
192     gmt = time(NULL);
193     bias=TIME_GetBias(gmt,&daylight);
194
195     tzinfo->Bias = -bias / 60;
196     tzinfo->StandardBias = 0;
197     tzinfo->DaylightBias = -60;
198
199     return TIME_ZONE_ID_STANDARD;
200 }
201
202
203 /***********************************************************************
204  *              SetTimeZoneInformation  (KERNEL32.673)
205  *
206  *  Set the local time zone with values based on the time zone structure.
207  *
208  * RETURNS
209  *
210  *  True on successful setting of the time zone.
211  *
212  * BUGS
213  *
214  *  Use the obsolete unix timezone structure and tz_dsttime member.
215  */
216 BOOL WINAPI SetTimeZoneInformation(
217     const LPTIME_ZONE_INFORMATION tzinfo) /* [in] The new time zone. */
218 {
219     struct timezone tz;
220
221     tz.tz_minuteswest = tzinfo->Bias;
222 #ifdef DST_NONE
223     tz.tz_dsttime = DST_NONE;
224 #else
225     tz.tz_dsttime = 0;
226 #endif
227     return !settimeofday(NULL, &tz);
228 }
229
230
231 /***********************************************************************
232  *              SystemTimeToTzSpecificLocalTime  (KERNEL32.683)
233  *
234  *  Converts the system time (utc) to the local time in the specified time zone.
235  *
236  * RETURNS
237  *
238  *  Returns true when the local time was calculated.
239  *
240  * BUGS
241  *
242  *  Does not handle daylight savings time adjustments correctly.
243  */
244 BOOL WINAPI SystemTimeToTzSpecificLocalTime(
245     LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The desired time zone. */
246     LPSYSTEMTIME            lpUniversalTime,       /* [in] The utc time to base local time on. */
247     LPSYSTEMTIME            lpLocalTime)           /* [out] The local time in the time zone. */
248 {
249   FIXME(":stub\n");
250   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
251        return FALSE;
252 }
253
254
255 /***********************************************************************
256  *              GetSystemTimeAsFileTime  (KERNEL32.408)
257  *
258  *  Fills in a file time structure with the current time in UTC format.
259  */
260 VOID WINAPI GetSystemTimeAsFileTime(
261     LPFILETIME time) /* [out] The file time struct to be filled with the system time. */
262 {
263     NtQuerySystemTime( (LARGE_INTEGER *)time );
264 }
265
266
267 /*********************************************************************
268  *      TIME_ClockTimeToFileTime    (olorin@fandra.org, 20-Sep-1998)
269  *
270  *  Used by GetProcessTimes to convert clock_t into FILETIME.
271  *
272  *      Differences to UnixTimeToFileTime:
273  *          1) Divided by CLK_TCK
274  *          2) Time is relative. There is no 'starting date', so there is 
275  *             no need in offset correction, like in UnixTimeToFileTime
276  */
277 static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
278 {
279     LONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
280     ((LARGE_INTEGER *)filetime)->QuadPart = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL );
281 }
282
283 /*********************************************************************
284  *      GetProcessTimes                         (KERNEL32.378)
285  *
286  *  Returns the user and kernel execution times of a process,
287  *  along with the creation and exit times if known.
288  *
289  *  olorin@fandra.org:
290  *  Would be nice to subtract the cpu time, used by Wine at startup.
291  *  Also, there is a need to separate times used by different applications.
292  *
293  * RETURNS
294  *
295  *  Always returns true.
296  *
297  * BUGS
298  *
299  *  lpCreationTime, lpExitTime are NOT INITIALIZED.
300  */
301 BOOL WINAPI GetProcessTimes(
302     HANDLE     hprocess,       /* [in] The process to be queried (obtained from PROCESS_QUERY_INFORMATION). */
303     LPFILETIME lpCreationTime, /* [out] The creation time of the process. */
304     LPFILETIME lpExitTime,     /* [out] The exit time of the process if exited. */
305     LPFILETIME lpKernelTime,   /* [out] The time spent in kernal routines in 100's of nanoseconds. */
306     LPFILETIME lpUserTime)     /* [out] The time spent in user routines in 100's of nanoseconds. */
307 {
308     struct tms tms;
309
310     times(&tms);
311     TIME_ClockTimeToFileTime(tms.tms_utime,lpUserTime);
312     TIME_ClockTimeToFileTime(tms.tms_stime,lpKernelTime);
313     return TRUE;
314 }