Bug Summary

File:src/add-ons/screen_savers/spider/SpiderSaver.cpp
Location:line 296, column 20
Description:Called C++ object pointer is null

Annotated Source Code

1/*
2 * Copyright 2007-2009, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Stephan Aßmus <superstippi@gmx.de>
7 */
8#include "SpiderSaver.h"
9
10#include <math.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include <Bitmap.h>
16#include <Catalog.h>
17#include <Message.h>
18#include <Menu.h>
19#include <MenuField.h>
20#include <MenuItem.h>
21#include <Slider.h>
22#include <StringView.h>
23
24#include "Polygon.h"
25#include "PolygonQueue.h"
26
27#undef B_TRANSLATION_CONTEXT"Screensaver Spider"
28#define B_TRANSLATION_CONTEXT"Screensaver Spider" "Screensaver Spider"
29
30enum {
31 MSG_QUEUE_NUMBER = 'qunm',
32 MSG_POLY_NUMBER = 'plnm',
33 MSG_QUEUE_DEPTH = 'qudp',
34 MSG_COLOR = 'colr',
35};
36
37#define MIN_POLY_POINTS3 3
38#define MAX_POLY_POINTS10 10
39#define MIN_QUEUE_DEPTH40 40
40#define MAX_QUEUE_DEPTH160 160
41#define MAX_QUEUE_NUMBER40 40
42
43enum {
44 RED = 1,
45 GREEN = 2,
46 BLUE = 3,
47 YELLOW = 4,
48 PURPLE = 5,
49 CYAN = 6,
50 GRAY = 7,
51};
52
53// MAIN INSTANTIATION FUNCTION
54extern "C" _EXPORT BScreenSaver*
55instantiate_screen_saver(BMessage *message, image_id image)
56{
57 return new SpiderSaver(message, image);
58}
59
60// constructor
61SpiderSaver::SpiderSaver(BMessage *message, image_id id)
62 : BScreenSaver(message, id),
63 fBackBitmap(NULL__null),
64 fBackView(NULL__null),
65 fQueues(new PolygonQueue*[MAX_QUEUE_NUMBER40]),
66 fQueueNumber(20),
67 fMaxPolyPoints(MAX_POLY_POINTS10),
68 fMaxQueueDepth(MAX_QUEUE_DEPTH160),
69 fColor(RED)
70{
71 for (int32 i = 0; i < MAX_QUEUE_NUMBER40; i++)
72 fQueues[i] = NULL__null;
73 if (message) {
74 int32 value;
75 if (message->FindInt32("queue number", &value) == B_OK((int)0))
76 fQueueNumber = value;
77 if (message->FindInt32("poly points", &value) == B_OK((int)0))
78 fMaxPolyPoints = value;
79 if (message->FindInt32("queue depth", &value) == B_OK((int)0))
80 fMaxQueueDepth = value;
81 if (message->FindInt32("color", &value) == B_OK((int)0))
82 fColor = value;
83 }
84 srand48((long int)system_time());
85}
86
87// destructor
88SpiderSaver::~SpiderSaver()
89{
90 _Cleanup();
91 delete[] fQueues;
92}
93
94// StartConfig
95void
96SpiderSaver::StartConfig(BView *view)
97{
98 SpiderView* configView = new SpiderView(view->Bounds(), this,
99 fQueueNumber, fMaxPolyPoints, fMaxQueueDepth, fColor);
100 view->AddChild(configView);
101}
102
103// StartSaver
104status_t
105SpiderSaver::StartSaver(BView *v, bool preview)
106{
107 SetTickSize(50000);
108
109 fPreview = preview;
110 fBounds = v->Bounds();
111 _Init(fBounds);
112
113 return B_OK((int)0);
114}
115
116// StopSaver
117void
118SpiderSaver::StopSaver()
119{
120 _Cleanup();
121}
122
123// Draw
124void
125SpiderSaver::Draw(BView *view, int32 frame)
126{
127 fLocker.Lock();
128 for (uint32 i = 0; i < fQueueNumber; i++) {
1
Loop condition is true. Entering loop body
3
Loop condition is false. Execution continues on line 132
129 if (fQueues[i])
2
Taking false branch
130 fQueues[i]->Step();
131 }
132 if (fBackView) {
4
Taking true branch
133 if (fBackBitmap->Lock()) {
5
Taking true branch
134 _DrawInto(fBackView);
6
Calling 'SpiderSaver::_DrawInto'
135 fBackView->Sync();
136 fBackBitmap->Unlock();
137 }
138 view->DrawBitmap(fBackBitmap, BPoint(0.0, 0.0));
139 }
140 fLocker.Unlock();
141}
142
143// SaveState
144status_t
145SpiderSaver::SaveState(BMessage* into) const
146{
147 if (into) {
148 into->AddInt32("queue number", (int32)fQueueNumber);
149 into->AddInt32("poly points", (int32)fMaxPolyPoints);
150 into->AddInt32("queue depth", (int32)fMaxQueueDepth);
151 into->AddInt32("color", (int32)fColor);
152 return B_OK((int)0);
153 }
154 return B_BAD_VALUE((-2147483647 - 1) + 5);
155}
156
157// SetQueueNumber
158void
159SpiderSaver::SetQueueNumber(uint32 number)
160{
161 fLocker.Lock();
162 _Cleanup();
163 fQueueNumber = number;
164 _Init(fBounds);
165 fLocker.Unlock();
166}
167
168// SetQueueDepth
169void
170SpiderSaver::SetQueueDepth(uint32 maxDepth)
171{
172 fLocker.Lock();
173 _Cleanup();
174 fMaxQueueDepth = maxDepth;
175 _Init(fBounds);
176 fLocker.Unlock();
177}
178
179// SetPolyPoints
180void
181SpiderSaver::SetPolyPoints(uint32 maxPoints)
182{
183 fLocker.Lock();
184 _Cleanup();
185 fMaxPolyPoints = maxPoints;
186 _Init(fBounds);
187 fLocker.Unlock();
188}
189
190// SetColor
191void
192SpiderSaver::SetColor(uint32 color)
193{
194 fLocker.Lock();
195 _Cleanup();
196 fColor = color;
197 _Init(fBounds);
198 fLocker.Unlock();
199}
200
201// _Init
202void
203SpiderSaver::_Init(BRect bounds)
204{
205 _AllocBackBitmap(bounds.Width(), bounds.Height());
206 uint32 minPoints = fMaxPolyPoints / 2;
207 uint32 maxPoints = fMaxPolyPoints;
208 uint32 minQueueDepth = fMaxQueueDepth / 2;
209 uint32 maxQueueDepth = fMaxQueueDepth;
210 if (fPreview) {
211 minQueueDepth /= 4;
212 maxQueueDepth /= 4;
213 }
214 for (uint32 i = 0; i < fQueueNumber; i++)
215 fQueues[i] = new PolygonQueue(new Polygon(bounds, minPoints
216 + lrand48()
217 % (maxPoints
218 - minPoints)),
219 minQueueDepth + lrand48() % (maxQueueDepth
220 - minQueueDepth));
221}
222
223// _Cleanup
224void
225SpiderSaver::_Cleanup()
226{
227 _FreeBackBitmap();
228 for (int32 i = 0; i < MAX_QUEUE_NUMBER40; i++) {
229 delete fQueues[i];
230 fQueues[i] = NULL__null;
231 }
232}
233
234// _AllocBackBitmap
235void
236SpiderSaver::_AllocBackBitmap(float width, float height)
237{
238 // sanity check
239 if (width <= 0.0 || height <= 0.0)
240 return;
241
242 BRect b(0.0, 0.0, width, height);
243 fBackBitmap = new BBitmap(b, B_RGB32, true);
244 if (!fBackBitmap)
245 return;
246 if (fBackBitmap->IsValid()) {
247 fBackView = new BView(b, 0, B_FOLLOW_NONE0, B_WILL_DRAW);
248 fBackBitmap->AddChild(fBackView);
249 memset(fBackBitmap->Bits(), 0, fBackBitmap->BitsLength());
250 } else {
251 _FreeBackBitmap();
252 fprintf(stderr, "SpiderSaver::_AllocBackBitmap(): bitmap invalid\n");
253 }
254}
255
256// _FreeBackBitmap
257void
258SpiderSaver::_FreeBackBitmap()
259{
260 if (fBackBitmap) {
261 delete fBackBitmap;
262 fBackBitmap = NULL__null;
263 fBackView = NULL__null;
264 }
265}
266
267// _DrawInto
268void
269SpiderSaver::_DrawInto(BView *view)
270{
271 for (uint32 i = 0; i < fQueueNumber; i++) {
7
Loop condition is true. Entering loop body
272 switch (fColor) {
8
Control jumps to the 'default' case at line 292
273 case GREEN:
274 view->SetHighColor(1, 2, 1, 255);
275 break;
276 case BLUE:
277 view->SetHighColor(1, 1, 2, 255);
278 break;
279 case YELLOW:
280 view->SetHighColor(2, 2, 1, 255);
281 break;
282 case PURPLE:
283 view->SetHighColor(2, 1, 2, 255);
284 break;
285 case CYAN:
286 view->SetHighColor(1, 2, 2, 255);
287 break;
288 case GRAY:
289 view->SetHighColor(2, 2, 2, 255);
290 break;
291 case RED:
292 default:
293 view->SetHighColor(2, 1, 1, 255);
294 break;
9
Execution continues on line 296
295 }
296 if (Polygon* p = fQueues[i]->Head()) {
10
Called C++ object pointer is null
297 view->SetDrawingMode(B_OP_ADD);
298 _DrawPolygon(p, view);
299 }
300 if (Polygon* p = fQueues[i]->Tail()) {
301 view->SetDrawingMode(B_OP_SUBTRACT);
302 _DrawPolygon(p, view);
303 }
304 }
305}
306
307// _DrawPolygon
308void
309SpiderSaver::_DrawPolygon(Polygon* polygon, BView *view)
310{
311 int32 pointCount = polygon->CountPoints();
312 if (pointCount > 1) {
313 BPoint p = polygon->PointAt(0);
314 view->MovePenTo(p);
315 for (int32 i = 1; i < pointCount; i++)
316 view->StrokeLine(polygon->PointAt(i));
317 view->StrokeLine(p);
318 }
319}
320
321// constructor
322SpiderView::SpiderView(BRect frame, SpiderSaver* saver,
323 uint32 queueNumber, uint32 maxPolyPoints,
324 uint32 maxQueueDepth, uint32 color)
325 : BView(frame, "spider view", B_FOLLOW_NONE0, B_WILL_DRAW | B_PULSE_NEEDED),
326 fSaver(saver)
327{
328 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
329
330 frame.OffsetTo(0.0, 0.0);
331 frame.InsetBy(10.0, 5.0);
332
333 float viewHeight = floorf(frame.Height() / 5.0);
334
335 // title stuff
336 font_height fh;
337 be_bold_font->GetHeight(&fh);
338 float fontHeight = fh.ascent + fh.descent + 5.0;
339 frame.bottom = frame.top + fontHeight;
340 BStringView* title = new BStringView(frame, B_EMPTY_STRING,
341 B_TRANSLATE("Spider by stippi")BLocaleRoster::Default()->GetCatalog()->GetString(("Spider by stippi"
), "Screensaver Spider")
);
342 title->SetFont(be_bold_font);
343 AddChild(title);
344
345 be_plain_font->GetHeight(&fh);
346 fontHeight = fh.ascent + fh.descent + 5.0;
347 frame.top = frame.bottom;
348 frame.bottom = frame.top + fontHeight;
349 title = new BStringView(frame, B_EMPTY_STRING, B_TRANSLATE("for bonefish")BLocaleRoster::Default()->GetCatalog()->GetString(("for bonefish"
), "Screensaver Spider")
);
350 BFont font(be_plain_font);
351 font.SetShear(110.0);
352 title->SetFont(&font);
353 title->SetAlignment(B_ALIGN_CENTER);
354 AddChild(title);
355
356 // controls
357 frame.top = 10.0;
358 frame.bottom = frame.top + viewHeight;
359 frame.OffsetBy(0.0, viewHeight);
360 fQueueNumberS = new BSlider(frame, "queue number",
361 B_TRANSLATE("Max. polygon count")BLocaleRoster::Default()->GetCatalog()->GetString(("Max. polygon count"
), "Screensaver Spider")
, new BMessage(MSG_QUEUE_NUMBER),
362 1, MAX_QUEUE_NUMBER40);
363 fQueueNumberS->SetHashMarks(B_HASH_MARKS_BOTTOM);
364 fQueueNumberS->SetHashMarkCount((MAX_QUEUE_NUMBER40 - 1) / 2 + 1);
365 fQueueNumberS->SetValue(queueNumber);
366 AddChild(fQueueNumberS);
367 frame.OffsetBy(0.0, viewHeight);
368 fPolyNumberS = new BSlider(frame, "poly points",
369 B_TRANSLATE("Max. points per polygon")BLocaleRoster::Default()->GetCatalog()->GetString(("Max. points per polygon"
), "Screensaver Spider")
, new BMessage(MSG_POLY_NUMBER),
370 MIN_POLY_POINTS3, MAX_POLY_POINTS10);
371 fPolyNumberS->SetHashMarks(B_HASH_MARKS_BOTTOM);
372 fPolyNumberS->SetHashMarkCount(MAX_POLY_POINTS10 - MIN_POLY_POINTS3 + 1);
373 fPolyNumberS->SetValue(maxPolyPoints);
374 AddChild(fPolyNumberS);
375 frame.OffsetBy(0.0, viewHeight);
376 fQueueDepthS = new BSlider(frame, "queue depth", B_TRANSLATE("Trail depth")BLocaleRoster::Default()->GetCatalog()->GetString(("Trail depth"
), "Screensaver Spider")
,
377 new BMessage(MSG_QUEUE_DEPTH), MIN_QUEUE_DEPTH40, MAX_QUEUE_DEPTH160);
378 fQueueDepthS->SetHashMarks(B_HASH_MARKS_BOTTOM);
379 fQueueDepthS->SetHashMarkCount((MAX_QUEUE_DEPTH160 - MIN_QUEUE_DEPTH40) / 4 + 1);
380 fQueueDepthS->SetValue(maxQueueDepth);
381 AddChild(fQueueDepthS);
382
383 BMenu* menu = new BMenu(B_TRANSLATE("Color")BLocaleRoster::Default()->GetCatalog()->GetString(("Color"
), "Screensaver Spider")
);
384 BMessage* message = new BMessage(MSG_COLOR);
385 message->AddInt32("color", RED);
386 BMenuItem* item = new BMenuItem(B_TRANSLATE("Red")BLocaleRoster::Default()->GetCatalog()->GetString(("Red"
), "Screensaver Spider")
, message);
387 if (color == RED)
388 item->SetMarked(true);
389 menu->AddItem(item);
390 message = new BMessage(MSG_COLOR);
391 message->AddInt32("color", GREEN);
392 item = new BMenuItem(B_TRANSLATE("Green")BLocaleRoster::Default()->GetCatalog()->GetString(("Green"
), "Screensaver Spider")
, message);
393 if (color == GREEN)
394 item->SetMarked(true);
395 menu->AddItem(item);
396 message = new BMessage(MSG_COLOR);
397 message->AddInt32("color", BLUE);
398 item = new BMenuItem(B_TRANSLATE("Blue")BLocaleRoster::Default()->GetCatalog()->GetString(("Blue"
), "Screensaver Spider")
, message);
399 if (color == BLUE)
400 item->SetMarked(true);
401 menu->AddItem(item);
402 message = new BMessage(MSG_COLOR);
403 message->AddInt32("color", YELLOW);
404 item = new BMenuItem(B_TRANSLATE("Yellow")BLocaleRoster::Default()->GetCatalog()->GetString(("Yellow"
), "Screensaver Spider")
, message);
405 if (color == YELLOW)
406 item->SetMarked(true);
407 menu->AddItem(item);
408 message = new BMessage(MSG_COLOR);
409 message->AddInt32("color", PURPLE);
410 item = new BMenuItem(B_TRANSLATE("Purple")BLocaleRoster::Default()->GetCatalog()->GetString(("Purple"
), "Screensaver Spider")
, message);
411 if (color == PURPLE)
412 item->SetMarked(true);
413 menu->AddItem(item);
414 message = new BMessage(MSG_COLOR);
415 message->AddInt32("color", CYAN);
416 item = new BMenuItem(B_TRANSLATE("Cyan")BLocaleRoster::Default()->GetCatalog()->GetString(("Cyan"
), "Screensaver Spider")
, message);
417 if (color == CYAN)
418 item->SetMarked(true);
419 menu->AddItem(item);
420 message = new BMessage(MSG_COLOR);
421 message->AddInt32("color", GRAY);
422 item = new BMenuItem(B_TRANSLATE("Gray")BLocaleRoster::Default()->GetCatalog()->GetString(("Gray"
), "Screensaver Spider")
, message);
423 if (color == GRAY)
424 item->SetMarked(true);
425 menu->AddItem(item);
426
427 menu->SetLabelFromMarked(true);
428 menu->SetRadioMode(true);
429
430 frame.OffsetBy(0.0, viewHeight);
431 fColorMF = new BMenuField(frame, "color", B_TRANSLATE("Color")BLocaleRoster::Default()->GetCatalog()->GetString(("Color"
), "Screensaver Spider")
, menu);
432 fColorMF->SetDivider(fColorMF->StringWidth(B_TRANSLATE("Color")BLocaleRoster::Default()->GetCatalog()->GetString(("Color"
), "Screensaver Spider")
) + 5.0);
433 AddChild(fColorMF);
434}
435
436// destructor
437SpiderView::~SpiderView()
438{
439}
440
441// AttachedToWindow
442void
443SpiderView::AttachedToWindow()
444{
445 fQueueNumberS->SetTarget(this);
446 fPolyNumberS->SetTarget(this);
447 fQueueDepthS->SetTarget(this);
448 fColorMF->Menu()->SetTargetForItems(this);
449}
450
451// MessageReceived
452void
453SpiderView::MessageReceived(BMessage* message)
454{
455 switch (message->what) {
456 case MSG_QUEUE_NUMBER:
457 fSaver->SetQueueNumber(fQueueNumberS->Value());
458 break;
459 case MSG_POLY_NUMBER:
460 fSaver->SetPolyPoints(fPolyNumberS->Value());
461 break;
462 case MSG_QUEUE_DEPTH:
463 fSaver->SetQueueDepth(fQueueDepthS->Value());
464 break;
465 case MSG_COLOR: {
466 uint32 color;
467 if (message->FindInt32("color", (int32*)&color) == B_OK((int)0))
468 fSaver->SetColor(color);
469 break;
470 }
471 default:
472 BView::MessageReceived(message);
473 break;
474 }
475}
476