vfs: check userland buffers before reading them.
[haiku.git] / src / apps / clock / cl_view.cpp
blob9f56caa35a754721df400374b05b8cd149854bce
1 /*
2 * Copyright 1999, Be Incorporated. All Rights Reserved.
3 * This file may be used under the terms of the Be Sample Code License.
5 */
7 #include "clock.h"
8 #include "cl_view.h"
11 #include <Alert.h>
12 #include <Bitmap.h>
13 #include <Debug.h>
14 #include <Dragger.h>
15 #include <Entry.h>
16 #include <Resources.h>
17 #include <Roster.h>
20 #include <time.h>
23 TOffscreenView::TOffscreenView(BRect frame, const char *name, short mRadius,
24 short hRadius, short offset, long face, bool show)
25 : BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW),
26 fHours(0),
27 fMinutes(0),
28 fSeconds(0),
29 fOffset(offset),
30 fHoursRadius(hRadius),
31 fMinutesRadius(mRadius),
32 fFace(face),
33 fShowSeconds(show),
34 fInner(NULL),
35 fCenter(NULL)
37 for (short i = 0; i <= 8; i++)
38 fClockFace[i] = NULL;
40 status_t error;
41 BResources rsrcs;
42 error = rsrcs.SetToImage(&&dummy_label);
43 dummy_label:
44 if (error == B_OK) {
45 size_t len;
46 void *picH;
47 BRect theRect(0, 0, 82, 82);
48 for (short loop = 0; loop <= 8; loop++) {
49 if ((picH = rsrcs.FindResource('PICT', loop + 4, &len))) {
50 fClockFace[loop] = new BBitmap(theRect, B_CMAP8);
51 fClockFace[loop]->SetBits(picH, len, 0, B_CMAP8);
52 free(picH);
56 theRect.Set(0,0,15,15);
57 if ((picH = rsrcs.FindResource(B_MINI_ICON_TYPE, "center", &len))) {
58 fCenter = new BBitmap(theRect, B_CMAP8);
59 fCenter->SetBits(picH, len, 0, B_CMAP8);
60 free(picH);
63 theRect.Set(0,0,2,2);
64 if ((picH = rsrcs.FindResource('PICT', 13, &len))) {
65 fInner = new BBitmap(theRect, B_CMAP8);
66 fInner->SetBits(picH, len, 0, B_CMAP8);
67 free(picH);
71 float x, y;
72 float counter;
73 short index = 0;
75 // Generate minutes points array
76 for (counter = 90; counter >= 0; counter -= 6, index++) {
77 x = mRadius * cos(((360 - counter)/180.0) * 3.1415);
78 x += 41;
79 y = mRadius * sin(((360 - counter)/180.0) * 3.1415);
80 y += 41;
81 fMinutePoints[index].Set(x,y);
82 x = hRadius * cos(((360 - counter)/180.0) * 3.1415);
83 x += 41;
84 y = hRadius * sin(((360 - counter)/180.0) * 3.1415);
85 y += 41;
86 fHourPoints[index].Set(x,y);
89 for (counter = 354; counter > 90; counter -= 6,index++) {
90 x = mRadius * cos(((360 - counter)/180.0) * 3.1415);
91 x += 41;
92 y = mRadius * sin(((360 - counter)/180.0) * 3.1415);
93 y += 41;
94 fMinutePoints[index].Set(x,y);
95 x = hRadius * cos(((360 - counter)/180.0) * 3.1415);
96 x += 41;
97 y = hRadius * sin(((360 - counter)/180.0) * 3.1415);
98 y += 41;
99 fHourPoints[index].Set(x,y);
104 void
105 TOffscreenView::NextFace()
107 fFace++;
108 if (fFace > 8)
109 fFace = 1;
113 void
114 TOffscreenView::DrawX()
116 ASSERT(Window());
118 if (Window()->Lock()) {
119 if (fClockFace[fFace] != NULL)
120 DrawBitmap(fClockFace[fFace], BPoint(0, 0));
123 // Draw hands
125 SetHighColor(0, 0, 0);
126 int32 hours = fHours;
127 if (hours >= 12)
128 hours -= 12;
129 hours *= 5;
130 hours += (fMinutes / 12);
131 SetDrawingMode(B_OP_OVER);
132 StrokeLine(BPoint(fOffset, fOffset), fHourPoints[hours]);
134 if (fCenter != NULL)
135 DrawBitmap(fCenter, BPoint(fOffset - 3, fOffset - 3));
136 StrokeLine(BPoint(fOffset, fOffset), fMinutePoints[fMinutes]);
137 SetHighColor(180, 180, 180);
138 if (fShowSeconds)
139 StrokeLine(BPoint(fOffset, fOffset), fMinutePoints[fSeconds]);
140 SetDrawingMode(B_OP_COPY);
141 if (fInner != NULL)
142 DrawBitmap(fInner, BPoint(fOffset - 1, fOffset - 1));
143 Sync();
144 Window()->Unlock();
149 TOffscreenView::~TOffscreenView()
151 for (int32 counter = 0; counter <= 8; counter++)
152 delete fClockFace[counter];
156 // #pragma mark -
159 TOnscreenView::TOnscreenView(BRect rect, const char *title, short mRadius,
160 short hRadius, short offset)
161 : BView(rect, title, B_FOLLOW_NONE,
162 B_WILL_DRAW | B_PULSE_NEEDED | B_DRAW_ON_CHILDREN),
163 fOffscreen(NULL),
164 fOffscreenView(NULL)
166 InitObject(rect, mRadius, hRadius, offset, 1, TRUE);
168 rect.OffsetTo(B_ORIGIN);
169 rect.top = rect.bottom - 7;
170 rect.left = rect.right - 7;
171 BDragger *dw = new BDragger(rect, this);
172 AddChild(dw);
176 void
177 TOnscreenView::InitObject(BRect rect, short mRadius, short hRadius,
178 short offset, long face, bool show)
180 fOffscreenView = new TOffscreenView(rect, "freqd", mRadius, hRadius, offset, face, show);
181 fOffscreen = new BBitmap(rect, B_CMAP8, true);
182 if (fOffscreen != NULL && fOffscreen->Lock()) {
183 fOffscreen->AddChild(fOffscreenView);
184 fOffscreen->Unlock();
186 fOffscreenView->DrawX();
191 TOnscreenView::~TOnscreenView()
193 delete fOffscreen;
197 TOnscreenView::TOnscreenView(BMessage *data)
198 : BView(data),
199 fOffscreen(NULL),
200 fOffscreenView(NULL)
202 InitObject(data->FindRect("bounds"), data->FindInt32("mRadius"),
203 data->FindInt32("hRadius"), data->FindInt32("offset"),
204 data->FindInt32("face"), data->FindBool("seconds"));
208 status_t
209 TOnscreenView::Archive(BMessage *data, bool deep) const
211 status_t status = BView::Archive(data, deep);
212 if (status == B_OK)
213 status = data->AddString("add_on", kAppSignature);
215 if (status == B_OK)
216 status = data->AddRect("bounds", Bounds());
218 if (status == B_OK)
219 status = data->AddInt32("mRadius", fOffscreenView->fMinutesRadius);
221 if (status == B_OK)
222 status = data->AddInt32("hRadius", fOffscreenView->fHoursRadius);
224 if (status == B_OK)
225 status = data->AddInt32("offset", fOffscreenView->fOffset);
227 if (status == B_OK)
228 status = data->AddBool("seconds", fOffscreenView->fShowSeconds);
230 if (status == B_OK)
231 status = data->AddInt32("face", fOffscreenView->fFace);
233 return status;
237 BArchivable *
238 TOnscreenView::Instantiate(BMessage *data)
240 if (!validate_instantiation(data, "TOnscreenView"))
241 return NULL;
242 return new TOnscreenView(data);
246 void
247 TOnscreenView::Pulse()
249 ASSERT(fOffscreen);
250 ASSERT(fOffscreenView);
252 time_t current = time(0);
253 struct tm *loctime = localtime(&current);
255 short hours = loctime->tm_hour;
256 short minutes = loctime->tm_min;
257 short seconds = loctime->tm_sec;
259 if ((fOffscreenView->fShowSeconds && (seconds != fOffscreenView->fSeconds))
260 || (minutes != fOffscreenView->fMinutes)) {
261 fOffscreenView->fHours = hours;
262 fOffscreenView->fMinutes = minutes;
263 fOffscreenView->fSeconds = seconds;
264 BRect b = Bounds();
265 b.InsetBy(12,12);
266 Draw(b);
271 void
272 TOnscreenView::UseFace(short face)
274 fOffscreenView->fFace = face;
275 BRect b = Bounds();
276 b.InsetBy(12,12);
277 Draw(b);
281 void
282 TOnscreenView::ShowSecs(bool secs)
284 fOffscreenView->fShowSeconds = secs;
285 BRect b = Bounds();
286 b.InsetBy(12,12);
287 Invalidate(b);
291 short
292 TOnscreenView::ReturnFace()
294 return fOffscreenView->fFace;
298 short
299 TOnscreenView::ReturnSeconds()
301 return fOffscreenView->fShowSeconds;
305 void
306 TOnscreenView::Draw(BRect rect)
308 ASSERT(fOffscreen);
309 ASSERT(fOffscreenView);
311 if (fOffscreen->Lock()) {
312 // Composite the clock offscreen...
313 fOffscreenView->DrawX();
314 DrawBitmap(fOffscreen, rect, rect);
315 fOffscreen->Unlock();
320 void
321 TOnscreenView::MouseDown( BPoint point )
323 BPoint cursor;
324 uint32 buttons;
325 BRect bounds = Bounds();
327 GetMouse(&cursor,&buttons);
328 if (buttons & B_SECONDARY_MOUSE_BUTTON) {
329 fOffscreenView->fShowSeconds = !fOffscreenView->fShowSeconds;
330 bounds.InsetBy(12,12);
331 Invalidate(bounds);
332 } else {
333 fOffscreenView->NextFace();
334 Invalidate(bounds);
335 BView *child = ChildAt(0);
336 if (child)
337 child->Invalidate();
342 void
343 TOnscreenView::MessageReceived(BMessage *msg)
345 switch(msg->what) {
346 case B_ABOUT_REQUESTED:
348 BAlert *alert = new BAlert("About Clock",
349 "Clock (The Replicant version)\n\n(C)2002, 2003 OpenBeOS,\n"
350 "2004 - 2007, Haiku, Inc.\n\nOriginally coded by the folks "
351 "at Be.\n Copyright Be Inc., 1991 - 1998", "OK");
352 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
353 alert->Go();
354 } break;
356 default:
357 BView::MessageReceived(msg);