1#include "SnowView.h" 2 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6#include <math.h> 7 8#include <Alert.h> 9#include <Catalog.h> 10#include <Debug.h> 11#include <Message.h> 12#include <MessageRunner.h> 13#include <MessageFilter.h> 14#include <OS.h> 15#include <Region.h> 16#include <Screen.h> 17 18#include "Flakes.h" 19 20 21#define FORWARD_TO_PARENT 22#undef B_TRANSLATION_CONTEXT 23#define B_TRANSLATION_CONTEXT "BSnow" 24 25 26SnowView::SnowView() 27 : 28 BView(BRect(SNOW_VIEW_RECT), "BSnow", B_FOLLOW_NONE, 29 B_WILL_DRAW | B_PULSE_NEEDED) 30{ 31 fAttached = false; 32 fMsgRunner = NULL; 33 fCachedParent = NULL; 34 fFallenBmp = NULL; 35 fFallenView = NULL; 36 fFallenReg = NULL; 37 fInvalidator = -1; 38 fShowClickMe = false; 39 for (int i = 0; i < WORKSPACES_COUNT; i++) 40 fFlakes[i] = NULL; 41 for (int i = 0; i < NUM_PATTERNS; i++) 42 fFlakeBitmaps[i] = NULL; 43 BRect r(Frame()); 44 r.left = r.right - 7; 45 r.top = r.bottom - 7; 46 fDragger = new BDragger(r, this); 47 AddChild(fDragger); 48 SetHighColor(255,255,255); 49} 50 51#ifdef DEBUG 52filter_result msgfilter(BMessage *message, BHandler **target, BMessageFilter *filter) 53{ 54 switch (message->what) { 55 case B_MOUSE_DOWN: 56 case B_MOUSE_UP: 57 case B_MOUSE_MOVED: 58 case '_EVP': 59 case '_UPD': 60 case '_PUL': 61 case 'NTCH': 62 case 'NMDN': 63 break; 64 default: 65 printf("For: %p: %s\n", *target, (*target)->Name()); 66 message->PrintToStream(); 67 } 68 return B_DISPATCH_MESSAGE; 69} 70#endif 71 72SnowView::SnowView(BMessage *archive) 73 : BView(archive) 74{ 75 system_info si; 76 PRINT(("SnowView()\n")); 77#ifdef DEBUG 78 archive->PrintToStream(); 79#endif 80 fDragger = NULL; 81 fAttached = false; 82 fMsgRunner = NULL; 83 fFallenBmp = NULL; 84 fFallenView = NULL; 85 fFallenReg = NULL; 86 fCachedParent = NULL; 87 fShowClickMe = false; 88 SetFlags(Flags() & ~B_PULSE_NEEDED); /* it's only used when in the app */ 89 get_system_info(&si); 90 fNumFlakes = ((int32)(si.cpu_clock_speed/1000000)) * si.cpu_count / 3; //; 91 printf("BSnow: using %ld flakes\n", fNumFlakes); 92 for (int i = 0; i < WORKSPACES_COUNT; i++) { 93 fFlakes[i] = new flake[fNumFlakes]; 94 memset(fFlakes[i], 0, fNumFlakes * sizeof(flake)); 95 } 96 for (int i = 0; i < NUM_PATTERNS; i++) { 97 fFlakeBitmaps[i] = new BBitmap(BRect(0,0,7,7), B_CMAP8); 98 fFlakeBitmaps[i]->SetBits(gFlakeBits[i], 8*8, 0, B_CMAP8); 99 } 100 fCurrentWorkspace = 0; 101 SetHighColor(255,255,255); 102 SetDrawingMode(B_OP_OVER); 103} 104 105SnowView::~SnowView() 106{ 107 for (int i = 0; i < WORKSPACES_COUNT; i++) 108 if (fFlakes[i]) 109 delete [] fFlakes[i]; 110 if (fFallenBmp) 111 delete fFallenBmp; /* the view goes away with it */ 112} 113 114BArchivable *SnowView::Instantiate(BMessage *data) 115{ 116 return new SnowView(data); 117} 118 119status_t SnowView::Archive(BMessage *data, bool deep) const 120{ 121 status_t err; 122 err = BView::Archive(data, deep); 123 if (err < B_OK) 124 return err; 125 data->AddString("add_on", APP_SIG); 126 return B_OK; 127} 128 129void SnowView::AttachedToWindow() 130{ 131 BView *p; 132 rgb_color col; 133 fAttached = true; 134/* if (!fMsgRunner) 135 fMsgRunner = new BMessageRunner(BMessenger(this), 136 new BMessage(MSG_PULSE_ME), 137 INTERVAL); 138*/ 139 p = Parent(); 140 if (p) 141 col = B_TRANSPARENT_32_BIT;//Parent()->ViewColor(); 142 else 143 col = ui_color(B_PANEL_BACKGROUND_COLOR); 144 SetViewColor(col); 145// BScreen bs; 146// fCachedWsWidth = bs.Frame().IntegerWidth(); 147// fCachedWsHeight = bs.Frame().IntegerHeight(); 148 fDragger = dynamic_cast<BDragger *>(FindView("_dragger_")); 149 if (fDragger && p) { 150 fCachedParent = p; 151 fCachedWsWidth = p->Frame().IntegerWidth(); 152 fCachedWsHeight = p->Frame().IntegerHeight(); 153 fDragger->SetViewColor(col); 154 if (fDragger->InShelf()) { 155 p->SetFlags(p->Flags() | B_DRAW_ON_CHILDREN); 156#ifdef B_BEOS_VERSION_DANO 157 p->SetDoubleBuffering(p->DoubleBuffering() | B_UPDATE_EXPOSED); 158#endif 159 ResizeTo(p->Bounds().Width(), p->Bounds().Height()); 160 MoveTo(0,0); 161 fDragger->MoveTo(p->Bounds().Width()-7, p->Bounds().Height()-7); 162 } 163 BRect fallenRect(p->Bounds()); 164 fallenRect.top = fallenRect.bottom - FALLEN_HEIGHT; 165 fFallenBmp = new BBitmap(fallenRect, B_BITMAP_ACCEPTS_VIEWS, B_CMAP8); 166 memset(fFallenBmp->Bits(), B_TRANSPARENT_MAGIC_CMAP8, (size_t)(fallenRect.Height()*fFallenBmp->BytesPerRow())); 167 fFallenView = new BView(fallenRect, "offscreen fallen snow", B_FOLLOW_NONE, 0); 168 fFallenBmp->AddChild(fFallenView); 169 fFallenReg = new BRegion; 170 fInvalidator = spawn_thread(SnowMakerThread, INVALIDATOR_THREAD_NAME, B_LOW_PRIORITY, (void *)this); 171 resume_thread(fInvalidator); 172 printf("BSnow: OK: ws = %" B_PRId32 " x %" B_PRId32 "\n", fCachedWsWidth, fCachedWsHeight); 173#ifdef DEBUG 174 Window()->AddCommonFilter(new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, msgfilter)); 175#endif 176 } 177} 178 179void SnowView::DetachedFromWindow() 180{ 181 fAttached = false; 182/* 183 if (Parent()) { 184 Parent()->Invalidate(Parent()->Bounds()); 185 } 186*/ 187 if (fMsgRunner) 188 delete fMsgRunner; 189 fMsgRunner = NULL; 190 status_t err; 191 fCachedParent = NULL; 192 if (fInvalidator > B_OK) 193 wait_for_thread(fInvalidator, &err); 194 fInvalidator = -1; 195 if (fFallenReg) 196 delete fFallenReg; 197} 198 199void SnowView::MessageReceived(BMessage *msg) 200{ 201 BAlert *info; 202 //msg->PrintToStream(); 203 switch (msg->what) { 204 case MSG_PULSE_ME: 205 if (Parent()) { 206 Calc(); 207 InvalFlakes(); 208 } 209 break; 210 case B_ABOUT_REQUESTED: 211 info = new BAlert("BSnow info", 212 "BSnow, just in case you don't have real one...\n" 213 "" B_UTF8_COPYRIGHT " 2003, Fran��ois Revol.", 214 "Where is Santa ??"); 215 info->SetFeel(B_NORMAL_WINDOW_FEEL); 216 info->SetLook(B_FLOATING_WINDOW_LOOK); 217 info->SetFlags(info->Flags()|B_NOT_ZOOMABLE|B_CLOSE_ON_ESCAPE); 218 info->Go(NULL); 219 break; 220 default: 221//#ifdef FORWARD_TO_PARENT 222/* 223 if (fAttached && Parent()) 224 Parent()->MessageReceived(msg); 225 else 226*/ 227//#endif 228 BView::MessageReceived(msg); 229 } 230} 231 232void SnowView::Draw(BRect ur) 233{ 234 int i; 235 if (!fCachedParent) { 236 if (!fShowClickMe) { /* show "drag me" */ 237 SetLowColor(ViewColor()); 238 SetHighColor(0,0,0); 239 SetFontSize(12); 240 DrawString(B_TRANSLATE("Drag me on your desktop"B_UTF8_ELLIPSIS), 241 BPoint(15,25)); 242 BPoint arrowHead(Bounds().RightBottom() + BPoint(-10,-10)); 243 StrokeLine(arrowHead, arrowHead - BPoint(7,0)); 244 StrokeLine(arrowHead, arrowHead - BPoint(0,7)); 245 StrokeLine(arrowHead, arrowHead - BPoint(12,12)); 246 return; 247 } else { 248 SetLowColor(ViewColor()); 249 SetHighColor(0,0,0); 250 SetFontSize(12); 251 DrawString(B_TRANSLATE("Click me to remove BSnow"B_UTF8_ELLIPSIS), 252 BPoint(15,25)); 253 return; 254 } 255 } 256 //printf("Draw()\n"); 257 uint32 cw = fCurrentWorkspace; 258 if (fFlakes[cw] == NULL) 259 return; 260 /* draw the snow already fallen */ 261// BRect fallenRect(Bounds()); 262// fallenRect.top = fallenRect.bottom - FALLEN_HEIGHT; 263// if (ur.Intersects(fallenRect)) { 264 //if (fFallenBmp->Lock()) { 265 // DrawBitmap(fFallenBmp, fallenRect); 266 // fFallenBmp->Unlock(); 267 //} 268 int32 cnt = fFallenReg->CountRects(); 269// drawing_mode oldmode = DrawingMode(); 270// SetDrawingMode(B_OP_ADD); 271 272 for (i=0; i<cnt; i++) { 273 BRect r = fFallenReg->RectAt(i); 274// SetHighColor(245, 245, 245, 200); 275// FillRect(r); 276// SetHighColor(255, 255, 255, 255); 277// r.InsetBy(1,1); 278 FillRect(r); 279 } 280// SetDrawingMode(oldmode); 281// } 282 /* draw our flakes */ 283 for (i=0; i<fNumFlakes; i++) { 284 int pat; 285 if (!ur.Contains(BRect(fFlakes[cw][i].pos-BPoint(4,4), fFlakes[cw][i].pos+BPoint(4,4)))) 286 continue; 287 if (fFlakes[cw][i].weight == 0) 288 continue; 289 pat = (fFlakes[cw][i].weight>3)?1:0; 290 //FillRect(BRect(fFlakes[cw][i].pos-BPoint(PAT_HOTSPOT),fFlakes[cw][i].pos-BPoint(PAT_HOTSPOT)+BPoint(7,7)), gFlakePatterns[pat]); 291/* 292 StrokeLine(fFlakes[cw][i].pos+BPoint(-1,-1), 293 fFlakes[cw][i].pos+BPoint(1,1)); 294 StrokeLine(fFlakes[cw][i].pos+BPoint(-1,1), 295 fFlakes[cw][i].pos+BPoint(1,-1)); 296*/ 297 DrawBitmap(fFlakeBitmaps[pat], fFlakes[cw][i].pos-BPoint(PAT_HOTSPOT)); 298 } 299} 300 301void SnowView::Pulse() 302{ 303 if (fShowClickMe) 304 return; /* done */ 305 if (fCachedParent) 306 return; /* we are in Tracker! */ 307 BMessenger msgr("application/x-vnd.Be-TRAK"); 308 BMessage msg(B_GET_PROPERTY), reply; 309 msg.AddSpecifier("Frame"); 310 msg.AddSpecifier("View", "BSnow"); 311 msg.AddSpecifier("Window", 1); /* 0 is Twitcher */ 312 if (msgr.SendMessage(&msg, &reply) == B_OK && reply.what == B_REPLY) { 313 //reply.PrintToStream(); 314 Invalidate(Bounds()); 315 fShowClickMe = true; 316 } 317} 318 319void SnowView::Calc() 320{ 321 int i; 322 uint32 cw = fCurrentWorkspace; 323 324 /* check if the parent changed size */ 325 BRect pFrame = fCachedParent->Frame(); 326 if (fCachedWsWidth != pFrame.Width() || fCachedWsHeight != pFrame.Height()) { 327 fCachedWsWidth = pFrame.IntegerWidth(); 328 fCachedWsHeight = pFrame.IntegerHeight(); 329 printf("BSnow: Parent resized to %" B_PRId32 " %" B_PRId32 "\n", fCachedWsWidth, fCachedWsHeight); 330 fFallenReg->MakeEmpty(); /* remove all the fallen snow */ 331 ResizeTo(pFrame.IntegerWidth(), pFrame.IntegerHeight()); 332 fDragger->MoveTo(pFrame.IntegerWidth()-7, pFrame.IntegerHeight()-7); 333 } 334 335 /* make new flakes */ 336 for (i=0; i<fNumFlakes; i++) { 337 if (fFlakes[cw][i].weight == 0) { 338 fFlakes[cw][i].weight = ((float)(rand() % WEIGHT_SPAN)) / WEIGHT_GRAN; 339 fFlakes[cw][i].weight = MAX(fFlakes[cw][i].weight, 0.5); 340 fFlakes[cw][i].pos.y = rand() % 5 - 2; 341 fFlakes[cw][i].pos.x = (rand()%(fCachedWsWidth+2*fCachedWsHeight))-fCachedWsHeight; 342 if (fFlakes[cw][i].pos.x < -10) { 343 fFlakes[cw][i].pos.y = -fFlakes[cw][i].pos.x; 344 if (fWind > 0) 345 fFlakes[cw][i].pos.x = 0; 346 else 347 fFlakes[cw][i].pos.x = fCachedWsWidth; 348 } 349 if (fFlakes[cw][i].pos.x > fCachedWsWidth+10) { 350 fFlakes[cw][i].pos.y = fFlakes[cw][i].pos.x - fCachedWsWidth; 351 if (fWind > 0) 352 fFlakes[cw][i].pos.x = 0; 353 else 354 fFlakes[cw][i].pos.x = fCachedWsWidth; 355 } 356 } 357 } 358 359 /* like a candle in the wind... */ 360 if (fWindDuration < system_time()) { 361 fWindDuration = system_time() + ((((bigtime_t)rand())*1000) % WIND_MAX_DURATION); 362 fWind = (rand() % WIND_SPAN) - WIND_SPAN/2; 363 printf("BSnow: wind change: %f\n", fWind); 364 } 365 366 367// if (fFallenView->LockLooperWithTimeout(5000)) { 368// if (fFallenBmp) { 369// uint8 *fallenBits = (uint8 *)fFallenBmp->Bits(); 370 371 BRegion desktopReg; 372 GetClippingRegion(&desktopReg); 373 374 /* let's add some gravity and wind */ 375 for (i=0; i<fNumFlakes; i++) { 376 float yinc; 377 if (fFlakes[cw][i].weight == 0) 378 continue; 379 fFlakes[cw][i].opos = fFlakes[cw][i].pos; 380 381 yinc = fFlakes[cw][i].weight - (rand() % 3); 382 yinc = MAX(yinc, 0.5); 383 fFlakes[cw][i].pos.y += yinc; 384 385// if (fFlakes[cw][i].pos.y > (fCachedWsHeight-FALLEN_HEIGHT)) { 386 387 bool fallen = false; 388 bool keepfalling = false; 389 390 /* fallen on the flour */ 391 if (fFlakes[cw][i].pos.y > fCachedWsHeight-2) 392 fallen = true; 393 /* fallon on another fallen flake */ 394 else if (fFallenReg->Intersects(BRect(fFlakes[cw][i].pos - BPoint(0,1), 395 fFlakes[cw][i].pos + BPoint(0,1)))) { 396 /* don't accumulate too much */ 397 if ((fFlakes[cw][i].pos.y > fCachedWsHeight-30) || 398 !desktopReg.Intersects( 399 BRect(fFlakes[cw][i].pos + BPoint(0,6), 400 fFlakes[cw][i].pos + BPoint(0,10)))) 401 fallen = true; 402 /* fallen on a window */ 403 } else if (!desktopReg.Intersects( 404 BRect(fFlakes[cw][i].pos + BPoint(-1,-1-2), 405 fFlakes[cw][i].pos + BPoint(1,1-1))) && 406 desktopReg.Intersects( 407 BRect(fFlakes[cw][i].pos + BPoint(-1,-1-3), 408 fFlakes[cw][i].pos + BPoint(1,1-3)))) { 409 //printf("fallen3 @ %f %f\n", fFlakes[cw][i].pos.x, fFlakes[cw][i].pos.y); 410 fFlakes[cw][i].pos = fFlakes[cw][i].opos; 411 fallen = true; 412 keepfalling = true; /* but keep one falling */ 413 } 414 415/* else if (fallenBits[ (long)(fFlakes[cw][i].pos.y 416 * fFallenBmp->BytesPerRow() 417 + fFlakes[cw][i].pos.y 418 - (fCachedWsHeight-FALLEN_HEIGHT)) ] != B_TRANSPARENT_MAGIC_CMAP8) { 419 fallen = true; 420 }*/ 421 422// if (fallen) { 423// int pat = (fFlakes[cw][i].weight>3)?1:0; 424// if (fFlakes[cw][i].pos.y > fCachedWsHeight-1) 425// fFlakes[cw][i].pos.y = fCachedWsHeight-(rand()%4); 426 //fFallenView->DrawBitmap(fFlakeBitmaps[pat], fFlakes[cw][i].pos-BPoint(PAT_HOTSPOT)); 427// fallenBits[ (long)(fFlakes[cw][i].pos.y * fFallenBmp->BytesPerRow() 428// + fFlakes[cw][i].pos.y-(fCachedWsHeight-FALLEN_HEIGHT)) ] = 0x56; 429// printf("fallen @ %f, %f\n", fFlakes[cw][i].pos.x, fFlakes[cw][i].pos.y); 430// } 431 if (fallen) { 432 if (!keepfalling) 433 fFlakes[cw][i].weight = 0; 434 fFallenReg->Include(BRect(fFlakes[cw][i].pos - BPoint(2,0), 435 fFlakes[cw][i].pos + BPoint(2,2))); 436 if (keepfalling) { 437 fFlakes[cw][i].pos += BPoint(0,10); 438 /* except if under the desktop */ 439 if (fFlakes[cw][i].pos.y > fCachedWsHeight-1) 440 fFlakes[cw][i].weight = 0; 441 } 442 } 443 444 /* cleanup, when a window hides the snow */ 445 fFallenReg->IntersectWith(&desktopReg); 446 447 /* cleanup, when a window is moved */ 448 /* seems to lockup Tracker */ 449/* 450 int32 cnt = fFallenReg->CountRects(); 451 for (i=0; i<cnt; i++) { 452 BRect r = fFallenReg->RectAt(i); 453 if (desktopReg.Intersects(r.OffsetByCopy(0,15))) { 454 fFallenReg->Exclude(r); 455 cnt--; 456 } 457 } 458*/ 459 /* add the effect of the wind */ 460 fFlakes[cw][i].pos.x += fWind + (rand() % 6 - 3); 461 if ((fFlakes[cw][i].pos.x > fCachedWsWidth+50)||(fFlakes[cw][i].pos.x < -50)) 462 fFlakes[cw][i].weight = 0; 463 } 464// fFallenView->UnlockLooper(); 465// } 466#if 0 467 for (i=0; i<10; i++) 468 printf("f[%d] = {%f, %f}, {%f, %f}, %d\n", i, 469 fFlakes[cw][i].opos.x, fFlakes[cw][i].opos.y, 470 fFlakes[cw][i].pos.x, fFlakes[cw][i].pos.y, 471 fFlakes[cw][i].weight); 472#endif 473} 474 475void SnowView::InvalFlakes() 476{ 477 int i; 478 BView *p = Parent(); 479 if (!p) 480 return; 481 //printf("InvalFlakes()\n"); 482 uint32 cw = fCurrentWorkspace; 483 484 for (i=0; i<fNumFlakes; i++) { 485 if (fFlakes[cw][i].weight) 486 Invalidate(BRect(fFlakes[cw][i].opos-BPoint(PAT_HOTSPOT), fFlakes[cw][i].opos-BPoint(PAT_HOTSPOT)+BPoint(7,7))); 487 } 488} 489 490void SnowView::MouseDown(BPoint where) 491{ 492#ifdef FORWARD_TO_PARENT 493 if (fAttached && Parent()) 494 Parent()->MouseDown(where); 495#endif 496} 497 498void SnowView::MouseUp(BPoint where) 499{ 500#ifdef FORWARD_TO_PARENT 501 if (fAttached && Parent()) 502 Parent()->MouseUp(where); 503#endif 504 if (fCachedParent) 505 return; /* we are *inside* the Tracker, 506 * don't even try talking to ourselve 507 * with the window locked 508 */ 509 BMessenger msgr("application/x-vnd.Be-TRAK"); 510 BMessage msg(B_DELETE_PROPERTY), reply; 511 msg.AddSpecifier("Replicant", "BSnow"); 512 msg.AddSpecifier("Shelf"); 513 msg.AddSpecifier("View", "PoseView"); 514 msg.AddSpecifier("Window", 1); /* 0 is Tracker Status */ 515 if ((msgr.SendMessage(&msg, &reply) == B_OK) && 516 (reply.what == B_NO_REPLY || reply.what == B_REPLY)) { 517 //reply.PrintToStream(); 518 fShowClickMe = false; 519 Invalidate(Bounds()); 520 } 521 /* 522 BMessage: what = JAHA (0x4a414841, or 1245792321) 523 entry index, type='LONG', c=1, size= 4, data[0]: 0x2 (2, '') 524 entry when, type='LLNG', c=1, size= 8, data[0]: 0xf6a1b09ac (66204666284, '') 525 entry source, type='PNTR', c=1, size= 4, 526 entry be:sender, type='MSNG', c=1, size=24, 527 */ 528} 529 530void SnowView::MouseMoved(BPoint where, uint32 code, const BMessage *a_message) 531{ 532#ifdef FORWARD_TO_PARENT 533 if (fAttached && Parent()) 534 Parent()->MouseMoved(where, code, a_message); 535#endif 536} 537 538void SnowView::KeyDown(const char *bytes, int32 numBytes) 539{ 540#ifdef FORWARD_TO_PARENT 541 if (fAttached && Parent()) 542 Parent()->KeyDown(bytes, numBytes); 543#endif 544} 545 546void SnowView::KeyUp(const char *bytes, int32 numBytes) 547{ 548#ifdef FORWARD_TO_PARENT 549 if (fAttached && Parent()) 550 Parent()->KeyUp(bytes, numBytes); 551#endif 552} 553 554#define PORTION_GRAN 20 555 556int32 SnowView::SnowMakerThread(void *p_this) 557{ 558 SnowView *_this = (SnowView *)p_this; 559 BView *p = _this->Parent(); 560 BRect portion(0,0,(_this->fCachedWsWidth/PORTION_GRAN)-1, (_this->fCachedWsHeight/PORTION_GRAN)-1); 561 int nf = _this->fNumFlakes; 562 BRegion reg(BRect(-1,-1,-1,-1)); 563 while (p && _this->fAttached) { 564 snooze(INTERVAL/(10*(nf?nf:1))); 565 int32 cw = _this->fCurrentWorkspace; 566 bool drawThisOne = false; 567//printf("processing flake %d...\n", current); 568 //for (; (current%(fNumFlakes/4); current++) 569 if (reg.Intersects(portion)) { 570 for (int i = 0; !drawThisOne && i < nf; i++) { 571 /* if we find at least one flake in this rect, draw it */ 572 if ((_this->fFlakes[cw][i].weight) && ( 573 portion.Intersects(BRect(_this->fFlakes[cw][i].opos - BPoint(4,4), _this->fFlakes[cw][i].opos + BPoint(4,4))) || 574 portion.Intersects(BRect(_this->fFlakes[cw][i].pos - BPoint(4,4), _this->fFlakes[cw][i].pos + BPoint(4,4))))) { 575 drawThisOne = true; 576 } 577 } 578 } 579 //if (!drawThisOne) 580 //printf("!Invalidate(%f, %f, %f, %f)\n", portion.left, portion.top, portion.right, portion.bottom); 581 /* avoid deadlock on exit */ 582 if (drawThisOne && (_this->LockLooperWithTimeout(2000) == B_OK)) { 583// printf("Invalidate(%f, %f, %f, %f)\n", portion.left, portion.top, portion.right, portion.bottom); 584 p->Invalidate(portion); 585 _this->UnlockLooper(); 586 } 587 portion.OffsetBy(_this->fCachedWsWidth/PORTION_GRAN, 0); 588 if (portion.left >= _this->fCachedWsWidth) { /* right wrap */ 589 //printf("rigth wrap to %ld\n", _this->fCachedWsWidth); 590 portion.OffsetTo(0, portion.top+(_this->fCachedWsHeight/PORTION_GRAN)); 591 } 592 if (portion.top >= _this->fCachedWsHeight) { 593 portion.OffsetTo(0,0); 594 /* avoid deadlock on exit */ 595 if (_this->LockLooperWithTimeout(5000) == B_OK) { 596//printf("calculating flakes...\n"); 597 _this->Calc(); 598//printf("done calculating flakes.\n"); 599 _this->GetClippingRegion(®); 600 //printf("Region:\n"); 601 //reg.PrintToStream(); 602 _this->UnlockLooper(); 603 } 604 } 605 } 606#if 0 607 BView *p = _this->Parent(); 608 while (p && _this->fAttached) { 609 snooze(INTERVAL/_this->fNumFlakes); 610//printf("processing flake %d...\n", current); 611 //for (; (current%(fNumFlakes/4); current++) 612 /* avoid deadlock on exit */ 613 if (_this->LockLooperWithTimeout(2000) == B_OK) { 614 if (_this->fFlakes[_this->fCurrentWorkspace][current].weight) { 615 p->Invalidate(BRect(_this->fFlakes[_this->fCurrentWorkspace][current].opos - BPoint(4,4), 616 _this->fFlakes[_this->fCurrentWorkspace][current].opos + BPoint(4,4))); 617 p->Invalidate(BRect(_this->fFlakes[_this->fCurrentWorkspace][current].pos - BPoint(4,4), 618 _this->fFlakes[_this->fCurrentWorkspace][current].pos + BPoint(4,4))); 619 } 620 _this->UnlockLooper(); 621 current++; 622 current %= _this->fNumFlakes; 623 if (!current) { 624 /* avoid deadlock on exit */ 625 if (_this->LockLooperWithTimeout(2000) == B_OK) { 626printf("calculating flakes...\n"); 627 _this->Calc(); 628printf("done calculating flakes.\n"); 629 _this->UnlockLooper(); 630 } 631 } 632 } 633 } 634#endif 635 return B_OK; 636} 637