Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/programs/clock/winclock.c
4389 views
1
/*
2
* Clock (winclock.c)
3
*
4
* Copyright 1998 by Marcel Baur <[email protected]>
5
*
6
* This file is based on rolex.c by Jim Peterson.
7
*
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.
11
*
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.
16
*
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.
21
*
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
25
*/
26
27
#include <math.h>
28
#include <stdlib.h>
29
#include <string.h>
30
#include "windows.h"
31
#include "winclock.h"
32
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))
38
39
static const int SHADOW_DEPTH = 2;
40
41
typedef struct
42
{
43
POINT Start;
44
POINT End;
45
} HandData;
46
47
static HandData HourHand, MinuteHand, SecondHand;
48
49
static void DrawTicks(HDC dc, const POINT* centre, int radius)
50
{
51
int t;
52
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);
63
}
64
65
/* Hour divisions */
66
for(t=0; t<12; t++) {
67
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);
75
}
76
}
77
78
static void DrawFace(HDC dc, const POINT* centre, int radius, int border)
79
{
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)
88
{
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);
92
}
93
DeleteObject(SelectObject(dc, GetStockObject(NULL_PEN)));
94
}
95
96
static void DrawHand(HDC dc,HandData* hand)
97
{
98
MoveToEx(dc, hand->Start.x, hand->Start.y, NULL);
99
LineTo(dc, hand->End.x, hand->End.y);
100
}
101
102
static void DrawHands(HDC dc, BOOL bSeconds)
103
{
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)));
116
}
117
118
SelectObject(dc, CreatePen(PS_SOLID, 4, ShadowColor));
119
120
OffsetWindowOrgEx(dc, -SHADOW_DEPTH, -SHADOW_DEPTH, NULL);
121
DrawHand(dc, &MinuteHand);
122
DrawHand(dc, &HourHand);
123
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);
128
129
DeleteObject(SelectObject(dc, GetStockObject(NULL_PEN)));
130
}
131
132
static void PositionHand(const POINT* centre, double length, double angle, HandData* hand)
133
{
134
hand->Start = *centre;
135
hand->End.x = centre->x + sin(angle)*length;
136
hand->End.y = centre->y - cos(angle)*length;
137
}
138
139
static void PositionHands(const POINT* centre, int radius, BOOL bSeconds)
140
{
141
SYSTEMTIME st;
142
double hour, minute, second;
143
144
/* 0 <= hour,minute,second < 2pi */
145
/* Adding the millisecond count makes the second hand move more smoothly */
146
147
GetLocalTime(&st);
148
149
second = st.wSecond + st.wMilliseconds/1000.0;
150
minute = st.wMinute + second/60.0;
151
hour = st.wHour % 12 + minute/60.0;
152
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);
157
}
158
159
void AnalogClock(HDC dc, int x, int y, BOOL bSeconds, BOOL border)
160
{
161
POINT centre;
162
int radius;
163
164
radius = min(x, y)/2 - SHADOW_DEPTH;
165
if (radius < 0)
166
return;
167
168
centre.x = x/2;
169
centre.y = y/2;
170
171
DrawFace(dc, &centre, radius, border);
172
173
PositionHands(&centre, radius, bSeconds);
174
DrawHands(dc, bSeconds);
175
}
176
177
178
HFONT SizeFont(HDC dc, int x, int y, BOOL bSeconds, const LOGFONTW* font)
179
{
180
SIZE extent;
181
LOGFONTW lf;
182
double xscale, yscale;
183
HFONT oldFont, newFont;
184
WCHAR szTime[255];
185
int chars;
186
187
chars = GetTimeFormatW(LOCALE_USER_DEFAULT, bSeconds ? 0 : TIME_NOSECONDS, NULL,
188
NULL, szTime, ARRAY_SIZE(szTime));
189
if (!chars)
190
return 0;
191
192
--chars;
193
194
lf = *font;
195
lf.lfHeight = -20;
196
197
x -= 2 * SHADOW_DEPTH;
198
y -= 2 * SHADOW_DEPTH;
199
200
oldFont = SelectObject(dc, CreateFontIndirectW(&lf));
201
GetTextExtentPointW(dc, szTime, chars, &extent);
202
DeleteObject(SelectObject(dc, oldFont));
203
204
xscale = (double)x/extent.cx;
205
yscale = (double)y/extent.cy;
206
lf.lfHeight *= min(xscale, yscale);
207
newFont = CreateFontIndirectW(&lf);
208
209
return newFont;
210
}
211
212
void DigitalClock(HDC dc, int x, int y, BOOL bSeconds, HFONT font)
213
{
214
SIZE extent;
215
HFONT oldFont;
216
WCHAR szTime[255];
217
int chars;
218
219
chars = GetTimeFormatW(LOCALE_USER_DEFAULT, bSeconds ? 0 : TIME_NOSECONDS, NULL,
220
NULL, szTime, ARRAY_SIZE(szTime));
221
if (!chars)
222
return;
223
--chars;
224
225
oldFont = SelectObject(dc, font);
226
GetTextExtentPointW(dc, szTime, chars, &extent);
227
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);
232
233
SetTextColor(dc, HandColor);
234
TextOutW(dc, (x - extent.cx)/2, (y - extent.cy)/2, szTime, chars);
235
236
SelectObject(dc, oldFont);
237
}
238
239