ddraw/tests: Use compare_uint() in compare_float() instead of abs().
[wine.git] / programs / clock / winclock.c
blobbfa04bd60ebfbbd33da67229a2fafc9e3241ef47
1 /*
2 * Clock (winclock.c)
4 * Copyright 1998 by Marcel Baur <mbaur@g26.ethz.ch>
6 * This file is based on rolex.c by Jim Peterson.
8 * I just managed to move the relevant parts into the Clock application
9 * and made it look like the original Windows one. You can find the original
10 * rolex.c in the wine /libtest directory.
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include <math.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include "windows.h"
31 #include "winclock.h"
33 #define FaceColor (GetSysColor(COLOR_3DFACE))
34 #define HandColor (GetSysColor(COLOR_3DHIGHLIGHT))
35 #define TickColor (GetSysColor(COLOR_3DHIGHLIGHT))
36 #define ShadowColor (GetSysColor(COLOR_3DDKSHADOW))
37 #define BackgroundColor (GetSysColor(COLOR_3DFACE))
39 static const int SHADOW_DEPTH = 2;
41 typedef struct
43 POINT Start;
44 POINT End;
45 } HandData;
47 static HandData HourHand, MinuteHand, SecondHand;
49 static void DrawTicks(HDC dc, const POINT* centre, int radius)
51 int t;
53 /* Minute divisions */
54 if (radius>64)
55 for(t=0; t<60; t++) {
56 MoveToEx(dc,
57 centre->x + sin(t*M_PI/30)*0.9*radius,
58 centre->y - cos(t*M_PI/30)*0.9*radius,
59 NULL);
60 LineTo(dc,
61 centre->x + sin(t*M_PI/30)*0.89*radius,
62 centre->y - cos(t*M_PI/30)*0.89*radius);
65 /* Hour divisions */
66 for(t=0; t<12; t++) {
68 MoveToEx(dc,
69 centre->x + sin(t*M_PI/6)*0.9*radius,
70 centre->y - cos(t*M_PI/6)*0.9*radius,
71 NULL);
72 LineTo(dc,
73 centre->x + sin(t*M_PI/6)*0.8*radius,
74 centre->y - cos(t*M_PI/6)*0.8*radius);
78 static void DrawFace(HDC dc, const POINT* centre, int radius, int border)
80 /* Ticks */
81 SelectObject(dc, CreatePen(PS_SOLID, 2, ShadowColor));
82 OffsetWindowOrgEx(dc, -SHADOW_DEPTH, -SHADOW_DEPTH, NULL);
83 DrawTicks(dc, centre, radius);
84 DeleteObject(SelectObject(dc, CreatePen(PS_SOLID, 2, TickColor)));
85 OffsetWindowOrgEx(dc, SHADOW_DEPTH, SHADOW_DEPTH, NULL);
86 DrawTicks(dc, centre, radius);
87 if (border)
89 SelectObject(dc, GetStockObject(NULL_BRUSH));
90 DeleteObject(SelectObject(dc, CreatePen(PS_SOLID, 5, ShadowColor)));
91 Ellipse(dc, centre->x - radius, centre->y - radius, centre->x + radius, centre->y + radius);
93 DeleteObject(SelectObject(dc, GetStockObject(NULL_PEN)));
96 static void DrawHand(HDC dc,HandData* hand)
98 MoveToEx(dc, hand->Start.x, hand->Start.y, NULL);
99 LineTo(dc, hand->End.x, hand->End.y);
102 static void DrawHands(HDC dc, BOOL bSeconds)
104 if (bSeconds) {
105 #if 0
106 SelectObject(dc, CreatePen(PS_SOLID, 1, ShadowColor));
107 OffsetWindowOrgEx(dc, -SHADOW_DEPTH, -SHADOW_DEPTH, NULL);
108 DrawHand(dc, &SecondHand);
109 DeleteObject(SelectObject(dc, CreatePen(PS_SOLID, 1, HandColor)));
110 OffsetWindowOrgEx(dc, SHADOW_DEPTH, SHADOW_DEPTH, NULL);
111 #else
112 SelectObject(dc, CreatePen(PS_SOLID, 1, HandColor));
113 #endif
114 DrawHand(dc, &SecondHand);
115 DeleteObject(SelectObject(dc, GetStockObject(NULL_PEN)));
118 SelectObject(dc, CreatePen(PS_SOLID, 4, ShadowColor));
120 OffsetWindowOrgEx(dc, -SHADOW_DEPTH, -SHADOW_DEPTH, NULL);
121 DrawHand(dc, &MinuteHand);
122 DrawHand(dc, &HourHand);
124 DeleteObject(SelectObject(dc, CreatePen(PS_SOLID, 4, HandColor)));
125 OffsetWindowOrgEx(dc, SHADOW_DEPTH, SHADOW_DEPTH, NULL);
126 DrawHand(dc, &MinuteHand);
127 DrawHand(dc, &HourHand);
129 DeleteObject(SelectObject(dc, GetStockObject(NULL_PEN)));
132 static void PositionHand(const POINT* centre, double length, double angle, HandData* hand)
134 hand->Start = *centre;
135 hand->End.x = centre->x + sin(angle)*length;
136 hand->End.y = centre->y - cos(angle)*length;
139 static void PositionHands(const POINT* centre, int radius, BOOL bSeconds)
141 SYSTEMTIME st;
142 double hour, minute, second;
144 /* 0 <= hour,minute,second < 2pi */
145 /* Adding the millisecond count makes the second hand move more smoothly */
147 GetLocalTime(&st);
149 second = st.wSecond + st.wMilliseconds/1000.0;
150 minute = st.wMinute + second/60.0;
151 hour = st.wHour % 12 + minute/60.0;
153 PositionHand(centre, radius * 0.5, hour/12 * 2*M_PI, &HourHand);
154 PositionHand(centre, radius * 0.65, minute/60 * 2*M_PI, &MinuteHand);
155 if (bSeconds)
156 PositionHand(centre, radius * 0.79, second/60 * 2*M_PI, &SecondHand);
159 void AnalogClock(HDC dc, int x, int y, BOOL bSeconds, BOOL border)
161 POINT centre;
162 int radius;
164 radius = min(x, y)/2 - SHADOW_DEPTH;
165 if (radius < 0)
166 return;
168 centre.x = x/2;
169 centre.y = y/2;
171 DrawFace(dc, &centre, radius, border);
173 PositionHands(&centre, radius, bSeconds);
174 DrawHands(dc, bSeconds);
178 HFONT SizeFont(HDC dc, int x, int y, BOOL bSeconds, const LOGFONTW* font)
180 SIZE extent;
181 LOGFONTW lf;
182 double xscale, yscale;
183 HFONT oldFont, newFont;
184 WCHAR szTime[255];
185 int chars;
187 chars = GetTimeFormatW(LOCALE_USER_DEFAULT, bSeconds ? 0 : TIME_NOSECONDS, NULL,
188 NULL, szTime, ARRAY_SIZE(szTime));
189 if (!chars)
190 return 0;
192 --chars;
194 lf = *font;
195 lf.lfHeight = -20;
197 x -= 2 * SHADOW_DEPTH;
198 y -= 2 * SHADOW_DEPTH;
200 oldFont = SelectObject(dc, CreateFontIndirectW(&lf));
201 GetTextExtentPointW(dc, szTime, chars, &extent);
202 DeleteObject(SelectObject(dc, oldFont));
204 xscale = (double)x/extent.cx;
205 yscale = (double)y/extent.cy;
206 lf.lfHeight *= min(xscale, yscale);
207 newFont = CreateFontIndirectW(&lf);
209 return newFont;
212 void DigitalClock(HDC dc, int x, int y, BOOL bSeconds, HFONT font)
214 SIZE extent;
215 HFONT oldFont;
216 WCHAR szTime[255];
217 int chars;
219 chars = GetTimeFormatW(LOCALE_USER_DEFAULT, bSeconds ? 0 : TIME_NOSECONDS, NULL,
220 NULL, szTime, ARRAY_SIZE(szTime));
221 if (!chars)
222 return;
223 --chars;
225 oldFont = SelectObject(dc, font);
226 GetTextExtentPointW(dc, szTime, chars, &extent);
228 SetBkColor(dc, BackgroundColor);
229 SetTextColor(dc, ShadowColor);
230 TextOutW(dc, (x - extent.cx)/2 + SHADOW_DEPTH, (y - extent.cy)/2 + SHADOW_DEPTH, szTime, chars);
231 SetBkMode(dc, TRANSPARENT);
233 SetTextColor(dc, HandColor);
234 TextOutW(dc, (x - extent.cx)/2, (y - extent.cy)/2, szTime, chars);
236 SelectObject(dc, oldFont);