| /* |
| * Clock (winclock.c) |
| * |
| * Copyright 1998 by Marcel Baur <mbaur@g26.ethz.ch> |
| * |
| * This file is based on rolex.c by Jim Peterson. |
| * |
| * I just managed to move the relevant parts into the Clock application |
| * and made it look like the original Windows one. You can find the original |
| * rolex.c in the wine /libtest directory. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| #include <math.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include "winclock.h" |
| #include "windows.h" |
| #include "main.h" |
| #include "winnls.h" |
| |
| COLORREF FaceColor = RGB(192,192,192); |
| COLORREF HandColor = RGB(0,0,0); |
| COLORREF EtchColor = RGB(0,0,0); |
| |
| float Pi=3.1415926; |
| |
| int nLastSecond = 60; |
| |
| HandData OldSecond,OldHour,OldMinute; |
| |
| int MiddleX(void) { |
| int X, diff; |
| |
| X = (Globals.MaxX/2); |
| diff = (Globals.MaxX-Globals.MaxY); |
| if (diff>0) { X = (X-(diff/2)); } |
| return X; |
| } |
| |
| int MiddleY(void) { |
| int Y, diff; |
| |
| Y = (Globals.MaxY/2); |
| diff = (Globals.MaxX-Globals.MaxY); |
| if (diff<0) { Y = Y+(diff/2); } |
| return Y; |
| } |
| |
| void DrawFace(HDC dc) |
| { |
| int MidX, MidY, t, DiffX, DiffY; |
| |
| MidX = MiddleX(); |
| MidY = MiddleY(); |
| DiffX = (Globals.MaxX-MidX*2)/2; |
| DiffY = (Globals.MaxY-MidY*2)/2; |
| |
| SelectObject(dc,CreateSolidBrush(FaceColor)); |
| SelectObject(dc,CreatePen(PS_SOLID,1,EtchColor)); |
| Ellipse(dc,DiffX,DiffY,2*MidX+DiffX,2*MidY+DiffY); |
| |
| for(t=0; t<12; t++) |
| { |
| MoveToEx(dc,(MidX+DiffX)+sin(t*Pi/6)*0.9*MidX,(MidY+DiffY)-cos(t*Pi/6)*0.9*MidY,NULL); |
| LineTo(dc,(MidY+DiffX)+sin(t*Pi/6)*0.8*MidX,(MidY+DiffY)-cos(t*Pi/6)*0.8*MidY); |
| } |
| if(Globals.MaxX>64 && Globals.MaxY>64) |
| for(t=0; t<60; t++) |
| SetPixel(dc,(MidX+DiffX)+sin(t*Pi/30)*0.9*MidX,(MidY+DiffY)-cos(t*Pi/30)*0.9*MidY |
| ,EtchColor); |
| DeleteObject(SelectObject(dc,GetStockObject(NULL_BRUSH))); |
| DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN))); |
| memset(&OldSecond,0,sizeof(OldSecond)); |
| memset(&OldMinute,0,sizeof(OldMinute)); |
| memset(&OldHour,0,sizeof(OldHour)); |
| } |
| |
| void DrawHourHand(HDC dc) |
| { |
| if (OldHour.DontRedraw) return; |
| MoveToEx(dc, OldHour.StartX, OldHour.StartY, NULL); |
| LineTo(dc, OldHour.EndX, OldHour.EndY); |
| } |
| |
| void DrawMinuteHand(HDC dc) |
| { |
| if (OldMinute.DontRedraw) return; |
| MoveToEx(dc, OldMinute.StartX, OldMinute.StartY, NULL); |
| LineTo(dc, OldMinute.EndX, OldMinute.EndY); |
| } |
| |
| void DrawSecondHand(HDC dc) |
| { |
| if (OldSecond.DontRedraw) return; |
| MoveToEx(dc, OldSecond.StartX, OldSecond.StartY, NULL); |
| LineTo(dc, OldSecond.EndX, OldSecond.EndY); |
| } |
| |
| BOOL UpdateHourHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos) |
| { |
| int Sx, Sy, Ex, Ey; |
| BOOL rv; |
| |
| rv = FALSE; |
| Sx = MidX; Sy = MidY; |
| Ex = MidX+sin(Pos*Pi/6000)*XExt; |
| Ey = MidY-cos(Pos*Pi/6000)*YExt; |
| rv = ( Sx!=OldHour.StartX || Ex!=OldHour.EndX || |
| Sy!=OldHour.StartY || Ey!=OldHour.EndY ); |
| if (Globals.bAnalog && rv)DrawHourHand(dc); |
| OldHour.StartX = Sx; OldHour.EndX = Ex; |
| OldHour.StartY = Sy; OldHour.EndY = Ey; |
| OldHour.DontRedraw=FALSE; |
| return rv; |
| } |
| |
| BOOL UpdateMinuteHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos) |
| { |
| int Sx, Sy, Ex, Ey; |
| BOOL rv; |
| |
| rv = FALSE; |
| Sx = MidX; Sy = MidY; |
| Ex = MidX+sin(Pos*Pi/30000)*XExt; |
| Ey = MidY-cos(Pos*Pi/30000)*YExt; |
| rv = ( Sx!=OldMinute.StartX || Ex!=OldMinute.EndX || |
| Sy!=OldMinute.StartY || Ey!=OldMinute.EndY ); |
| if (Globals.bAnalog && rv)DrawMinuteHand(dc); |
| OldMinute.StartX = Sx; OldMinute.EndX = Ex; |
| OldMinute.StartY = Sy; OldMinute.EndY = Ey; |
| OldMinute.DontRedraw=FALSE; |
| return rv; |
| } |
| |
| BOOL UpdateSecondHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos) |
| { |
| int Sx, Sy, Ex, Ey; |
| BOOL rv; |
| |
| rv = FALSE; |
| |
| if (Globals.bSeconds) { |
| Sx = MidX; Sy = MidY; |
| Ex = MidX+sin(Pos*Pi/3000)*XExt; |
| Ey = MidY-cos(Pos*Pi/3000)*YExt; |
| rv = ( Sx!=OldSecond.StartX || Ex!=OldSecond.EndX || |
| Sy!=OldSecond.StartY || Ey!=OldSecond.EndY ); |
| if (Globals.bAnalog && rv) DrawSecondHand(dc); |
| OldSecond.StartX = Sx; OldSecond.EndX = Ex; |
| OldSecond.StartY = Sy; OldSecond.EndY = Ey; |
| OldSecond.DontRedraw=FALSE; |
| } |
| |
| return rv; |
| } |
| |
| void DigitalClock(HDC dc) { |
| |
| CHAR szTime[MAX_STRING_LEN]; |
| LPSTR time = szTime; |
| static short xChar, yChar; |
| TEXTMETRIC tm; |
| |
| SYSTEMTIME st; |
| LPSYSTEMTIME lpst = &st; |
| |
| GetLocalTime(&st); |
| GetTimeFormat(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, lpst, NULL, time, |
| MAX_STRING_LEN); |
| |
| SelectObject(dc,CreatePen(PS_SOLID,1,FaceColor)); |
| xChar = tm.tmAveCharWidth; |
| yChar = tm.tmHeight; |
| |
| xChar = 100; |
| yChar = 100; |
| TextOut (dc, xChar, yChar, szTime, strlen (szTime)); |
| DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN))); |
| |
| } |
| |
| |
| |
| void AnalogClock(HDC dc) { |
| |
| SYSTEMTIME st; |
| WORD H, M, S, F; |
| int MidX, MidY, DiffX, DiffY; |
| BOOL Redraw; |
| |
| GetLocalTime(&st); |
| |
| S = st.wSecond; |
| if (nLastSecond==S) { exit; } |
| nLastSecond = S; |
| H = st.wHour; |
| M = st.wMinute; |
| F = st.wMilliseconds / 10; |
| F = F + S*100; |
| M = M*1000+F/6; |
| H = H*1000+M/60; |
| MidX = MiddleX(); |
| MidY = MiddleY(); |
| DiffX = (Globals.MaxX-MidX*2)/2; |
| DiffY = (Globals.MaxY-MidY*2)/2; |
| |
| SelectObject(dc,CreatePen(PS_SOLID,1,FaceColor)); |
| Redraw = FALSE; |
| if(UpdateHourHand(dc,MidX+DiffX,MidY+DiffY,MidX*0.5,MidY*0.5,H)) Redraw = TRUE; |
| if(UpdateMinuteHand(dc,MidX+DiffX,MidY+DiffY,MidX*0.65,MidY*0.65,M)) Redraw = TRUE; |
| if(UpdateSecondHand(dc,MidX+DiffX,MidY+DiffY,MidX*0.79,MidY*0.79,F)) Redraw = TRUE; |
| |
| DeleteObject(SelectObject(dc,CreatePen(PS_SOLID,1,HandColor))); |
| if(Redraw) |
| { |
| DrawSecondHand(dc); |
| DrawMinuteHand(dc); |
| DrawHourHand(dc); |
| } |
| DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN))); |
| |
| } |
| |
| void Idle(HDC idc) |
| { |
| HDC context; |
| |
| if(idc) |
| context=idc; |
| else |
| context=GetDC(Globals.hMainWnd); |
| |
| if (!context) return; |
| |
| if (Globals.bAnalog) |
| { |
| AnalogClock(context); |
| } |
| else |
| { |
| DigitalClock(context); |
| } |
| if(!idc) ReleaseDC(Globals.hMainWnd, context); |
| } |