Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / classes / zune / clock / clock.c
blobf0e43a95d2721f1e1bba4931138598053d6e711f
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/types.h>
9 #include <utility/date.h>
11 #include <aros/debug.h>
12 #include <aros/asmcall.h>
14 #include <proto/muimaster.h>
15 #include <proto/graphics.h>
16 #include <proto/intuition.h>
17 #include <proto/utility.h>
18 #include <proto/timer.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <math.h>
24 #include "clock.h"
25 #include "clock_private.h"
27 #define SHADOW_OFFX 4
28 #define SHADOW_OFFY 4
31 /*** Methods ****************************************************************/
32 IPTR Clock__OM_NEW(Class *cl, Object *obj, struct opSet *msg)
34 struct Clock_DATA *data;
35 struct TagItem *ti;
37 obj = (Object *) DoSuperNewTags
39 cl, obj, NULL,
41 MUIA_InnerLeft, 4,
42 MUIA_InnerTop, 4,
43 MUIA_InnerRight, 4,
44 MUIA_InnerBottom, 4,
46 TAG_MORE, (IPTR) msg->ops_AttrList
49 if (!obj) return 0;
51 data = INST_DATA(cl, obj);
52 data->frozen = GetTagData(MUIA_Clock_Frozen, FALSE, msg->ops_AttrList) ? TRUE : FALSE;
53 data->edithand = (WORD)GetTagData(MUIA_Clock_EditHand, (IPTR)-1, msg->ops_AttrList);
54 data->editpen = -1;
56 if ((ti = FindTagItem(MUIA_Clock_Time, msg->ops_AttrList)))
58 struct ClockData *cd = (struct ClockData *)ti->ti_Data;
60 data->clockdata = *cd;
62 else
64 struct timeval tv;
66 GetSysTime(&tv);
67 Amiga2Date(tv.tv_secs, &data->clockdata);
70 data->ihn.ihn_Flags = MUIIHNF_TIMER;
71 data->ihn.ihn_Method = MUIM_Clock_Timer;
72 data->ihn.ihn_Object = obj;
73 data->ihn.ihn_Millis = 1000;
75 return (IPTR)obj;
79 IPTR Clock__OM_DISPOSE(Class *cl, Object *obj, Msg msg)
81 return DoSuperMethodA(cl, obj, msg);
85 IPTR Clock__OM_SET(Class *cl, Object *obj, struct opSet *msg)
87 struct Clock_DATA *data = INST_DATA(cl, obj);
88 struct ClockData old_clockdata;
89 const struct TagItem *tags = msg->ops_AttrList;
90 struct TagItem *tag;
91 BOOL redraw = FALSE;
93 old_clockdata = data->clockdata;
95 while ((tag = NextTagItem(&tags)) != NULL)
97 switch(tag->ti_Tag)
99 case MUIA_Clock_Time:
100 data->clockdata = *(struct ClockData *)tag->ti_Data;
101 redraw = TRUE;
102 break;
104 case MUIA_Clock_Hour:
105 data->clockdata.hour = tag->ti_Data;
106 redraw = TRUE;
107 break;
109 case MUIA_Clock_Min:
110 data->clockdata.min = tag->ti_Data;
111 redraw = TRUE;
112 break;
114 case MUIA_Clock_Sec:
115 data->clockdata.sec = tag->ti_Data;
116 redraw = TRUE;
117 break;
119 case MUIA_Clock_Frozen:
120 data->frozen = tag->ti_Data ? TRUE : FALSE;
121 break;
123 case MUIA_Clock_EditHand:
124 data->edithand = tag->ti_Data;
125 redraw = TRUE;
126 break;
128 } /* switch(tag->ti_Tag) */
130 } /* while ((tag = NextTagItem(&tags)) != NULL) */
132 if (redraw)
134 MUI_Redraw(obj, MADF_DRAWUPDATE);
137 return DoSuperMethodA(cl, obj, (Msg)msg);
141 IPTR Clock__OM_GET(Class *cl, Object *obj, struct opGet *msg)
143 struct Clock_DATA *data = INST_DATA(cl, obj);
144 IPTR retval = TRUE;
146 switch(msg->opg_AttrID)
148 case MUIA_Clock_Time:
149 *(struct ClockData **)msg->opg_Storage = &data->clockdata;
150 break;
152 case MUIA_Clock_Hour:
153 *msg->opg_Storage = data->clockdata.hour;
154 break;
156 case MUIA_Clock_Min:
157 *msg->opg_Storage = data->clockdata.min;
158 break;
160 case MUIA_Clock_Sec:
161 *msg->opg_Storage = data->clockdata.sec;
162 break;
164 case MUIA_Clock_Frozen:
165 *msg->opg_Storage = data->frozen;
166 break;
168 case MUIA_Clock_EditHand:
169 *msg->opg_Storage = data->edithand;
170 break;
172 default:
173 retval = DoSuperMethodA(cl, obj, (Msg)msg);
174 break;
177 return retval;
181 IPTR Clock__MUIM_Setup(Class *cl, Object *obj, struct MUIP_Setup *msg)
183 struct Clock_DATA *data = INST_DATA(cl, obj);
185 if (!DoSuperMethodA(cl, obj, (Msg)msg)) return FALSE;
187 DoMethod(_app(obj), MUIM_Application_AddInputHandler, (IPTR) &data->ihn);
189 data->editpen = ObtainBestPen(_screen(obj)->ViewPort.ColorMap,
190 0xFFFFFFFF,
191 0xD8D8D8D8,
192 0x00000000,
193 OBP_Precision, PRECISION_GUI,
194 OBP_FailIfBad, FALSE,
195 TAG_DONE);
196 return TRUE;
200 IPTR Clock__MUIM_Cleanup(Class *cl, Object *obj, struct MUIP_Cleanup *msg)
202 struct Clock_DATA *data = INST_DATA(cl, obj);
204 if (data->editpen != -1)
206 ReleasePen(_screen(obj)->ViewPort.ColorMap, data->editpen);
207 data->editpen = -1;
210 if (data->clockbm)
212 DeinitRastPort(&data->clockrp);
213 FreeBitMap(data->clockbm);
214 FreeRaster(data->clockraster, data->clockbmw, data->clockbmh);
215 data->clockbm = NULL;
216 data->clockraster = NULL;
218 DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR) &data->ihn);
220 return DoSuperMethodA(cl, obj, (Msg)msg);
224 IPTR Clock__MUIM_AskMinMax(Class *cl, Object *obj, struct MUIP_AskMinMax *msg)
226 DoSuperMethodA(cl, obj, (Msg)msg);
228 msg->MinMaxInfo->MinWidth += 31;
229 msg->MinMaxInfo->MinHeight += 31;
230 msg->MinMaxInfo->DefWidth += 31;
231 msg->MinMaxInfo->DefHeight += 31;
232 msg->MinMaxInfo->MaxWidth = MUI_MAXMAX;
233 msg->MinMaxInfo->MaxHeight = MUI_MAXMAX;
235 return TRUE;
239 #define MY_PI 3.14159265358979323846
241 static void DrawHand
243 struct RastPort *rp, WORD cx, WORD cy, DOUBLE angle,
244 WORD radius1, WORD radius2
247 WORD x, y;
249 x = cx + (WORD)(cos(angle + MY_PI) * radius1);
250 y = cy - (WORD)(sin(angle + MY_PI) * radius1);
252 AreaMove(rp, x, y);
254 x = cx + (WORD)(cos(angle + MY_PI / 2.0) * radius1);
255 y = cy - (WORD)(sin(angle + MY_PI / 2.0) * radius1);
257 AreaDraw(rp, x, y);
259 x = cx + (WORD)(cos(angle) * radius2);
260 y = cy - (WORD)(sin(angle) * radius2);
262 AreaDraw(rp, x, y);
264 x = cx + (WORD)(cos(angle - MY_PI / 2.0) * radius1);
265 y = cy - (WORD)(sin(angle - MY_PI / 2.0) * radius1);
267 AreaDraw(rp, x, y);
269 x = cx + (WORD)(cos(angle + MY_PI) * radius1);
270 y = cy - (WORD)(sin(angle + MY_PI) * radius1);
272 AreaDraw(rp, x, y);
274 AreaEnd(rp);
278 static void DrawThinHand(struct RastPort *rp, WORD cx, WORD cy, DOUBLE angle, WORD radius)
280 WORD x, y;
282 Move(rp, cx, cy);
284 x = cx + (WORD)(cos(angle) * radius);
285 y = cy - (WORD)(sin(angle) * radius);
287 Draw(rp, x, y);
290 IPTR Clock__MUIM_Draw(Class *cl, Object *obj, struct MUIP_Draw *msg)
292 struct Clock_DATA *data = INST_DATA(cl, obj);
293 struct RastPort *obj_rp;
294 struct Region *region;
295 struct Rectangle rect;
296 APTR clip = NULL;
297 WORD r, x, y, x2, y2, i, cx, cy, c;
298 WORD new_clockbmw, new_clockbmh;
299 WORD clock_posx, clock_posy;
300 DOUBLE angle;
302 r = (_mwidth(obj) - SHADOW_OFFX) / 2;
303 y = (_mheight(obj) - SHADOW_OFFY) / 2;
305 r = (r < y) ? r : y;
307 new_clockbmw = r * 2 + 1 + SHADOW_OFFX;
308 new_clockbmh = r * 2 + 1 + SHADOW_OFFY;
310 clock_posx = _mleft(obj) + (_mwidth(obj) - new_clockbmw) / 2;
311 clock_posy = _mtop(obj) + (_mheight(obj) - new_clockbmh) / 2;
313 region = NewRegion();
314 if (region)
316 rect.MinX = _left(obj);
317 rect.MinY = _top(obj);
318 rect.MaxX = _right(obj);
319 rect.MaxY = _bottom(obj);
321 OrRectRegion(region, &rect);
323 rect.MinX = clock_posx;
324 rect.MinY = clock_posy;
325 rect.MaxX = clock_posx + new_clockbmw - 1;
326 rect.MaxY = clock_posy + new_clockbmh - 1;
328 ClearRectRegion(region, &rect);
330 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
333 DoSuperMethodA(cl, obj, (Msg)msg);
335 if (region)
337 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
340 if (!(msg->flags & (MADF_DRAWOBJECT | MADF_DRAWUPDATE))) return 0;
342 if (!data->clockbm || (data->clockbmr != r))
344 if (data->clockbm)
346 DeinitRastPort(&data->clockrp);
347 FreeBitMap(data->clockbm);
348 FreeRaster(data->clockraster, data->clockbmw, data->clockbmh);
349 data->clockraster = NULL;
352 data->clockbmw = new_clockbmw;
353 data->clockbmh = new_clockbmh;
355 data->clockbm = AllocBitMap(data->clockbmw,
356 data->clockbmh,
357 GetBitMapAttr(_rp(obj)->BitMap, BMA_DEPTH),
358 BMF_MINPLANES,
359 _rp(obj)->BitMap);
361 if (!data->clockbm) return 0;
363 data->clockraster = AllocRaster(data->clockbmw, data->clockbmh);
364 if (!data->clockraster)
366 FreeBitMap(data->clockbm);
367 data->clockbm = 0;
368 return 0;
371 InitRastPort(&data->clockrp);
372 data->clockrp.BitMap = data->clockbm;
374 InitArea(&data->clockai, data->areabuf, sizeof(data->areabuf) / 5);
375 data->clockrp.AreaInfo = &data->clockai;
377 InitTmpRas(&data->clocktr, data->clockraster, RASSIZE(data->clockbmw, data->clockbmh));
378 data->clockrp.TmpRas = &data->clocktr;
380 data->clockbmr = r;
383 obj_rp = _rp(obj);
384 _rp(obj) = &data->clockrp;
386 DoMethod(obj, MUIM_DrawBackground, 0, 0, data->clockbmw , data->clockbmh, clock_posx, clock_posy, 0);
388 cx = r + SHADOW_OFFX;
389 cy = r + SHADOW_OFFY;
391 SetDrMd(_rp(obj), JAM1);
392 SetAPen(_rp(obj), _pens(obj)[MPEN_HALFSHADOW]);
394 for(c = 0; c < 2; c++)
396 for(angle = 0.0, i = 0; angle < 2.0 * MY_PI; angle += 2 * MY_PI / 60.0, i++)
398 x = cx + (WORD)(cos(angle) * r);
399 y = cy - (WORD)(sin(angle) * r);
401 if ((i % 5) == 0)
403 x2 = cx + (WORD)(cos(angle) * (r * 90 / 100));
404 y2 = cy - (WORD)(sin(angle) * (r * 90 / 100));
405 Move(_rp(obj), x, y); Draw(_rp(obj), x2, y2);
407 else
409 WritePixel(_rp(obj), x, y);
413 cx -= SHADOW_OFFX;
414 cy -= SHADOW_OFFY;
415 SetAPen(_rp(obj), _dri(obj)->dri_Pens[SHADOWPEN]);
418 cx += SHADOW_OFFX * 2;
419 cy += SHADOW_OFFY * 2;
421 SetAPen(_rp(obj), _pens(obj)[MPEN_HALFSHADOW]);
423 for(c = 0; c < 2; c++)
425 DOUBLE angle, h;
427 h = data->clockdata.hour + (data->clockdata.min / 60.0);
428 if (h > 12.0) h -= 12.0;
430 angle = MY_PI / 2.0 + MY_PI * 2.0 * (12.0 - h) / 12.0;
432 if (c == 1)
434 if ((data->edithand == MUIV_Clock_EditHand_Hour) && data->frozen)
436 SetAPen(_rp(obj), (data->editpen == -1) ? _dri(obj)->dri_Pens[SHINEPEN] : data->editpen);
438 else
440 SetAPen(_rp(obj), _dri(obj)->dri_Pens[SHADOWPEN]);
444 DrawHand(_rp(obj),
447 angle,
448 r * 6 / 100,
449 r * 60 / 100);
451 angle = MY_PI / 2.0 + MY_PI * 2.0 * ((double)60 - data->clockdata.min) / 60.0;
453 if (c == 1)
455 if ((data->edithand == MUIV_Clock_EditHand_Minute) && data->frozen)
457 SetAPen(_rp(obj), (data->editpen == -1) ? _dri(obj)->dri_Pens[SHINEPEN] : data->editpen);
459 else
461 SetAPen(_rp(obj), _dri(obj)->dri_Pens[SHADOWPEN]);
465 DrawHand(_rp(obj),
468 angle,
469 r * 4 / 100,
470 r * 85 / 100);
472 angle = MY_PI / 2.0 + MY_PI * 2.0 * ((double)60 - data->clockdata.sec) / 60.0;
474 if (c == 1)
476 if ((data->edithand == MUIV_Clock_EditHand_Second) && data->frozen)
478 SetAPen(_rp(obj), (data->editpen == -1) ? _dri(obj)->dri_Pens[SHINEPEN] : data->editpen);
480 else
482 SetAPen(_rp(obj), _dri(obj)->dri_Pens[SHADOWPEN]);
486 DrawThinHand(_rp(obj), cx, cy, angle, r * 85 / 100);
488 cx -= SHADOW_OFFX;
489 cy -= SHADOW_OFFY;
493 _rp(obj) = obj_rp;
495 BltBitMapRastPort(data->clockbm,
498 _rp(obj),
499 clock_posx,
500 clock_posy,
501 data->clockbmw,
502 data->clockbmh, 192);
504 return 0;
508 IPTR Clock__MUIM_Clock_Timer(Class *cl, Object *obj, Msg msg)
510 struct Clock_DATA *data;
511 struct ClockData cd;
512 struct timeval tv;
514 data = INST_DATA(cl, obj);
516 if (!data->frozen)
518 GetSysTime(&tv);
519 Amiga2Date(tv.tv_secs, &cd);
521 set(obj, MUIA_Clock_Time, &cd);
522 set(obj, MUIA_Clock_Ticked, TRUE);
525 return 0;