- New implementation of SendMessage, ReceiveMessage, ReplyMessage functions
[wine] / programs / clock / winclock.c
1 /* 
2  *  Clock (winclock.c)
3  *
4  *  Copyright 1998 by Marcel Baur <mbaur@g26.ethz.ch>
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  *  Original file header:
13  *  >
14  *  > rolex.c: Windows clock application for WINE (by Jim Peterson)    
15  *  >                                                                 
16  *  > This is a translation of a Turbo Pascal OWL application I made   
17  *  > once, so it's a little flaky (tons of globals, functions that    
18  *  > could have been in-lined, etc.).  The source code should easily  
19  *  > compile with a standard Win32 C compiler.                        
20  *  >                                                                 
21  *  > To try it out, type 'make rolex'.                               
22  *  >
23  *
24  */
25
26 #include <math.h>
27 #include <string.h>
28 #include "winclock.h"
29 #include "windows.h"
30 #include "main.h"
31 #include "winnls.h"
32
33 COLORREF FaceColor = RGB(192,192,192);
34 COLORREF HandColor = RGB(0,0,0);
35 COLORREF EtchColor = RGB(0,0,0);
36
37 float Pi=3.1415926;
38
39 int nLastSecond = 60;
40
41 HandData OldSecond,OldHour,OldMinute;
42
43 int MiddleX(void) {
44   int X, diff;
45
46   X    = (Globals.MaxX/2);  
47   diff = (Globals.MaxX-Globals.MaxY);
48   if (diff>0) { X = (X-(diff/2)); }
49   return X;
50 }
51
52 int MiddleY(void) {
53   int Y, diff;
54   
55   Y    = (Globals.MaxY/2);
56   diff = (Globals.MaxX-Globals.MaxY);
57   if (diff<0) { Y = Y+(diff/2); }
58   return Y;
59 }
60
61 void DrawFace(HDC dc)
62 {
63   int MidX, MidY, t, DiffX, DiffY;
64   
65   MidX = MiddleX();
66   MidY = MiddleY();
67   DiffX = (Globals.MaxX-MidX*2)/2;
68   DiffY = (Globals.MaxY-MidY*2)/2;
69
70   SelectObject(dc,CreateSolidBrush(FaceColor));
71   SelectObject(dc,CreatePen(PS_SOLID,1,EtchColor));
72   Ellipse(dc,DiffX,DiffY,2*MidX+DiffX,2*MidY+DiffY);
73
74   for(t=0; t<12; t++)
75   {
76     MoveToEx(dc,(MidX+DiffX)+sin(t*Pi/6)*0.9*MidX,(MidY+DiffY)-cos(t*Pi/6)*0.9*MidY,NULL);
77     LineTo(dc,(MidY+DiffX)+sin(t*Pi/6)*0.8*MidX,(MidY+DiffY)-cos(t*Pi/6)*0.8*MidY);
78   }
79   if(Globals.MaxX>64 && Globals.MaxY>64)
80     for(t=0; t<60; t++)
81       SetPixel(dc,(MidX+DiffX)+sin(t*Pi/30)*0.9*MidX,(MidY+DiffY)-cos(t*Pi/30)*0.9*MidY
82                ,EtchColor);
83   DeleteObject(SelectObject(dc,GetStockObject(NULL_BRUSH)));
84   DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN)));
85   memset(&OldSecond,0,sizeof(OldSecond));
86   memset(&OldMinute,0,sizeof(OldMinute));
87   memset(&OldHour,0,sizeof(OldHour));
88 }
89
90 void DrawHourHand(HDC dc)
91 {
92   if (OldHour.DontRedraw) return;
93   MoveToEx(dc, OldHour.StartX, OldHour.StartY, NULL);
94   LineTo(dc, OldHour.EndX, OldHour.EndY);
95 }
96
97 void DrawMinuteHand(HDC dc)
98 {
99   if (OldMinute.DontRedraw) return;
100   MoveToEx(dc, OldMinute.StartX, OldMinute.StartY, NULL);
101   LineTo(dc, OldMinute.EndX, OldMinute.EndY);
102 }
103
104 void DrawSecondHand(HDC dc)
105 {
106     if (OldSecond.DontRedraw) return;
107     MoveToEx(dc, OldSecond.StartX, OldSecond.StartY, NULL);
108     LineTo(dc, OldSecond.EndX, OldSecond.EndY);
109 }
110
111 BOOL UpdateHourHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos)
112 {
113   int Sx, Sy, Ex, Ey;
114   BOOL rv;
115
116   rv = FALSE;
117   Sx = MidX; Sy = MidY;
118   Ex = MidX+sin(Pos*Pi/6000)*XExt;
119   Ey = MidY-cos(Pos*Pi/6000)*YExt;
120   rv = ( Sx!=OldHour.StartX || Ex!=OldHour.EndX || 
121          Sy!=OldHour.StartY || Ey!=OldHour.EndY );
122   if (Globals.bAnalog && rv)DrawHourHand(dc);
123   OldHour.StartX = Sx; OldHour.EndX = Ex;
124   OldHour.StartY = Sy; OldHour.EndY = Ey;
125   OldHour.DontRedraw=FALSE;
126   return rv;
127 }
128
129 BOOL UpdateMinuteHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos)
130 {
131   int Sx, Sy, Ex, Ey;
132   BOOL rv;
133
134   rv = FALSE;
135   Sx = MidX; Sy = MidY;
136   Ex = MidX+sin(Pos*Pi/30000)*XExt;
137   Ey = MidY-cos(Pos*Pi/30000)*YExt;
138   rv = ( Sx!=OldMinute.StartX || Ex!=OldMinute.EndX ||
139          Sy!=OldMinute.StartY || Ey!=OldMinute.EndY );
140   if (Globals.bAnalog && rv)DrawMinuteHand(dc);
141   OldMinute.StartX = Sx; OldMinute.EndX = Ex;
142   OldMinute.StartY = Sy; OldMinute.EndY = Ey;
143   OldMinute.DontRedraw=FALSE;
144   return rv;
145 }
146
147 BOOL UpdateSecondHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos)
148 {
149   int Sx, Sy, Ex, Ey;
150   BOOL rv;
151
152   rv = FALSE;
153   
154   if (Globals.bSeconds) {
155     Sx = MidX; Sy = MidY;
156     Ex = MidX+sin(Pos*Pi/3000)*XExt;
157     Ey = MidY-cos(Pos*Pi/3000)*YExt;
158     rv = ( Sx!=OldSecond.StartX || Ex!=OldSecond.EndX ||
159            Sy!=OldSecond.StartY || Ey!=OldSecond.EndY );
160     if (Globals.bAnalog && rv) DrawSecondHand(dc);
161     OldSecond.StartX = Sx; OldSecond.EndX = Ex;
162     OldSecond.StartY = Sy; OldSecond.EndY = Ey;
163     OldSecond.DontRedraw=FALSE;
164   }
165   
166   return rv;
167 }
168
169 void DigitalClock(HDC dc) {
170
171   CHAR szTime[MAX_STRING_LEN];
172   LPSTR time = szTime;
173   static short xChar, yChar;
174   TEXTMETRIC tm;
175   
176   SYSTEMTIME st;
177   LPSYSTEMTIME lpst = &st;
178   
179   GetLocalTime(&st);
180   GetTimeFormat(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, lpst, NULL, time, 
181                 MAX_STRING_LEN);
182                 
183   SelectObject(dc,CreatePen(PS_SOLID,1,FaceColor));
184   xChar = tm.tmAveCharWidth;
185   yChar = tm.tmHeight;
186   
187   xChar = 100;
188   yChar = 100;
189   TextOut (dc, xChar, yChar, szTime, strlen (szTime)); 
190   DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN)));
191               
192 }
193
194
195
196 void AnalogClock(HDC dc) {
197
198   SYSTEMTIME st;
199   WORD H, M, S, F;
200   int MidX, MidY, DiffX, DiffY;
201   BOOL Redraw;
202
203   GetLocalTime(&st);
204
205   S = st.wSecond;
206   if (nLastSecond==S) { exit; }
207   nLastSecond = S;
208   H = st.wHour;
209   M = st.wMinute;
210   F = st.wMilliseconds / 10;
211   F = F + S*100;
212   M = M*1000+F/6;
213   H = H*1000+M/60;
214   MidX = MiddleX();
215   MidY = MiddleY();
216   DiffX = (Globals.MaxX-MidX*2)/2;
217   DiffY = (Globals.MaxY-MidY*2)/2;
218
219   SelectObject(dc,CreatePen(PS_SOLID,1,FaceColor));
220   Redraw = FALSE;
221   if(UpdateHourHand(dc,MidX+DiffX,MidY+DiffY,MidX*0.5,MidY*0.5,H)) Redraw = TRUE;
222   if(UpdateMinuteHand(dc,MidX+DiffX,MidY+DiffY,MidX*0.65,MidY*0.65,M)) Redraw = TRUE;
223   if(UpdateSecondHand(dc,MidX+DiffX,MidY+DiffY,MidX*0.79,MidY*0.79,F)) Redraw = TRUE;
224
225   DeleteObject(SelectObject(dc,CreatePen(PS_SOLID,1,HandColor)));
226     if(Redraw)
227       {
228         DrawSecondHand(dc);
229         DrawMinuteHand(dc);
230         DrawHourHand(dc);
231       }
232   DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN))); 
233   
234 }
235
236 void Idle(HDC idc)
237 {
238   HDC context;
239
240   if(idc)
241         context=idc;
242   else
243         context=GetDC(Globals.hMainWnd);
244
245   if (!context) return;
246
247   if (Globals.bAnalog)
248   {
249     AnalogClock(context);
250   }
251   else 
252   {
253     DigitalClock(context);
254   }
255   if(!idc) ReleaseDC(Globals.hMainWnd, context);
256 }