1 /* 2 * Copyright 2001-2016, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * DarkWyrm <bpmagic@columbus.rr.com> 7 * Adrian Oanca <adioanca@cotty.iren.ro> 8 * Stephan Aßmus <superstippi@gmx.de> 9 * Stefano Ceccherini (burton666@libero.it) 10 * Axel Dörfler, axeld@pinc-software.de 11 * Jérôme Duval, jerome.duval@free.fr 12 * Andrej Spielmann, <andrej.spielmann@seh.ox.ac.uk> 13 * Philippe Saint-Pierre, stpere@gmail.com 14 * Wim van der Meer, <WPJvanderMeer@gmail.com> 15 * Joseph Groover <looncraz@looncraz.net> 16 */ 17 18 19 /*! \class ServerApp ServerApp.h 20 \brief Counterpart to BApplication within the app_server 21 */ 22 23 24 #include "ServerApp.h" 25 26 #include <new> 27 #include <stdio.h> 28 #include <string.h> 29 #include <syslog.h> 30 31 #include <AppDefs.h> 32 #include <Autolock.h> 33 #include <AutoLocker.h> 34 #include <Debug.h> 35 #include <List.h> 36 #include <ScrollBar.h> 37 #include <Shape.h> 38 #include <String.h> 39 #include <StackOrHeapArray.h> 40 41 #include <FontPrivate.h> 42 #include <MessengerPrivate.h> 43 #include <PrivateScreen.h> 44 #include <RosterPrivate.h> 45 #include <ServerProtocol.h> 46 #include <WindowPrivate.h> 47 48 #include "AppFontManager.h" 49 #include "AppServer.h" 50 #include "BitmapManager.h" 51 #include "CursorManager.h" 52 #include "CursorSet.h" 53 #include "Desktop.h" 54 #include "DecorManager.h" 55 #include "DrawingEngine.h" 56 #include "EventStream.h" 57 #include "GlobalFontManager.h" 58 #include "HWInterface.h" 59 #include "InputManager.h" 60 #include "OffscreenServerWindow.h" 61 #include "Screen.h" 62 #include "ServerBitmap.h" 63 #include "ServerConfig.h" 64 #include "ServerCursor.h" 65 #include "ServerPicture.h" 66 #include "ServerTokenSpace.h" 67 #include "ServerWindow.h" 68 #include "SystemPalette.h" 69 #include "Window.h" 70 71 72 //#define DEBUG_SERVERAPP 73 #ifdef DEBUG_SERVERAPP 74 # define STRACE(x) debug_printf x 75 #else 76 # define STRACE(x) ; 77 #endif 78 79 //#define DEBUG_SERVERAPP_FONT 80 #ifdef DEBUG_SERVERAPP_FONT 81 # define FTRACE(x) debug_printf x 82 #else 83 # define FTRACE(x) ; 84 #endif 85 86 using std::nothrow; 87 88 static const uint32 kMsgUpdateShowAllDraggers = '_adg'; 89 static const uint32 kMsgAppQuit = 'appQ'; 90 91 92 ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort, 93 port_id clientLooperPort, team_id clientTeam, 94 int32 clientToken, const char* signature) 95 : 96 MessageLooper("application"), 97 98 fMessagePort(-1), 99 fClientReplyPort(clientReplyPort), 100 fDesktop(desktop), 101 fSignature(signature), 102 fClientTeam(clientTeam), 103 fWindowListLock("window list"), 104 fInitialWorkspace(desktop->CurrentWorkspace()), 105 // TODO: this should probably be retrieved when the app is loaded! 106 fTemporaryDisplayModeChange(0), 107 fMapLocker("server app maps"), 108 fAppCursor(NULL), 109 fViewCursor(NULL), 110 fCursorHideLevel(0), 111 fIsActive(false), 112 fMemoryAllocator(new (std::nothrow) ClientMemoryAllocator(this), true), 113 fAppFontManager(NULL) 114 { 115 if (fSignature.IsEmpty()) 116 fSignature = "application/no-signature"; 117 118 char name[B_OS_NAME_LENGTH]; 119 snprintf(name, sizeof(name), "a<%" B_PRId32 ":%s", fClientTeam, 120 SignatureLeaf()); 121 122 fMessagePort = create_port(DEFAULT_MONITOR_PORT_SIZE, name); 123 if (fMessagePort < B_OK) 124 return; 125 126 fLink.SetSenderPort(fClientReplyPort); 127 fLink.SetReceiverPort(fMessagePort); 128 fLink.SetTargetTeam(fClientTeam); 129 130 // we let the application own the port, so that we get aware when it's gone 131 if (set_port_owner(fMessagePort, fClientTeam) < B_OK) { 132 delete_port(fMessagePort); 133 fMessagePort = -1; 134 return; 135 } 136 137 BMessenger::Private(fHandlerMessenger).SetTo(fClientTeam, 138 clientLooperPort, clientToken); 139 140 // record the current system wide fonts.. 141 desktop->LockSingleWindow(); 142 DesktopSettings settings(desktop); 143 settings.GetDefaultPlainFont(fPlainFont); 144 settings.GetDefaultBoldFont(fBoldFont); 145 settings.GetDefaultFixedFont(fFixedFont); 146 desktop->UnlockSingleWindow(); 147 148 fAppFontManager = new AppFontManager(); 149 150 STRACE(("ServerApp %s:\n", Signature())); 151 STRACE(("\tBApp port: %" B_PRId32 "\n", fClientReplyPort)); 152 STRACE(("\tReceiver port: %" B_PRId32 "\n", fMessagePort)); 153 } 154 155 156 ServerApp::~ServerApp() 157 { 158 STRACE(("*ServerApp %s:~ServerApp()\n", Signature())); 159 ASSERT(fQuitting); 160 161 // quit all server windows 162 163 fWindowListLock.Lock(); 164 for (int32 i = fWindowList.CountItems(); i-- > 0;) { 165 ServerWindow* window = fWindowList.ItemAt(i); 166 window->Quit(); 167 } 168 fWindowListLock.Unlock(); 169 170 // wait for the windows to quit 171 snooze(20000); 172 173 fDesktop->RevertScreenModes(fTemporaryDisplayModeChange); 174 175 fWindowListLock.Lock(); 176 for (int32 i = fWindowList.CountItems(); i-- > 0;) { 177 ServerWindow* window = fWindowList.ItemAt(i); 178 179 // A window could have been removed in the mean time 180 // (if those 20 milli seconds from above weren't enough) 181 if (window == NULL) 182 continue; 183 184 sem_id deathSemaphore = window->DeathSemaphore(); 185 fWindowListLock.Unlock(); 186 187 // wait 3 seconds for our window to quit - that's quite a long 188 // time, but killing it might have desastrous effects 189 if (MessageLooper::WaitForQuit(deathSemaphore, 3000000) != B_OK) { 190 // This really shouldn't happen, as it shows we're buggy 191 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST 192 syslog(LOG_ERR, "ServerApp %s: ServerWindow doesn't respond!\n", 193 Signature()); 194 #else 195 debugger("ServerWindow doesn't respond!\n"); 196 #endif 197 } 198 fWindowListLock.Lock(); 199 } 200 201 if (fMemoryAllocator != NULL) 202 fMemoryAllocator->Detach(); 203 fMapLocker.Lock(); 204 205 while (!fBitmapMap.empty()) 206 _DeleteBitmap(fBitmapMap.begin()->second); 207 208 while (!fPictureMap.empty()) 209 fPictureMap.begin()->second->SetOwner(NULL); 210 211 fDesktop->GetCursorManager().DeleteCursors(fClientTeam); 212 213 delete fAppFontManager; 214 215 STRACE(("ServerApp %s::~ServerApp(): Exiting\n", Signature())); 216 } 217 218 219 /*! \brief Checks if the application was initialized correctly 220 */ 221 status_t 222 ServerApp::InitCheck() 223 { 224 if (fMessagePort < B_OK) 225 return fMessagePort; 226 227 if (fClientReplyPort < B_OK) 228 return fClientReplyPort; 229 230 if (fWindowListLock.InitCheck() < B_OK) 231 return fWindowListLock.InitCheck(); 232 233 if (fMemoryAllocator == NULL) 234 return B_NO_MEMORY; 235 236 return B_OK; 237 } 238 239 240 void 241 ServerApp::Quit() 242 { 243 Quit(-1); 244 } 245 246 247 /*! \brief This quits the application and deletes it. You're not supposed 248 to call its destructor directly. 249 250 At the point you're calling this method, the application should already 251 be removed from the application list. 252 */ 253 void 254 ServerApp::Quit(sem_id shutdownSemaphore) 255 { 256 if (fThread < B_OK) { 257 delete this; 258 return; 259 } 260 261 // execute application deletion in the message looper thread 262 263 fQuitting = true; 264 PostMessage(kMsgAppQuit); 265 266 send_data(fThread, 'QUIT', &shutdownSemaphore, sizeof(sem_id)); 267 } 268 269 270 /*! \brief Sets the ServerApp's active status 271 \param value The new status of the ServerApp. 272 273 This changes an internal flag and also sets the current cursor to the one 274 specified by the application 275 */ 276 void 277 ServerApp::Activate(bool value) 278 { 279 if (fIsActive == value) 280 return; 281 282 fIsActive = value; 283 284 if (fIsActive) { 285 // notify registrar about the active app 286 BRoster::Private roster; 287 roster.UpdateActiveApp(ClientTeam()); 288 289 if (_HasWindowUnderMouse()) { 290 // Set the cursor to the application cursor, if any 291 fDesktop->SetCursor(CurrentCursor()); 292 } 293 fDesktop->HWInterface()->SetCursorVisible(fCursorHideLevel == 0); 294 } 295 } 296 297 298 void 299 ServerApp::SetCurrentCursor(ServerCursor* cursor) 300 { 301 fViewCursor.SetTo(cursor, false); 302 303 fDesktop->SetCursor(CurrentCursor()); 304 } 305 306 307 ServerCursor* 308 ServerApp::CurrentCursor() const 309 { 310 if (fViewCursor != NULL) 311 return fViewCursor; 312 313 return fAppCursor; 314 } 315 316 317 bool 318 ServerApp::AddWindow(ServerWindow* window) 319 { 320 BAutolock locker(fWindowListLock); 321 322 return fWindowList.AddItem(window); 323 } 324 325 326 void 327 ServerApp::RemoveWindow(ServerWindow* window) 328 { 329 BAutolock locker(fWindowListLock); 330 331 fWindowList.RemoveItem(window); 332 } 333 334 335 bool 336 ServerApp::InWorkspace(int32 index) const 337 { 338 BAutolock locker(fWindowListLock); 339 340 // we could cache this, but then we'd have to recompute the cached 341 // value everytime a window has closed or changed workspaces 342 343 // TODO: support initial application workspace! 344 345 for (int32 i = fWindowList.CountItems(); i-- > 0;) { 346 ServerWindow* serverWindow = fWindowList.ItemAt(i); 347 348 const Window* window = serverWindow->Window(); 349 if (window == NULL || window->IsOffscreenWindow()) 350 continue; 351 352 // only normal and unhidden windows count 353 354 if (window->IsNormal() && !window->IsHidden() 355 && window->InWorkspace(index)) 356 return true; 357 } 358 359 return false; 360 } 361 362 363 uint32 364 ServerApp::Workspaces() const 365 { 366 uint32 workspaces = 0; 367 368 BAutolock locker(fWindowListLock); 369 370 // we could cache this, but then we'd have to recompute the cached 371 // value everytime a window has closed or changed workspaces 372 373 for (int32 i = fWindowList.CountItems(); i-- > 0;) { 374 ServerWindow* serverWindow = fWindowList.ItemAt(i); 375 376 const Window* window = serverWindow->Window(); 377 if (window == NULL || window->IsOffscreenWindow()) 378 continue; 379 380 // only normal and unhidden windows count 381 382 if (window->IsNormal() && !window->IsHidden()) 383 workspaces |= window->Workspaces(); 384 } 385 386 // TODO: add initial application workspace! 387 return workspaces; 388 } 389 390 391 /*! \brief Acquires a reference of the desired bitmap, if available. 392 \param token ID token of the bitmap to find 393 \return The bitmap having that ID or NULL if not found 394 */ 395 ServerBitmap* 396 ServerApp::GetBitmap(int32 token) const 397 { 398 if (token < 1) 399 return NULL; 400 401 BAutolock _(fMapLocker); 402 403 ServerBitmap* bitmap = _FindBitmap(token); 404 if (bitmap == NULL) 405 return NULL; 406 407 bitmap->AcquireReference(); 408 409 return bitmap; 410 } 411 412 413 ServerPicture* 414 ServerApp::CreatePicture(const ServerPicture* original) 415 { 416 BReference<ServerPicture> picture; 417 if (original != NULL) 418 picture.SetTo(new(std::nothrow) ServerPicture(*original), true); 419 else 420 picture.SetTo(new(std::nothrow) ServerPicture(), true); 421 422 if (picture != NULL && !picture->SetOwner(this)) 423 return NULL; 424 425 return picture.Detach(); 426 } 427 428 429 ServerPicture* 430 ServerApp::GetPicture(int32 token) const 431 { 432 if (token < 1) 433 return NULL; 434 435 BAutolock _(fMapLocker); 436 437 ServerPicture* picture = _FindPicture(token); 438 if (picture == NULL) 439 return NULL; 440 441 picture->AcquireReference(); 442 443 return picture; 444 } 445 446 447 /*! To be called only by ServerPicture itself.*/ 448 bool 449 ServerApp::AddPicture(ServerPicture* picture) 450 { 451 BAutolock _(fMapLocker); 452 453 ASSERT(picture->Owner() == NULL); 454 455 try { 456 fPictureMap.insert(std::make_pair(picture->Token(), BReference<ServerPicture>(picture, false))); 457 } catch (std::bad_alloc& exception) { 458 return false; 459 } 460 461 return true; 462 } 463 464 465 /*! To be called only by ServerPicture itself.*/ 466 void 467 ServerApp::RemovePicture(ServerPicture* picture) 468 { 469 BAutolock _(fMapLocker); 470 471 ASSERT(picture->Owner() == this); 472 473 fPictureMap.erase(picture->Token()); 474 } 475 476 477 /*! Called from the ClientMemoryAllocator whenever a server area could be 478 deleted. 479 A message is then sent to the client telling it that it can delete its 480 client area, too. 481 */ 482 void 483 ServerApp::NotifyDeleteClientArea(area_id serverArea) 484 { 485 BMessage notify(kMsgDeleteServerMemoryArea); 486 notify.AddInt32("server area", serverArea); 487 488 SendMessageToClient(¬ify); 489 } 490 491 492 /*! \brief Send a message to the ServerApp's BApplication 493 \param message The message to send 494 */ 495 void 496 ServerApp::SendMessageToClient(BMessage* message) const 497 { 498 status_t status = fHandlerMessenger.SendMessage(message, (BHandler*)NULL, 499 100000); 500 if (status != B_OK) { 501 syslog(LOG_ERR, "app %s send to client failed: %s\n", Signature(), 502 strerror(status)); 503 } 504 } 505 506 507 // #pragma mark - private methods 508 509 510 void 511 ServerApp::_GetLooperName(char* name, size_t length) 512 { 513 snprintf(name, length, "a:%" B_PRId32 ":%s", ClientTeam(), SignatureLeaf()); 514 } 515 516 517 /*! \brief Handler function for BApplication API messages 518 \param code Identifier code for the message. Equivalent to BMessage::what 519 \param buffer Any attachments 520 521 Note that the buffer's exact format is determined by the particular message. 522 All attachments are placed in the buffer via a PortLink, so it will be a 523 matter of casting and incrementing an index variable to access them. 524 */ 525 void 526 ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) 527 { 528 switch (code) { 529 case AS_REGISTER_INPUT_SERVER: 530 { 531 EventStream* stream 532 = new(std::nothrow) InputServerStream(fHandlerMessenger); 533 if (stream != NULL 534 && (!stream->IsValid() || !gInputManager->AddStream(stream))) { 535 delete stream; 536 break; 537 } 538 539 // TODO: this should be done using notifications (so that an 540 // abandoned stream will get noticed directly) 541 if (fDesktop->EventDispatcher().InitCheck() != B_OK) 542 fDesktop->EventDispatcher().SetTo(gInputManager->GetStream()); 543 break; 544 } 545 546 case AS_APP_CRASHED: 547 // Allow the debugger to show its window: if needed, remove any 548 // kWindowScreenFeels from the windows of this application 549 if (fDesktop->LockAllWindows()) { 550 if (fWindowListLock.Lock()) { 551 for (int32 i = fWindowList.CountItems(); i-- > 0;) { 552 ServerWindow* serverWindow = fWindowList.ItemAt(i); 553 554 Window* window = serverWindow->Window(); 555 if (window == NULL || window->IsOffscreenWindow()) 556 continue; 557 558 if (window->Feel() == kWindowScreenFeel) 559 fDesktop->SetWindowFeel(window, B_NORMAL_WINDOW_FEEL); 560 } 561 562 fWindowListLock.Unlock(); 563 } 564 fDesktop->UnlockAllWindows(); 565 } 566 break; 567 568 case AS_DUMP_ALLOCATOR: 569 fMemoryAllocator->Dump(); 570 break; 571 case AS_DUMP_BITMAPS: 572 { 573 fMapLocker.Lock(); 574 575 debug_printf("Application %" B_PRId32 ", %s: %d bitmaps:\n", 576 ClientTeam(), Signature(), (int)fBitmapMap.size()); 577 578 BitmapMap::const_iterator iterator = fBitmapMap.begin(); 579 for (; iterator != fBitmapMap.end(); iterator++) { 580 ServerBitmap* bitmap = iterator->second; 581 debug_printf(" [%" B_PRId32 "] %" B_PRId32 "x%" B_PRId32 ", " 582 "area %" B_PRId32 ", size %" B_PRId32 "\n", 583 bitmap->Token(), bitmap->Width(), bitmap->Height(), 584 bitmap->Area(), bitmap->BitsLength()); 585 } 586 fMapLocker.Unlock(); 587 break; 588 } 589 590 case AS_CREATE_WINDOW: 591 case AS_CREATE_OFFSCREEN_WINDOW: 592 { 593 port_id clientReplyPort = -1; 594 status_t status = _CreateWindow(code, link, clientReplyPort); 595 596 // if sucessful, ServerWindow::Run() will already have replied 597 if (status < B_OK) { 598 // window creation failed, we need to notify the client 599 BPrivate::LinkSender reply(clientReplyPort); 600 reply.StartMessage(status); 601 reply.Flush(); 602 } 603 break; 604 } 605 606 case AS_GET_WINDOW_LIST: 607 { 608 team_id team; 609 if (link.Read<team_id>(&team) == B_OK) 610 fDesktop->WriteWindowList(team, fLink.Sender()); 611 break; 612 } 613 614 case AS_GET_WINDOW_INFO: 615 { 616 int32 serverToken; 617 if (link.Read<int32>(&serverToken) == B_OK) 618 fDesktop->WriteWindowInfo(serverToken, fLink.Sender()); 619 break; 620 } 621 622 case AS_GET_WINDOW_ORDER: 623 { 624 int32 workspace; 625 if (link.Read<int32>(&workspace) == B_OK) 626 fDesktop->WriteWindowOrder(workspace, fLink.Sender()); 627 break; 628 } 629 630 case AS_GET_APPLICATION_ORDER: 631 { 632 int32 workspace; 633 if (link.Read<int32>(&workspace) == B_OK) 634 fDesktop->WriteApplicationOrder(workspace, fLink.Sender()); 635 break; 636 } 637 638 case AS_MINIMIZE_TEAM: 639 { 640 team_id team; 641 if (link.Read<team_id>(&team) == B_OK) 642 fDesktop->MinimizeApplication(team); 643 break; 644 } 645 646 case AS_BRING_TEAM_TO_FRONT: 647 { 648 team_id team; 649 if (link.Read<team_id>(&team) == B_OK) 650 fDesktop->BringApplicationToFront(team); 651 break; 652 } 653 654 case AS_WINDOW_ACTION: 655 { 656 int32 token; 657 int32 action; 658 659 link.Read<int32>(&token); 660 if (link.Read<int32>(&action) != B_OK) 661 break; 662 663 fDesktop->WindowAction(token, action); 664 break; 665 } 666 667 // Decorator commands 668 669 case AS_SET_DECORATOR: 670 { 671 // Attached Data: 672 // path to decorator add-on 673 674 BString path; 675 link.ReadString(path); 676 677 status_t error = gDecorManager.SetDecorator(path, fDesktop); 678 679 fLink.Attach<status_t>(error); 680 fLink.Flush(); 681 682 if (error == B_OK) 683 fDesktop->BroadcastToAllApps(AS_UPDATE_DECORATOR); 684 break; 685 } 686 687 case AS_GET_DECORATOR: 688 { 689 fLink.StartMessage(B_OK); 690 fLink.AttachString(gDecorManager.GetCurrentDecorator().String()); 691 fLink.Flush(); 692 break; 693 } 694 695 case AS_SET_CONTROL_LOOK: 696 { 697 STRACE(("ServerApp %s: Set ControlLook\n", Signature())); 698 699 BString path; 700 status_t error = B_ERROR; 701 if (link.ReadString(path) == B_OK) { 702 LockedDesktopSettings settings(fDesktop); 703 error = settings.SetControlLook(path.String()); 704 } 705 706 fLink.StartMessage(error); 707 fLink.Flush(); 708 break; 709 } 710 711 case AS_GET_CONTROL_LOOK: 712 { 713 STRACE(("ServerApp %s: Get ControlLook\n", Signature())); 714 715 if (fDesktop->LockSingleWindow()) { 716 DesktopSettings settings(fDesktop); 717 718 fLink.StartMessage(B_OK); 719 fLink.AttachString(settings.ControlLook().String()); 720 fDesktop->UnlockSingleWindow(); 721 } else 722 fLink.StartMessage(B_ERROR); 723 724 fLink.Flush(); 725 break; 726 } 727 728 case AS_CREATE_BITMAP: 729 { 730 STRACE(("ServerApp %s: Received BBitmap creation request\n", 731 Signature())); 732 733 // Allocate a bitmap for an application 734 735 // Attached Data: 736 // 1) BRect bounds 737 // 2) color_space space 738 // 3) int32 bitmap_flags 739 // 4) int32 bytes_per_row 740 // 5) int32 screen_id 741 742 // Reply Data: 743 // 1) int32 server token 744 // 2) area_id id of the area in which the bitmap data resides 745 // 3) int32 area pointer offset used to calculate fBasePtr 746 747 // First, let's attempt to allocate the bitmap 748 BReference<ServerBitmap> bitmap; 749 uint8 allocationFlags = kAllocator; 750 751 BRect frame; 752 color_space colorSpace; 753 uint32 flags; 754 int32 bytesPerRow; 755 int32 screenID; 756 757 link.Read<BRect>(&frame); 758 link.Read<color_space>(&colorSpace); 759 link.Read<uint32>(&flags); 760 link.Read<int32>(&bytesPerRow); 761 if (link.Read<int32>(&screenID) == B_OK) { 762 // TODO: choose the right HWInterface with regards to the 763 // screenID 764 bitmap.SetTo(gBitmapManager->CreateBitmap(fMemoryAllocator, 765 *fDesktop->HWInterface(), frame, colorSpace, flags, 766 bytesPerRow, screenID, &allocationFlags), true); 767 } 768 769 STRACE(("ServerApp %s: Create Bitmap (%.1fx%.1f)\n", 770 Signature(), frame.Width() + 1, frame.Height() + 1)); 771 772 if (bitmap != NULL && _AddBitmap(bitmap)) { 773 fLink.StartMessage(B_OK); 774 fLink.Attach<int32>(bitmap->Token()); 775 fLink.Attach<uint8>(allocationFlags); 776 777 fLink.Attach<area_id>(bitmap->Area()); 778 fLink.Attach<int32>(bitmap->AreaOffset()); 779 780 if ((allocationFlags & kFramebuffer) != 0) 781 fLink.Attach<int32>(bitmap->BytesPerRow()); 782 } else { 783 fLink.StartMessage(B_NO_MEMORY); 784 } 785 786 fLink.Flush(); 787 break; 788 } 789 790 case AS_DELETE_BITMAP: 791 { 792 STRACE(("ServerApp %s: received BBitmap delete request\n", 793 Signature())); 794 795 // Attached Data: 796 // 1) int32 token 797 int32 token; 798 link.Read<int32>(&token); 799 800 fMapLocker.Lock(); 801 802 ServerBitmap* bitmap = _FindBitmap(token); 803 if (bitmap != NULL) { 804 STRACE(("ServerApp %s: Deleting Bitmap %" B_PRId32 "\n", 805 Signature(), token)); 806 807 _DeleteBitmap(bitmap); 808 } 809 810 fMapLocker.Unlock(); 811 break; 812 } 813 814 case AS_GET_BITMAP_OVERLAY_RESTRICTIONS: 815 { 816 overlay_restrictions restrictions; 817 status_t status = B_ERROR; 818 819 int32 token; 820 if (link.Read<int32>(&token) != B_OK) 821 break; 822 823 BReference<ServerBitmap> bitmap(GetBitmap(token), true); 824 if (bitmap != NULL) { 825 STRACE(("ServerApp %s: Get overlay restrictions for bitmap " 826 "%" B_PRId32 "\n", Signature(), token)); 827 828 status = fDesktop->HWInterface()->GetOverlayRestrictions( 829 bitmap->Overlay(), &restrictions); 830 } 831 832 fLink.StartMessage(status); 833 if (status == B_OK) 834 fLink.Attach(&restrictions, sizeof(overlay_restrictions)); 835 836 fLink.Flush(); 837 break; 838 } 839 840 case AS_GET_BITMAP_SUPPORT_FLAGS: 841 { 842 uint32 colorSpace; 843 if (link.Read<uint32>(&colorSpace) != B_OK) 844 break; 845 846 bool overlay = fDesktop->HWInterface()->CheckOverlayRestrictions( 847 64, 64, (color_space)colorSpace); 848 uint32 flags = overlay ? B_BITMAPS_SUPPORT_OVERLAY : 0; 849 850 fLink.StartMessage(B_OK); 851 fLink.Attach<int32>(flags); 852 fLink.Flush(); 853 break; 854 } 855 856 case AS_RECONNECT_BITMAP: 857 { 858 // First, let's attempt to allocate the bitmap 859 BReference<ServerBitmap> bitmap; 860 861 BRect frame; 862 color_space colorSpace; 863 uint32 flags; 864 int32 bytesPerRow; 865 int32 screenID; 866 area_id clientArea; 867 int32 areaOffset; 868 869 link.Read<BRect>(&frame); 870 link.Read<color_space>(&colorSpace); 871 link.Read<uint32>(&flags); 872 link.Read<int32>(&bytesPerRow); 873 link.Read<int32>(&screenID); 874 link.Read<int32>(&clientArea); 875 if (link.Read<int32>(&areaOffset) == B_OK) { 876 // TODO: choose the right HWInterface with regards to the 877 // screenID 878 bitmap.SetTo(gBitmapManager->CloneFromClient(clientArea, areaOffset, 879 frame, colorSpace, flags, bytesPerRow), true); 880 } 881 882 if (bitmap != NULL && _AddBitmap(bitmap)) { 883 fLink.StartMessage(B_OK); 884 fLink.Attach<int32>(bitmap->Token()); 885 886 fLink.Attach<area_id>(bitmap->Area()); 887 888 } else { 889 fLink.StartMessage(B_NO_MEMORY); 890 } 891 892 fLink.Flush(); 893 break; 894 } 895 896 // Picture ops 897 898 case AS_CREATE_PICTURE: 899 { 900 // TODO: Maybe rename this to AS_UPLOAD_PICTURE ? 901 STRACE(("ServerApp %s: Create Picture\n", Signature())); 902 status_t status = B_NO_MEMORY; 903 904 BReference<ServerPicture> picture(CreatePicture()); 905 if (picture != NULL) { 906 int32 subPicturesCount = 0; 907 link.Read<int32>(&subPicturesCount); 908 for (int32 i = 0; i < subPicturesCount; i++) { 909 int32 token = -1; 910 link.Read<int32>(&token); 911 912 BAutolock _(fMapLocker); 913 if (ServerPicture* subPicture = _FindPicture(token)) 914 picture->NestPicture(subPicture); 915 } 916 status = picture->ImportData(link); 917 } 918 if (status == B_OK) { 919 fLink.StartMessage(B_OK); 920 fLink.Attach<int32>(picture->Token()); 921 } else 922 fLink.StartMessage(status); 923 924 fLink.Flush(); 925 break; 926 } 927 928 case AS_DELETE_PICTURE: 929 { 930 STRACE(("ServerApp %s: Delete Picture\n", Signature())); 931 int32 token; 932 if (link.Read<int32>(&token) == B_OK) { 933 BAutolock _(fMapLocker); 934 935 ServerPicture* picture = _FindPicture(token); 936 if (picture != NULL) 937 picture->SetOwner(NULL); 938 } 939 break; 940 } 941 942 case AS_CLONE_PICTURE: 943 { 944 STRACE(("ServerApp %s: Clone Picture\n", Signature())); 945 int32 token; 946 BReference<ServerPicture> original; 947 if (link.Read<int32>(&token) == B_OK) 948 original.SetTo(GetPicture(token), true); 949 950 if (original != NULL) { 951 BReference<ServerPicture> cloned(CreatePicture(original), true); 952 if (cloned != NULL) { 953 fLink.StartMessage(B_OK); 954 fLink.Attach<int32>(cloned->Token()); 955 } else 956 fLink.StartMessage(B_NO_MEMORY); 957 } else 958 fLink.StartMessage(B_BAD_VALUE); 959 960 fLink.Flush(); 961 break; 962 } 963 964 case AS_DOWNLOAD_PICTURE: 965 { 966 STRACE(("ServerApp %s: Download Picture\n", Signature())); 967 int32 token; 968 link.Read<int32>(&token); 969 BReference<ServerPicture> picture(GetPicture(token), true); 970 if (picture != NULL) { 971 picture->ExportData(fLink); 972 // ExportData() calls StartMessage() already 973 } else 974 fLink.StartMessage(B_ERROR); 975 976 fLink.Flush(); 977 break; 978 } 979 980 case AS_CURRENT_WORKSPACE: 981 STRACE(("ServerApp %s: get current workspace\n", Signature())); 982 983 if (fDesktop->LockSingleWindow()) { 984 fLink.StartMessage(B_OK); 985 fLink.Attach<int32>(fDesktop->CurrentWorkspace()); 986 fDesktop->UnlockSingleWindow(); 987 } else 988 fLink.StartMessage(B_ERROR); 989 990 fLink.Flush(); 991 break; 992 993 case AS_ACTIVATE_WORKSPACE: 994 { 995 STRACE(("ServerApp %s: activate workspace\n", Signature())); 996 997 // TODO: See above 998 int32 index; 999 link.Read<int32>(&index); 1000 1001 bool takeFocusWindowThere; 1002 link.Read<bool>(&takeFocusWindowThere); 1003 1004 fDesktop->SetWorkspace(index, takeFocusWindowThere); 1005 break; 1006 } 1007 1008 case AS_SET_WORKSPACE_LAYOUT: 1009 { 1010 int32 newColumns; 1011 int32 newRows; 1012 if (link.Read<int32>(&newColumns) == B_OK 1013 && link.Read<int32>(&newRows) == B_OK) 1014 fDesktop->SetWorkspacesLayout(newColumns, newRows); 1015 break; 1016 } 1017 1018 case AS_GET_WORKSPACE_LAYOUT: 1019 { 1020 if (fDesktop->LockSingleWindow()) { 1021 DesktopSettings settings(fDesktop); 1022 1023 fLink.StartMessage(B_OK); 1024 fLink.Attach<int32>(settings.WorkspacesColumns()); 1025 fLink.Attach<int32>(settings.WorkspacesRows()); 1026 1027 fDesktop->UnlockSingleWindow(); 1028 } else 1029 fLink.StartMessage(B_ERROR); 1030 1031 fLink.Flush(); 1032 break; 1033 } 1034 1035 case AS_IDLE_TIME: 1036 STRACE(("ServerApp %s: idle time\n", Signature())); 1037 1038 fLink.StartMessage(B_OK); 1039 fLink.Attach<bigtime_t>(fDesktop->EventDispatcher().IdleTime()); 1040 fLink.Flush(); 1041 break; 1042 1043 case AS_SHOW_CURSOR: 1044 { 1045 STRACE(("ServerApp %s: Show Cursor\n", Signature())); 1046 fCursorHideLevel--; 1047 if (fCursorHideLevel < 0) 1048 fCursorHideLevel = 0; 1049 fDesktop->HWInterface()->SetCursorVisible(fCursorHideLevel == 0); 1050 break; 1051 } 1052 1053 case AS_HIDE_CURSOR: 1054 { 1055 STRACE(("ServerApp %s: Hide Cursor\n", Signature())); 1056 fCursorHideLevel++; 1057 fDesktop->HWInterface()->SetCursorVisible(fCursorHideLevel == 0); 1058 break; 1059 } 1060 1061 case AS_OBSCURE_CURSOR: 1062 { 1063 STRACE(("ServerApp %s: Obscure Cursor\n", Signature())); 1064 fDesktop->HWInterface()->ObscureCursor(); 1065 break; 1066 } 1067 1068 case AS_QUERY_CURSOR_HIDDEN: 1069 { 1070 STRACE(("ServerApp %s: Received IsCursorHidden request\n", 1071 Signature())); 1072 1073 fLink.StartMessage(fCursorHideLevel > 0 ? B_OK : B_ERROR); 1074 fLink.Flush(); 1075 break; 1076 } 1077 1078 case AS_SET_CURSOR: 1079 { 1080 STRACE(("ServerApp %s: SetCursor\n", Signature())); 1081 1082 // Attached data: 1083 // 1) bool flag to send a reply 1084 // 2) int32 token ID of the cursor to set 1085 // 3) port_id port to receive a reply. Only exists if the sync flag 1086 // is true. 1087 bool sync; 1088 int32 token; 1089 1090 link.Read<bool>(&sync); 1091 if (link.Read<int32>(&token) != B_OK) 1092 break; 1093 1094 if (!fDesktop->GetCursorManager().Lock()) 1095 break; 1096 1097 fAppCursor.SetTo(fDesktop->GetCursorManager().FindCursor(token), false); 1098 1099 if (_HasWindowUnderMouse()) 1100 fDesktop->SetCursor(CurrentCursor()); 1101 1102 fDesktop->GetCursorManager().Unlock(); 1103 1104 if (sync) { 1105 // The application is expecting a reply 1106 fLink.StartMessage(B_OK); 1107 fLink.Flush(); 1108 } 1109 break; 1110 } 1111 1112 case AS_SET_VIEW_CURSOR: 1113 { 1114 STRACE(("ServerApp %s: AS_SET_VIEW_CURSOR:\n", Signature())); 1115 1116 ViewSetViewCursorInfo info; 1117 if (link.Read<ViewSetViewCursorInfo>(&info) != B_OK) 1118 break; 1119 1120 if (fDesktop->GetCursorManager().Lock()) { 1121 BReference<ServerCursor> cursor(fDesktop->GetCursorManager().FindCursor( 1122 info.cursorToken), false); 1123 1124 fDesktop->GetCursorManager().Unlock(); 1125 1126 // We need to acquire the write lock here, since we cannot 1127 // afford that the window thread to which the view belongs 1128 // is running and messing with that same view. 1129 fDesktop->LockAllWindows(); 1130 1131 // Find the corresponding view by the given token. It's ok 1132 // if this view does not exist anymore, since it may have 1133 // already be deleted in the window thread before this 1134 // message got here. 1135 View* view; 1136 if (fViewTokens.GetToken(info.viewToken, B_HANDLER_TOKEN, 1137 (void**)&view) == B_OK) { 1138 // Set the cursor on the view. 1139 view->SetCursor(cursor); 1140 1141 // The cursor might need to be updated now. 1142 Window* window = view->Window(); 1143 if (window != NULL && window->IsFocus()) { 1144 if (fDesktop->ViewUnderMouse(window) == view->Token()) 1145 SetCurrentCursor(cursor); 1146 } 1147 } 1148 1149 fDesktop->UnlockAllWindows(); 1150 } 1151 1152 if (info.sync) { 1153 // sync the client (it can now delete the cursor) 1154 fLink.StartMessage(B_OK); 1155 fLink.Flush(); 1156 } 1157 break; 1158 } 1159 1160 case AS_CREATE_CURSOR: 1161 { 1162 STRACE(("ServerApp %s: Create Cursor\n", Signature())); 1163 1164 // Attached data: 1165 // 1) 68 bytes of fAppCursor data 1166 // 2) port_id reply port 1167 1168 status_t status = B_ERROR; 1169 uint8 cursorData[68]; 1170 ServerCursor* cursor = NULL; 1171 1172 // if (link.Read(cursorData, sizeof(cursorData)) >= B_OK) { 1173 // cursor = new (nothrow) ServerCursor(cursorData); 1174 // if (cursor == NULL) 1175 // status = B_NO_MEMORY; 1176 // } 1177 // 1178 // if (cursor != NULL) { 1179 // cursor->SetOwningTeam(fClientTeam); 1180 // fDesktop->GetCursorManager().AddCursor(cursor); 1181 // 1182 // // Synchronous message - BApplication is waiting on the cursor's ID 1183 // fLink.StartMessage(B_OK); 1184 // fLink.Attach<int32>(cursor->Token()); 1185 // } else 1186 // fLink.StartMessage(status); 1187 1188 if (link.Read(cursorData, sizeof(cursorData)) >= B_OK) { 1189 cursor = fDesktop->GetCursorManager().CreateCursor(fClientTeam, 1190 cursorData); 1191 if (cursor == NULL) 1192 status = B_NO_MEMORY; 1193 } 1194 1195 if (cursor != NULL) { 1196 // Synchronous message - BApplication is waiting on the 1197 // cursor's ID 1198 fLink.StartMessage(B_OK); 1199 fLink.Attach<int32>(cursor->Token()); 1200 } else 1201 fLink.StartMessage(status); 1202 1203 fLink.Flush(); 1204 break; 1205 } 1206 1207 case AS_CREATE_CURSOR_BITMAP: 1208 { 1209 STRACE(("ServerApp %s: Create Cursor bitmap\n", Signature())); 1210 1211 status_t status = B_ERROR; 1212 1213 int32 size = 0, bytesPerRow = 0; 1214 BRect cursorRect; 1215 color_space colorspace = B_RGBA32; 1216 BPoint hotspot; 1217 ServerCursor* cursor = NULL; 1218 1219 if (link.Read<BRect>(&cursorRect) == B_OK 1220 && link.Read<BPoint>(&hotspot) == B_OK 1221 && link.Read<color_space>(&colorspace) == B_OK 1222 && link.Read<int32>(&bytesPerRow) == B_OK 1223 && link.Read<int32>(&size) == B_OK 1224 && size > 0) { 1225 1226 BStackOrHeapArray<uint8, 256> byteArray(size); 1227 if (!byteArray.IsValid()) { 1228 status = B_NO_MEMORY; 1229 } else if (link.Read(byteArray, size) == B_OK) { 1230 cursor = fDesktop->GetCursorManager().CreateCursor( 1231 fClientTeam, cursorRect, colorspace, 0, hotspot); 1232 if (cursor == NULL) 1233 status = B_NO_MEMORY; 1234 else 1235 cursor->ImportBits(byteArray, size, bytesPerRow, colorspace); 1236 } 1237 } 1238 1239 if (cursor != NULL) { 1240 // Synchronous message - BApplication is waiting on the 1241 // cursor's ID 1242 fLink.StartMessage(B_OK); 1243 fLink.Attach<int32>(cursor->Token()); 1244 } else 1245 fLink.StartMessage(status); 1246 1247 fLink.Flush(); 1248 break; 1249 } 1250 1251 case AS_REFERENCE_CURSOR: 1252 { 1253 STRACE(("ServerApp %s: Reference BCursor\n", Signature())); 1254 1255 // Attached data: 1256 // 1) int32 token ID of the cursor to reference 1257 1258 int32 token; 1259 if (link.Read<int32>(&token) != B_OK) 1260 break; 1261 1262 if (!fDesktop->GetCursorManager().Lock()) 1263 break; 1264 1265 ServerCursor* cursor 1266 = fDesktop->GetCursorManager().FindCursor(token); 1267 if (cursor != NULL) 1268 cursor->AcquireReference(); 1269 1270 fDesktop->GetCursorManager().Unlock(); 1271 1272 break; 1273 } 1274 1275 case AS_DELETE_CURSOR: 1276 { 1277 STRACE(("ServerApp %s: Delete BCursor\n", Signature())); 1278 1279 // Attached data: 1280 // 1) int32 token ID of the cursor to delete 1281 1282 int32 token; 1283 if (link.Read<int32>(&token) != B_OK) 1284 break; 1285 1286 if (!fDesktop->GetCursorManager().Lock()) 1287 break; 1288 1289 ServerCursor* cursor 1290 = fDesktop->GetCursorManager().FindCursor(token); 1291 if (cursor != NULL) 1292 cursor->ReleaseReference(); 1293 1294 fDesktop->GetCursorManager().Unlock(); 1295 1296 break; 1297 } 1298 1299 case AS_GET_CURSOR_POSITION: 1300 { 1301 STRACE(("ServerApp %s: Get Cursor position\n", Signature())); 1302 1303 // Returns 1304 // 1) BPoint mouse location 1305 // 2) int32 button state 1306 1307 BPoint where; 1308 int32 buttons; 1309 fDesktop->GetLastMouseState(&where, &buttons); 1310 fLink.StartMessage(B_OK); 1311 fLink.Attach<BPoint>(where); 1312 fLink.Attach<int32>(buttons); 1313 fLink.Flush(); 1314 break; 1315 } 1316 1317 case AS_GET_CURSOR_BITMAP: 1318 { 1319 STRACE(("ServerApp %s: Get Cursor bitmap\n", Signature())); 1320 1321 // Returns 1322 // 1) uint32 number of data bytes of the bitmap 1323 // 2) uint32 cursor width in number of pixels 1324 // 3) uint32 cursor height in number of pixels 1325 // 4) BPoint cursor hot spot 1326 // 5) cursor bitmap data 1327 1328 ServerCursorReference cursorRef = fDesktop->Cursor(); 1329 ServerCursor* cursor = cursorRef.Get(); 1330 if (cursor != NULL) { 1331 uint32 size = cursor->BitsLength(); 1332 fLink.StartMessage(B_OK); 1333 fLink.Attach<uint32>(size); 1334 fLink.Attach<uint32>(cursor->Width()); 1335 fLink.Attach<uint32>(cursor->Height()); 1336 fLink.Attach<color_space>(cursor->ColorSpace()); 1337 fLink.Attach<BPoint>(cursor->GetHotSpot()); 1338 fLink.Attach(cursor->Bits(), size); 1339 } else 1340 fLink.StartMessage(B_ERROR); 1341 1342 fLink.Flush(); 1343 1344 break; 1345 } 1346 1347 case AS_GET_SCROLLBAR_INFO: 1348 { 1349 STRACE(("ServerApp %s: Get ScrollBar info\n", Signature())); 1350 1351 if (fDesktop->LockSingleWindow()) { 1352 scroll_bar_info info; 1353 DesktopSettings settings(fDesktop); 1354 settings.GetScrollBarInfo(info); 1355 1356 fLink.StartMessage(B_OK); 1357 fLink.Attach<scroll_bar_info>(info); 1358 fDesktop->UnlockSingleWindow(); 1359 } else 1360 fLink.StartMessage(B_ERROR); 1361 1362 fLink.Flush(); 1363 break; 1364 } 1365 1366 case AS_SET_SCROLLBAR_INFO: 1367 { 1368 STRACE(("ServerApp %s: Set ScrollBar info\n", Signature())); 1369 1370 // Attached Data: 1371 // 1) scroll_bar_info scroll bar info structure 1372 1373 scroll_bar_info info; 1374 if (link.Read<scroll_bar_info>(&info) == B_OK) { 1375 LockedDesktopSettings settings(fDesktop); 1376 settings.SetScrollBarInfo(info); 1377 } 1378 1379 fLink.StartMessage(B_OK); 1380 fLink.Flush(); 1381 break; 1382 } 1383 1384 case AS_GET_MENU_INFO: 1385 { 1386 STRACE(("ServerApp %s: Get menu info\n", Signature())); 1387 if (fDesktop->LockSingleWindow()) { 1388 menu_info info; 1389 DesktopSettings settings(fDesktop); 1390 settings.GetMenuInfo(info); 1391 1392 fLink.StartMessage(B_OK); 1393 fLink.Attach<menu_info>(info); 1394 1395 fDesktop->UnlockSingleWindow(); 1396 } else 1397 fLink.StartMessage(B_ERROR); 1398 1399 fLink.Flush(); 1400 break; 1401 } 1402 1403 case AS_SET_MENU_INFO: 1404 { 1405 STRACE(("ServerApp %s: Set menu info\n", Signature())); 1406 menu_info info; 1407 if (link.Read<menu_info>(&info) == B_OK) { 1408 LockedDesktopSettings settings(fDesktop); 1409 settings.SetMenuInfo(info); 1410 // TODO: SetMenuInfo() should do some validity check, so 1411 // that the answer we're giving can actually be useful 1412 } 1413 1414 fLink.StartMessage(B_OK); 1415 fLink.Flush(); 1416 break; 1417 } 1418 1419 case AS_SET_MOUSE_MODE: 1420 { 1421 STRACE(("ServerApp %s: Set Mouse Focus mode\n", 1422 Signature())); 1423 1424 // Attached Data: 1425 // 1) enum mode_mouse mouse focus mode 1426 1427 mode_mouse mouseMode; 1428 if (link.Read<mode_mouse>(&mouseMode) == B_OK) { 1429 LockedDesktopSettings settings(fDesktop); 1430 settings.SetMouseMode(mouseMode); 1431 } 1432 break; 1433 } 1434 1435 case AS_GET_MOUSE_MODE: 1436 { 1437 STRACE(("ServerApp %s: Get Mouse Focus mode\n", 1438 Signature())); 1439 1440 if (fDesktop->LockSingleWindow()) { 1441 DesktopSettings settings(fDesktop); 1442 1443 fLink.StartMessage(B_OK); 1444 fLink.Attach<mode_mouse>(settings.MouseMode()); 1445 1446 fDesktop->UnlockSingleWindow(); 1447 } else 1448 fLink.StartMessage(B_ERROR); 1449 1450 fLink.Flush(); 1451 break; 1452 } 1453 1454 case AS_SET_FOCUS_FOLLOWS_MOUSE_MODE: 1455 { 1456 STRACE(("ServerApp %s: Set Focus Follows Mouse mode\n", Signature())); 1457 1458 // Attached Data: 1459 // 1) enum mode_focus_follows_mouse FFM mouse mode 1460 1461 mode_focus_follows_mouse focusFollowsMousMode; 1462 if (link.Read<mode_focus_follows_mouse>(&focusFollowsMousMode) == B_OK) { 1463 LockedDesktopSettings settings(fDesktop); 1464 settings.SetFocusFollowsMouseMode(focusFollowsMousMode); 1465 } 1466 break; 1467 } 1468 1469 case AS_GET_FOCUS_FOLLOWS_MOUSE_MODE: 1470 { 1471 STRACE(("ServerApp %s: Get Focus Follows Mouse mode\n", Signature())); 1472 1473 if (fDesktop->LockSingleWindow()) { 1474 DesktopSettings settings(fDesktop); 1475 1476 fLink.StartMessage(B_OK); 1477 fLink.Attach<mode_focus_follows_mouse>( 1478 settings.FocusFollowsMouseMode()); 1479 1480 fDesktop->UnlockSingleWindow(); 1481 } else 1482 fLink.StartMessage(B_ERROR); 1483 1484 fLink.Flush(); 1485 break; 1486 } 1487 1488 case AS_SET_ACCEPT_FIRST_CLICK: 1489 { 1490 STRACE(("ServerApp %s: Set Accept First Click\n", Signature())); 1491 1492 // Attached Data: 1493 // 1) bool accept_first_click 1494 1495 bool acceptFirstClick; 1496 if (link.Read<bool>(&acceptFirstClick) == B_OK) { 1497 LockedDesktopSettings settings(fDesktop); 1498 settings.SetAcceptFirstClick(acceptFirstClick); 1499 } 1500 break; 1501 } 1502 1503 case AS_GET_ACCEPT_FIRST_CLICK: 1504 { 1505 STRACE(("ServerApp %s: Get Accept First Click\n", Signature())); 1506 1507 if (fDesktop->LockSingleWindow()) { 1508 DesktopSettings settings(fDesktop); 1509 1510 fLink.StartMessage(B_OK); 1511 fLink.Attach<bool>(settings.AcceptFirstClick()); 1512 1513 fDesktop->UnlockSingleWindow(); 1514 } else 1515 fLink.StartMessage(B_ERROR); 1516 1517 fLink.Flush(); 1518 break; 1519 } 1520 1521 case AS_GET_SHOW_ALL_DRAGGERS: 1522 { 1523 STRACE(("ServerApp %s: Get Show All Draggers\n", Signature())); 1524 1525 if (fDesktop->LockSingleWindow()) { 1526 DesktopSettings settings(fDesktop); 1527 1528 fLink.StartMessage(B_OK); 1529 fLink.Attach<bool>(settings.ShowAllDraggers()); 1530 1531 fDesktop->UnlockSingleWindow(); 1532 } else 1533 fLink.StartMessage(B_ERROR); 1534 1535 fLink.Flush(); 1536 break; 1537 } 1538 1539 case AS_SET_SHOW_ALL_DRAGGERS: 1540 { 1541 STRACE(("ServerApp %s: Set Show All Draggers\n", Signature())); 1542 1543 bool changed = false; 1544 bool show; 1545 if (link.Read<bool>(&show) == B_OK) { 1546 LockedDesktopSettings settings(fDesktop); 1547 if (show != settings.ShowAllDraggers()) { 1548 settings.SetShowAllDraggers(show); 1549 changed = true; 1550 } 1551 } 1552 1553 if (changed) 1554 fDesktop->BroadcastToAllApps(kMsgUpdateShowAllDraggers); 1555 break; 1556 } 1557 1558 case kMsgUpdateShowAllDraggers: 1559 { 1560 bool show = false; 1561 if (fDesktop->LockSingleWindow()) { 1562 DesktopSettings settings(fDesktop); 1563 show = settings.ShowAllDraggers(); 1564 fDesktop->UnlockSingleWindow(); 1565 } 1566 BMessage update(_SHOW_DRAG_HANDLES_); 1567 update.AddBool("show", show); 1568 1569 SendMessageToClient(&update); 1570 break; 1571 } 1572 1573 /* font messages */ 1574 1575 case AS_ADD_FONT_FILE: 1576 { 1577 FTRACE(("ServerApp %s: Received BFont creation request\n", 1578 Signature())); 1579 1580 // Add a font for an application from a file 1581 1582 // Attached Data: 1583 // 1) char* - path to font on disk 1584 1585 // Returns: 1586 // 1) uint16 - family ID of added font 1587 // 2) uint16 - style ID of added font 1588 // 3) uint16 - face of added font 1589 1590 AutoLocker< ::FontManager> fontLock(fAppFontManager); 1591 1592 if (fAppFontManager->CountFamilies() > MAX_USER_FONTS) { 1593 fLink.StartMessage(B_NOT_ALLOWED); 1594 fLink.Flush(); 1595 break; 1596 } 1597 1598 uint16 familyID, styleID; 1599 char* fontPath; 1600 link.ReadString(&fontPath); 1601 1602 status_t status = fAppFontManager->AddUserFontFromFile(fontPath, 1603 familyID, styleID); 1604 1605 if (status != B_OK) { 1606 fLink.StartMessage(status); 1607 } else { 1608 ServerFont font; 1609 status = font.SetFamilyAndStyle(familyID, styleID, 1610 fAppFontManager); 1611 1612 fLink.StartMessage(status); 1613 if (status == B_OK) { 1614 fLink.Attach<uint16>(font.FamilyID()); 1615 fLink.Attach<uint16>(font.StyleID()); 1616 fLink.Attach<uint16>(font.Face()); 1617 } 1618 } 1619 1620 fLink.Flush(); 1621 break; 1622 } 1623 1624 case AS_ADD_FONT_MEMORY: 1625 { 1626 FTRACE(("ServerApp %s: Received BFont memory creation request\n", 1627 Signature())); 1628 1629 // Add a font for an application from a memory area 1630 1631 // Attached Data: 1632 // 1) area_id - id of memory area where font resides 1633 // 2) size_t - size of memory area for font 1634 // 3) size_t - offset to start of font memory 1635 1636 // Returns: 1637 // 1) uint16 - family ID of added font 1638 // 2) uint16 - style ID of added font 1639 // 3) uint16 - face of added font 1640 1641 AutoLocker< ::FontManager> fontLock(fAppFontManager); 1642 1643 if (fAppFontManager->CountFamilies() > MAX_USER_FONTS) { 1644 fLink.StartMessage(B_NOT_ALLOWED); 1645 fLink.Flush(); 1646 break; 1647 } 1648 1649 area_id fontAreaID, fontAreaCloneID; 1650 area_info fontAreaInfo; 1651 char* area_addr; 1652 size_t size, offset; 1653 1654 link.Read<int32>(&fontAreaID); 1655 link.Read<size_t>(&size); 1656 link.Read<size_t>(&offset); 1657 fontAreaCloneID = clone_area("user font", 1658 (void **)&area_addr, 1659 B_ANY_ADDRESS, 1660 B_READ_AREA, 1661 fontAreaID); 1662 1663 if (fontAreaCloneID < B_OK) { 1664 fLink.StartMessage(fontAreaCloneID); 1665 fLink.Flush(); 1666 break; 1667 } 1668 1669 status_t status = get_area_info(fontAreaCloneID, &fontAreaInfo); 1670 if (status != B_OK) { 1671 fLink.StartMessage(status); 1672 fLink.Flush(); 1673 delete_area(fontAreaCloneID); 1674 break; 1675 } 1676 1677 size_t fontMemorySize = fontAreaInfo.size - offset; 1678 1679 if (size == 0) 1680 size = fontMemorySize; 1681 1682 // Check size of font area and reject if it's too large 1683 if (size > MAX_FONT_DATA_SIZE_BYTES 1684 || size > fontMemorySize) { 1685 fLink.StartMessage(B_BAD_DATA); 1686 fLink.Flush(); 1687 delete_area(fontAreaCloneID); 1688 break; 1689 } 1690 1691 FT_Byte* fontData = (FT_Byte*)(malloc (sizeof(FT_Byte) * size)); 1692 if (fontData == NULL) { 1693 delete_area(fontAreaCloneID); 1694 fLink.StartMessage(B_BAD_DATA); 1695 fLink.Flush(); 1696 break; 1697 } 1698 1699 memcpy(fontData, (FT_Byte*)fontAreaInfo.address + offset, size); 1700 1701 delete_area(fontAreaCloneID); 1702 1703 uint16 familyID, styleID; 1704 1705 status = fAppFontManager->AddUserFontFromMemory(fontData, size, 1706 familyID, styleID); 1707 1708 if (status != B_OK) { 1709 fLink.StartMessage(status); 1710 free(fontData); 1711 } else { 1712 ServerFont font; 1713 status = font.SetFamilyAndStyle(familyID, styleID, 1714 fAppFontManager); 1715 1716 if (status == B_OK) { 1717 font.SetFontData(fontData, size); 1718 fLink.StartMessage(B_OK); 1719 fLink.Attach<uint16>(font.FamilyID()); 1720 fLink.Attach<uint16>(font.StyleID()); 1721 fLink.Attach<uint16>(font.Face()); 1722 } else { 1723 fLink.StartMessage(status); 1724 free(fontData); 1725 } 1726 } 1727 1728 fLink.Flush(); 1729 break; 1730 } 1731 1732 case AS_REMOVE_FONT: 1733 { 1734 STRACE(("ServerApp %s: Received BFont removal request\n", 1735 Signature())); 1736 1737 // Remove an application-added font 1738 1739 // Attached Data: 1740 // 1) uint16 - familyID of font to remove 1741 // 2) uint16 - styleID of font to remove 1742 1743 uint16 familyID, styleID; 1744 link.Read<uint16>(&familyID); 1745 link.Read<uint16>(&styleID); 1746 1747 status_t status = B_OK; 1748 1749 AutoLocker< ::FontManager> fontLock(fAppFontManager); 1750 status = fAppFontManager->RemoveUserFont(familyID, styleID); 1751 1752 fLink.StartMessage(status); 1753 fLink.Flush(); 1754 break; 1755 } 1756 1757 case AS_SET_SYSTEM_FONT: 1758 { 1759 FTRACE(("ServerApp %s: AS_SET_SYSTEM_FONT\n", Signature())); 1760 // gets: 1761 // 1) string - font type ("plain", ...) 1762 // 2) string - family 1763 // 3) string - style 1764 // 4) float - size 1765 1766 char type[B_OS_NAME_LENGTH]; 1767 font_family familyName; 1768 font_style styleName; 1769 float size; 1770 1771 if (link.ReadString(type, sizeof(type)) == B_OK 1772 && link.ReadString(familyName, sizeof(familyName)) == B_OK 1773 && link.ReadString(styleName, sizeof(styleName)) == B_OK 1774 && link.Read<float>(&size) == B_OK) { 1775 gFontManager->Lock(); 1776 1777 FontStyle* style 1778 = gFontManager->GetStyle(familyName, styleName); 1779 if (style != NULL) { 1780 ServerFont font(*style, size); 1781 gFontManager->Unlock(); 1782 // We must not have locked the font manager when 1783 // locking the desktop (through LockedDesktopSettings 1784 // below) 1785 1786 LockedDesktopSettings settings(fDesktop); 1787 1788 // TODO: Should we also update our internal copies now? 1789 if (strcmp(type, "plain") == 0) 1790 settings.SetDefaultPlainFont(font); 1791 else if (strcmp(type, "bold") == 0) 1792 settings.SetDefaultBoldFont(font); 1793 else if (strcmp(type, "fixed") == 0) 1794 settings.SetDefaultFixedFont(font); 1795 } else 1796 gFontManager->Unlock(); 1797 } 1798 break; 1799 } 1800 1801 case AS_GET_SYSTEM_DEFAULT_FONT: 1802 { 1803 // input: 1804 // 1) string - font type ("plain", ...) 1805 1806 ServerFont font; 1807 1808 char type[B_OS_NAME_LENGTH]; 1809 status_t status = link.ReadString(type, sizeof(type)); 1810 if (status == B_OK) { 1811 if (strcmp(type, "plain") == 0) 1812 font = *gFontManager->DefaultPlainFont(); 1813 else if (strcmp(type, "bold") == 0) 1814 font = *gFontManager->DefaultBoldFont(); 1815 else if (strcmp(type, "fixed") == 0) 1816 font = *gFontManager->DefaultFixedFont(); 1817 else 1818 status = B_BAD_VALUE; 1819 } 1820 1821 if (status == B_OK) { 1822 // returns: 1823 // 1) string - family 1824 // 2) string - style 1825 // 3) float - size 1826 1827 fLink.StartMessage(B_OK); 1828 fLink.AttachString(font.Family()); 1829 fLink.AttachString(font.Style()); 1830 fLink.Attach<float>(font.Size()); 1831 } else 1832 fLink.StartMessage(status); 1833 1834 fLink.Flush(); 1835 break; 1836 } 1837 1838 case AS_GET_SYSTEM_FONTS: 1839 { 1840 FTRACE(("ServerApp %s: AS_GET_SYSTEM_FONTS\n", Signature())); 1841 // Returns: 1842 // 1) uint16 - family ID 1843 // 2) uint16 - style ID 1844 // 3) float - size in points 1845 // 4) uint16 - face flags 1846 // 5) uint32 - font flags 1847 1848 if (!fDesktop->LockSingleWindow()) { 1849 fLink.StartMessage(B_OK); 1850 fLink.Flush(); 1851 break; 1852 } 1853 1854 // The client is requesting the system fonts, this 1855 // could have happened either at application start up, 1856 // or because the client is resyncing with the global 1857 // fonts. So we record the current system wide fonts 1858 // into our own copies at this point. 1859 DesktopSettings settings(fDesktop); 1860 1861 settings.GetDefaultPlainFont(fPlainFont); 1862 settings.GetDefaultBoldFont(fBoldFont); 1863 settings.GetDefaultFixedFont(fFixedFont); 1864 1865 fLink.StartMessage(B_OK); 1866 1867 for (int32 i = 0; i < 3; i++) { 1868 ServerFont* font = NULL; 1869 switch (i) { 1870 case 0: 1871 font = &fPlainFont; 1872 fLink.AttachString("plain"); 1873 break; 1874 1875 case 1: 1876 font = &fBoldFont; 1877 fLink.AttachString("bold"); 1878 break; 1879 1880 case 2: 1881 font = &fFixedFont; 1882 fLink.AttachString("fixed"); 1883 break; 1884 } 1885 1886 fLink.Attach<uint16>(font->FamilyID()); 1887 fLink.Attach<uint16>(font->StyleID()); 1888 fLink.Attach<float>(font->Size()); 1889 fLink.Attach<uint16>(font->Face()); 1890 fLink.Attach<uint32>(font->Flags()); 1891 } 1892 1893 fDesktop->UnlockSingleWindow(); 1894 fLink.Flush(); 1895 break; 1896 } 1897 1898 case AS_GET_FONT_LIST_REVISION: 1899 { 1900 FTRACE(("ServerApp %s: AS_GET_FONT_LIST_REVISION\n", Signature())); 1901 1902 fLink.StartMessage(B_OK); 1903 fLink.Attach<int32>( 1904 gFontManager->CheckRevision(fDesktop->UserID())); 1905 fLink.Flush(); 1906 break; 1907 } 1908 1909 case AS_GET_FAMILY_AND_STYLES: 1910 { 1911 FTRACE(("ServerApp %s: AS_GET_FAMILY_AND_STYLES\n", Signature())); 1912 1913 // Attached Data: 1914 // 1) int32 the index of the font family to get 1915 1916 // Returns: 1917 // 1) string - name of family 1918 // 2) uint32 - flags of font family (B_IS_FIXED || B_HAS_TUNED_FONT) 1919 // 3) count of styles in that family 1920 // For each style: 1921 // 1) string - name of style 1922 // 2) uint16 - face of style 1923 // 3) uint32 - flags of style 1924 1925 int32 index; 1926 link.Read<int32>(&index); 1927 1928 AutoLocker< ::FontManager> fontLock(gFontManager); 1929 1930 FontFamily* family = gFontManager->FamilyAt(index); 1931 if (family == NULL) { 1932 fontLock.SetTo(fAppFontManager, false); 1933 1934 family = fAppFontManager->FamilyAt(index); 1935 } 1936 1937 if (family) { 1938 fLink.StartMessage(B_OK); 1939 fLink.AttachString(family->Name()); 1940 fLink.Attach<uint32>(family->Flags()); 1941 1942 int32 count = family->CountStyles(); 1943 1944 fLink.Attach<int32>(count); 1945 1946 for (int32 i = 0; i < count; i++) { 1947 FontStyle* style = family->StyleAt(i); 1948 1949 fLink.AttachString(style->Name()); 1950 fLink.Attach<uint16>(style->Face()); 1951 fLink.Attach<uint32>(style->Flags()); 1952 } 1953 } else 1954 fLink.StartMessage(B_BAD_VALUE); 1955 1956 1957 fLink.Flush(); 1958 break; 1959 } 1960 1961 case AS_GET_FAMILY_AND_STYLE: 1962 { 1963 FTRACE(("ServerApp %s: AS_GET_FAMILY_AND_STYLE\n", Signature())); 1964 1965 // Attached Data: 1966 // 1) uint16 - family ID 1967 // 2) uint16 - style ID 1968 1969 // Returns: 1970 // 1) font_family The name of the font family 1971 // 2) font_style - name of the style 1972 1973 uint16 familyID, styleID; 1974 link.Read<uint16>(&familyID); 1975 link.Read<uint16>(&styleID); 1976 1977 AutoLocker< ::FontManager> fontLock(gFontManager); 1978 1979 FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID); 1980 if (fontStyle == NULL) { 1981 fontLock.SetTo(fAppFontManager, false); 1982 1983 fontStyle = fAppFontManager->GetStyle(familyID, styleID); 1984 } 1985 1986 if (fontStyle != NULL) { 1987 fLink.StartMessage(B_OK); 1988 fLink.AttachString(fontStyle->Family()->Name()); 1989 fLink.AttachString(fontStyle->Name()); 1990 } else 1991 fLink.StartMessage(B_BAD_VALUE); 1992 1993 fLink.Flush(); 1994 1995 break; 1996 } 1997 1998 case AS_GET_FAMILY_AND_STYLE_IDS: 1999 { 2000 FTRACE(("ServerApp %s: AS_GET_FAMILY_AND_STYLE_IDS\n", 2001 Signature())); 2002 2003 // Attached Data: 2004 // 1) font_family - name of font family to use 2005 // 2) font_style - name of style in family 2006 // 3) family ID - only used if 1) is empty 2007 // 4) style ID - only used if 2) is empty 2008 // 5) face - the font's current face 2009 2010 // Returns: 2011 // 1) uint16 - family ID 2012 // 2) uint16 - style ID 2013 // 3) uint16 - face 2014 2015 font_family family; 2016 font_style style; 2017 uint16 familyID, styleID; 2018 uint16 face; 2019 if (link.ReadString(family, sizeof(font_family)) == B_OK 2020 && link.ReadString(style, sizeof(font_style)) == B_OK 2021 && link.Read<uint16>(&familyID) == B_OK 2022 && link.Read<uint16>(&styleID) == B_OK 2023 && link.Read<uint16>(&face) == B_OK) { 2024 // get the font and return IDs and face 2025 AutoLocker< ::FontManager> fontLock(gFontManager); 2026 2027 FontStyle* fontStyle = gFontManager->GetStyle(family, style, 2028 familyID, styleID, face); 2029 if (fontStyle == NULL) { 2030 fontLock.SetTo(fAppFontManager, false); 2031 2032 fontStyle = fAppFontManager->GetStyle(family, style, 2033 familyID, styleID, face); 2034 } 2035 2036 if (fontStyle != NULL) { 2037 fLink.StartMessage(B_OK); 2038 fLink.Attach<uint16>(fontStyle->Family()->ID()); 2039 fLink.Attach<uint16>(fontStyle->ID()); 2040 2041 // we try to keep the font face close to what we got 2042 face = fontStyle->PreservedFace(face); 2043 2044 fLink.Attach<uint16>(face); 2045 } else 2046 fLink.StartMessage(B_NAME_NOT_FOUND); 2047 } else 2048 fLink.StartMessage(B_BAD_VALUE); 2049 2050 fLink.Flush(); 2051 break; 2052 } 2053 2054 case AS_GET_FONT_FILE_FORMAT: 2055 { 2056 FTRACE(("ServerApp %s: AS_GET_FONT_FILE_FORMAT\n", Signature())); 2057 2058 // Attached Data: 2059 // 1) uint16 - family ID 2060 // 2) uint16 - style ID 2061 2062 // Returns: 2063 // 1) uint16 font_file_format of font 2064 2065 int32 familyID, styleID; 2066 link.Read<int32>(&familyID); 2067 link.Read<int32>(&styleID); 2068 2069 AutoLocker< ::FontManager> fontLock(gFontManager); 2070 2071 FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID); 2072 if (fontStyle == NULL) { 2073 fontLock.SetTo(fAppFontManager, false); 2074 2075 fontStyle = fAppFontManager->GetStyle(familyID, styleID); 2076 } 2077 2078 if (fontStyle != NULL) { 2079 fLink.StartMessage(B_OK); 2080 fLink.Attach<uint16>((uint16)fontStyle->FileFormat()); 2081 } else 2082 fLink.StartMessage(B_BAD_VALUE); 2083 2084 fLink.Flush(); 2085 break; 2086 } 2087 2088 case AS_GET_STRING_WIDTHS: 2089 { 2090 FTRACE(("ServerApp %s: AS_GET_STRING_WIDTHS\n", Signature())); 2091 2092 // Attached Data: 2093 // 1) uint16 ID of family 2094 // 2) uint16 ID of style 2095 // 3) float point size of font 2096 // 4) uint8 spacing to use 2097 // 5) int32 numStrings 2098 // 6) int32 string length to measure (numStrings times) 2099 // 7) string String to measure (numStrings times) 2100 2101 // Returns: 2102 // 1) float - width of the string in pixels (numStrings times) 2103 2104 uint16 familyID, styleID; 2105 float size; 2106 uint8 spacing; 2107 2108 link.Read<uint16>(&familyID); 2109 link.Read<uint16>(&styleID); 2110 link.Read<float>(&size); 2111 link.Read<uint8>(&spacing); 2112 int32 numStrings; 2113 if (link.Read<int32>(&numStrings) != B_OK) { 2114 // this results in a B_BAD_VALUE return 2115 numStrings = 0; 2116 size = 0.0f; 2117 } 2118 2119 BStackOrHeapArray<float, 64> widthArray(numStrings); 2120 BStackOrHeapArray<int32, 64> lengthArray(numStrings); 2121 BStackOrHeapArray<char*, 64> stringArray(numStrings); 2122 if (!widthArray.IsValid() || !lengthArray.IsValid() 2123 || !stringArray.IsValid()) { 2124 fLink.StartMessage(B_NO_MEMORY); 2125 fLink.Flush(); 2126 break; 2127 } 2128 2129 for (int32 i = 0; i < numStrings; i++) { 2130 // This version of ReadString allocates the strings, we free 2131 // them below 2132 link.ReadString(&stringArray[i], (size_t *)&lengthArray[i]); 2133 } 2134 2135 ServerFont font; 2136 2137 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2138 fAppFontManager); 2139 2140 if (status == B_OK && size > 0) { 2141 font.SetSize(size); 2142 font.SetSpacing(spacing); 2143 2144 for (int32 i = 0; i < numStrings; i++) { 2145 if (!stringArray[i] || lengthArray[i] <= 0) 2146 widthArray[i] = 0.0; 2147 else { 2148 widthArray[i] = font.StringWidth(stringArray[i], 2149 lengthArray[i]); 2150 } 2151 } 2152 2153 fLink.StartMessage(B_OK); 2154 fLink.Attach(widthArray, numStrings * sizeof(float)); 2155 } else 2156 fLink.StartMessage(B_BAD_VALUE); 2157 2158 fLink.Flush(); 2159 2160 for (int32 i = 0; i < numStrings; i++) 2161 free(stringArray[i]); 2162 break; 2163 } 2164 2165 case AS_GET_FONT_BOUNDING_BOX: 2166 { 2167 FTRACE(("ServerApp %s: AS_GET_BOUNDING_BOX\n", 2168 Signature())); 2169 2170 // Attached Data: 2171 // 1) uint16 - family ID 2172 // 2) uint16 - style ID 2173 // 3) float - font size 2174 2175 // Returns: 2176 // 1) BRect - box holding entire font 2177 2178 uint16 familyID, styleID; 2179 float size; 2180 2181 link.Read<uint16>(&familyID); 2182 link.Read<uint16>(&styleID); 2183 link.Read<float>(&size); 2184 2185 ServerFont font; 2186 2187 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2188 fAppFontManager); 2189 2190 if (status == B_OK && size > 0) { 2191 font.SetSize(size); 2192 2193 fLink.StartMessage(B_OK); 2194 fLink.Attach<BRect>(font.BoundingBox()); 2195 } else 2196 fLink.StartMessage(B_BAD_VALUE); 2197 2198 fLink.Flush(); 2199 break; 2200 } 2201 2202 case AS_GET_TUNED_COUNT: 2203 { 2204 FTRACE(("ServerApp %s: AS_GET_TUNED_COUNT\n", Signature())); 2205 2206 // Attached Data: 2207 // 1) uint16 - family ID 2208 // 2) uint16 - style ID 2209 2210 // Returns: 2211 // 1) int32 - number of font strikes available 2212 2213 uint16 familyID, styleID; 2214 link.Read<uint16>(&familyID); 2215 link.Read<uint16>(&styleID); 2216 2217 AutoLocker< ::FontManager> fontLock(gFontManager); 2218 2219 FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID); 2220 if (fontStyle == NULL) { 2221 fontLock.SetTo(fAppFontManager, false); 2222 2223 fontStyle = fAppFontManager->GetStyle(familyID, styleID); 2224 } 2225 2226 if (fontStyle != NULL) { 2227 fLink.StartMessage(B_OK); 2228 fLink.Attach<int32>(fontStyle->TunedCount()); 2229 } else 2230 fLink.StartMessage(B_BAD_VALUE); 2231 2232 fLink.Flush(); 2233 break; 2234 } 2235 2236 case AS_GET_TUNED_INFO: 2237 { 2238 FTRACE(("ServerApp %s: AS_GET_TUNED_INFO unimplmemented\n", 2239 Signature())); 2240 2241 // Attached Data: 2242 // 1) uint16 - family ID 2243 // 2) uint16 - style ID 2244 // 3) uint32 - index of the particular font strike 2245 2246 // Returns: 2247 // 1) tuned_font_info - info on the strike specified 2248 // ToDo: implement me! 2249 2250 fLink.StartMessage(B_ERROR); 2251 fLink.Flush(); 2252 break; 2253 } 2254 2255 case AS_GET_EXTRA_FONT_FLAGS: 2256 { 2257 FTRACE(("ServerApp %s: AS_GET_EXTRA_FONT_FLAGS\n", 2258 Signature())); 2259 2260 // Attached Data: 2261 // 1) uint16 - family ID 2262 // 2) uint16 - style ID 2263 2264 // Returns: 2265 // 1) uint32 - extra font flags 2266 2267 uint16 familyID, styleID; 2268 link.Read<uint16>(&familyID); 2269 link.Read<uint16>(&styleID); 2270 2271 AutoLocker< ::FontManager> fontLock(gFontManager); 2272 2273 FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID); 2274 if (fontStyle == NULL) { 2275 fontLock.SetTo(fAppFontManager, false); 2276 2277 fontStyle = fAppFontManager->GetStyle(familyID, styleID); 2278 } 2279 2280 if (fontStyle != NULL) { 2281 fLink.StartMessage(B_OK); 2282 fLink.Attach<uint32>(fontStyle->Flags()); 2283 } else 2284 fLink.StartMessage(B_BAD_VALUE); 2285 2286 fLink.Flush(); 2287 break; 2288 } 2289 2290 case AS_GET_FONT_HEIGHT: 2291 { 2292 FTRACE(("ServerApp %s: AS_GET_FONT_HEIGHT\n", Signature())); 2293 2294 // Attached Data: 2295 // 1) uint16 family ID 2296 // 2) uint16 style ID 2297 // 3) float size 2298 2299 uint16 familyID, styleID; 2300 float size; 2301 link.Read<uint16>(&familyID); 2302 link.Read<uint16>(&styleID); 2303 link.Read<float>(&size); 2304 2305 AutoLocker< ::FontManager> fontLock(gFontManager); 2306 2307 FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID); 2308 if (fontStyle == NULL) { 2309 fontLock.SetTo(fAppFontManager, false); 2310 2311 fontStyle = fAppFontManager->GetStyle(familyID, styleID); 2312 } 2313 2314 if (fontStyle != NULL) { 2315 font_height height; 2316 fontStyle->GetHeight(size, height); 2317 2318 fLink.StartMessage(B_OK); 2319 fLink.Attach<font_height>(height); 2320 } else 2321 fLink.StartMessage(B_BAD_VALUE); 2322 2323 fLink.Flush(); 2324 break; 2325 } 2326 2327 case AS_GET_UNICODE_BLOCKS: 2328 { 2329 FTRACE(("ServerApp %s: AS_GET_UNICODE_BLOCKS\n", Signature())); 2330 2331 // Attached Data: 2332 // 1) uint16 family ID 2333 // 2) uint16 style ID 2334 2335 // Returns: 2336 // 1) unicode_block - bitfield of Unicode blocks in font 2337 2338 uint16 familyID, styleID; 2339 link.Read<uint16>(&familyID); 2340 link.Read<uint16>(&styleID); 2341 2342 ServerFont font; 2343 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2344 fAppFontManager); 2345 2346 if (status == B_OK) { 2347 unicode_block blocksForFont; 2348 font.GetUnicodeBlocks(blocksForFont); 2349 2350 fLink.StartMessage(B_OK); 2351 fLink.Attach<unicode_block>(blocksForFont); 2352 } else 2353 fLink.StartMessage(status); 2354 2355 fLink.Flush(); 2356 break; 2357 } 2358 2359 case AS_GET_HAS_UNICODE_BLOCK: 2360 { 2361 FTRACE(("ServerApp %s: AS_INCLUDES_UNICODE_BLOCK\n", Signature())); 2362 2363 // Attached Data: 2364 // 1) uint16 family ID 2365 // 2) uint16 style ID 2366 // 3) uint32 start of unicode block 2367 // 4) uint32 end of unicode block 2368 2369 // Returns: 2370 // 1) bool - whether or not font includes specified block range 2371 2372 uint16 familyID, styleID; 2373 uint32 start, end; 2374 link.Read<uint16>(&familyID); 2375 link.Read<uint16>(&styleID); 2376 link.Read<uint32>(&start); 2377 link.Read<uint32>(&end); 2378 2379 ServerFont font; 2380 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2381 fAppFontManager); 2382 2383 if (status == B_OK) { 2384 bool hasBlock; 2385 2386 status = font.IncludesUnicodeBlock(start, end, hasBlock); 2387 fLink.StartMessage(status); 2388 fLink.Attach<bool>(hasBlock); 2389 } else 2390 fLink.StartMessage(status); 2391 2392 fLink.Flush(); 2393 break; 2394 } 2395 2396 case AS_GET_GLYPH_SHAPES: 2397 { 2398 FTRACE(("ServerApp %s: AS_GET_GLYPH_SHAPES\n", Signature())); 2399 2400 // Attached Data: 2401 // 1) uint16 - family ID 2402 // 2) uint16 - style ID 2403 // 3) float - point size 2404 // 4) float - shear 2405 // 5) float - rotation 2406 // 6) float - false bold width 2407 // 6) uint32 - flags 2408 // 7) int32 - numChars 2409 // 8) int32 - numBytes 2410 // 8) char - chars (numBytes times) 2411 2412 // Returns: 2413 // 1) BShape - glyph shape 2414 // numChars times 2415 2416 uint16 familyID, styleID; 2417 uint32 flags; 2418 float size, shear, rotation, falseBoldWidth; 2419 2420 link.Read<uint16>(&familyID); 2421 link.Read<uint16>(&styleID); 2422 link.Read<float>(&size); 2423 link.Read<float>(&shear); 2424 link.Read<float>(&rotation); 2425 link.Read<float>(&falseBoldWidth); 2426 link.Read<uint32>(&flags); 2427 2428 int32 numChars, numBytes; 2429 link.Read<int32>(&numChars); 2430 link.Read<int32>(&numBytes); 2431 2432 BStackOrHeapArray<char, 256> charArray(numBytes); 2433 BStackOrHeapArray<BShape*, 64> shapes(numChars); 2434 if (!charArray.IsValid() || !shapes.IsValid()) { 2435 fLink.StartMessage(B_NO_MEMORY); 2436 fLink.Flush(); 2437 break; 2438 } 2439 2440 link.Read(charArray, numBytes); 2441 2442 ServerFont font; 2443 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2444 fAppFontManager); 2445 2446 if (status == B_OK) { 2447 font.SetSize(size); 2448 font.SetShear(shear); 2449 font.SetRotation(rotation); 2450 font.SetFalseBoldWidth(falseBoldWidth); 2451 font.SetFlags(flags); 2452 2453 status = font.GetGlyphShapes(charArray, numChars, shapes); 2454 if (status == B_OK) { 2455 fLink.StartMessage(B_OK); 2456 for (int32 i = 0; i < numChars; i++) { 2457 fLink.AttachShape(*shapes[i]); 2458 delete shapes[i]; 2459 } 2460 } 2461 } 2462 2463 if (status != B_OK) 2464 fLink.StartMessage(status); 2465 2466 fLink.Flush(); 2467 break; 2468 } 2469 2470 case AS_GET_HAS_GLYPHS: 2471 { 2472 FTRACE(("ServerApp %s: AS_GET_HAS_GLYPHS\n", Signature())); 2473 2474 // Attached Data: 2475 // 1) uint16 - family ID 2476 // 2) uint16 - style ID 2477 // 3) int32 - numChars 2478 // 4) int32 - numBytes 2479 // 5) char - the char buffer with size numBytes 2480 2481 uint16 familyID, styleID; 2482 link.Read<uint16>(&familyID); 2483 link.Read<uint16>(&styleID); 2484 2485 int32 numChars, numBytes; 2486 link.Read<int32>(&numChars); 2487 link.Read<int32>(&numBytes); 2488 2489 BStackOrHeapArray<char, 256> charArray(numBytes); 2490 BStackOrHeapArray<bool, 256> hasArray(numChars); 2491 if (!charArray.IsValid() || !hasArray.IsValid()) { 2492 fLink.StartMessage(B_NO_MEMORY); 2493 fLink.Flush(); 2494 break; 2495 } 2496 2497 link.Read(charArray, numBytes); 2498 2499 ServerFont font; 2500 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2501 fAppFontManager); 2502 2503 if (status == B_OK) { 2504 status = font.GetHasGlyphs(charArray, numBytes, numChars, 2505 hasArray); 2506 if (status == B_OK) { 2507 fLink.StartMessage(B_OK); 2508 fLink.Attach(hasArray, numChars * sizeof(bool)); 2509 } 2510 } 2511 2512 if (status != B_OK) 2513 fLink.StartMessage(status); 2514 2515 fLink.Flush(); 2516 break; 2517 } 2518 2519 case AS_GET_EDGES: 2520 { 2521 FTRACE(("ServerApp %s: AS_GET_EDGES\n", Signature())); 2522 2523 // Attached Data: 2524 // 1) uint16 - family ID 2525 // 2) uint16 - style ID 2526 // 3) int32 - numChars 2527 // 4) int32 - numBytes 2528 // 5) char - the char buffer with size numBytes 2529 2530 uint16 familyID, styleID; 2531 link.Read<uint16>(&familyID); 2532 link.Read<uint16>(&styleID); 2533 2534 int32 numChars; 2535 link.Read<int32>(&numChars); 2536 2537 uint32 numBytes; 2538 link.Read<uint32>(&numBytes); 2539 2540 BStackOrHeapArray<char, 256> charArray(numBytes); 2541 BStackOrHeapArray<edge_info, 64> edgeArray(numChars); 2542 if (!charArray.IsValid() || !edgeArray.IsValid()) { 2543 fLink.StartMessage(B_NO_MEMORY); 2544 fLink.Flush(); 2545 break; 2546 } 2547 2548 link.Read(charArray, numBytes); 2549 2550 ServerFont font; 2551 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2552 fAppFontManager); 2553 2554 if (status == B_OK) { 2555 status = font.GetEdges(charArray, numBytes, numChars, 2556 edgeArray); 2557 if (status == B_OK) { 2558 fLink.StartMessage(B_OK); 2559 fLink.Attach(edgeArray, numChars * sizeof(edge_info)); 2560 } 2561 } 2562 2563 if (status != B_OK) 2564 fLink.StartMessage(status); 2565 2566 fLink.Flush(); 2567 break; 2568 } 2569 2570 case AS_GET_ESCAPEMENTS: 2571 { 2572 FTRACE(("ServerApp %s: AS_GET_ESCAPEMENTS\n", Signature())); 2573 2574 // Attached Data: 2575 // 1) uint16 - family ID 2576 // 2) uint16 - style ID 2577 // 3) float - point size 2578 // 4) uint8 - spacing 2579 // 5) float - rotation 2580 // 6) uint32 - flags 2581 // 7) int32 - numChars 2582 // 8) char - char -\ both 2583 // 9) BPoint - offset -/ (numChars times) 2584 2585 // Returns: 2586 // 1) BPoint - escapement 2587 // numChars times 2588 2589 uint16 familyID, styleID; 2590 uint32 flags; 2591 float size, rotation; 2592 uint8 spacing; 2593 2594 link.Read<uint16>(&familyID); 2595 link.Read<uint16>(&styleID); 2596 link.Read<float>(&size); 2597 link.Read<uint8>(&spacing); 2598 link.Read<float>(&rotation); 2599 link.Read<uint32>(&flags); 2600 2601 escapement_delta delta; 2602 link.Read<float>(&delta.nonspace); 2603 link.Read<float>(&delta.space); 2604 2605 bool wantsOffsets; 2606 link.Read<bool>(&wantsOffsets); 2607 2608 int32 numChars; 2609 link.Read<int32>(&numChars); 2610 2611 uint32 numBytes; 2612 link.Read<uint32>(&numBytes); 2613 2614 BStackOrHeapArray<char, 256> charArray(numBytes); 2615 BStackOrHeapArray<BPoint, 64> escapements(numChars); 2616 BPoint* offsets = NULL; 2617 if (wantsOffsets) 2618 offsets = new(std::nothrow) BPoint[numChars]; 2619 2620 if (!charArray.IsValid() || !escapements.IsValid() 2621 || (offsets == NULL && wantsOffsets)) { 2622 delete[] offsets; 2623 fLink.StartMessage(B_NO_MEMORY); 2624 fLink.Flush(); 2625 break; 2626 } 2627 2628 link.Read(charArray, numBytes); 2629 2630 ServerFont font; 2631 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2632 fAppFontManager); 2633 2634 if (status == B_OK) { 2635 font.SetSize(size); 2636 font.SetSpacing(spacing); 2637 font.SetRotation(rotation); 2638 font.SetFlags(flags); 2639 2640 status = font.GetEscapements(charArray, numBytes, numChars, 2641 delta, escapements, offsets); 2642 2643 if (status == B_OK) { 2644 fLink.StartMessage(B_OK); 2645 for (int32 i = 0; i < numChars; i++) 2646 fLink.Attach<BPoint>(escapements[i]); 2647 2648 if (wantsOffsets) { 2649 for (int32 i = 0; i < numChars; i++) 2650 fLink.Attach<BPoint>(offsets[i]); 2651 } 2652 } 2653 } 2654 2655 if (status != B_OK) 2656 fLink.StartMessage(status); 2657 2658 delete[] offsets; 2659 fLink.Flush(); 2660 break; 2661 } 2662 2663 case AS_GET_ESCAPEMENTS_AS_FLOATS: 2664 { 2665 FTRACE(("ServerApp %s: AS_GET_ESCAPEMENTS_AS_FLOATS\n", Signature())); 2666 2667 // Attached Data: 2668 // 1) uint16 - family ID 2669 // 2) uint16 - style ID 2670 // 3) float - point size 2671 // 4) uint8 - spacing 2672 // 5) float - rotation 2673 // 6) uint32 - flags 2674 // 7) float - additional "nonspace" delta 2675 // 8) float - additional "space" delta 2676 // 9) int32 - numChars 2677 // 10) int32 - numBytes 2678 // 11) char - the char buffer with size numBytes 2679 2680 // Returns: 2681 // 1) float - escapement buffer with numChar entries 2682 2683 uint16 familyID, styleID; 2684 uint32 flags; 2685 float size, rotation; 2686 uint8 spacing; 2687 2688 link.Read<uint16>(&familyID); 2689 link.Read<uint16>(&styleID); 2690 link.Read<float>(&size); 2691 link.Read<uint8>(&spacing); 2692 link.Read<float>(&rotation); 2693 link.Read<uint32>(&flags); 2694 2695 escapement_delta delta; 2696 link.Read<float>(&delta.nonspace); 2697 link.Read<float>(&delta.space); 2698 2699 int32 numChars; 2700 link.Read<int32>(&numChars); 2701 2702 uint32 numBytes; 2703 link.Read<uint32>(&numBytes); 2704 2705 BStackOrHeapArray<char, 256> charArray(numBytes); 2706 BStackOrHeapArray<float, 64> escapements(numChars); 2707 if (!charArray.IsValid() || !escapements.IsValid()) { 2708 fLink.StartMessage(B_NO_MEMORY); 2709 fLink.Flush(); 2710 break; 2711 } 2712 2713 link.Read(charArray, numBytes); 2714 2715 // figure out escapements 2716 2717 ServerFont font; 2718 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2719 fAppFontManager); 2720 2721 if (status == B_OK) { 2722 font.SetSize(size); 2723 font.SetSpacing(spacing); 2724 font.SetRotation(rotation); 2725 font.SetFlags(flags); 2726 2727 status = font.GetEscapements(charArray, numBytes, numChars, 2728 delta, escapements); 2729 2730 if (status == B_OK) { 2731 fLink.StartMessage(B_OK); 2732 fLink.Attach(escapements, numChars * sizeof(float)); 2733 } 2734 } 2735 2736 if (status != B_OK) 2737 fLink.StartMessage(status); 2738 2739 fLink.Flush(); 2740 break; 2741 } 2742 2743 case AS_GET_BOUNDINGBOXES_CHARS: 2744 case AS_GET_BOUNDINGBOXES_STRING: 2745 { 2746 FTRACE(("ServerApp %s: AS_GET_BOUNDINGBOXES_CHARS\n", Signature())); 2747 2748 // Attached Data: 2749 // 1) uint16 - family ID 2750 // 2) uint16 - style ID 2751 // 3) float - point size 2752 // 4) float - rotation 2753 // 5) float - shear 2754 // 6) float - false bold width 2755 // 7) uint8 - spacing 2756 // 8) uint32 - flags 2757 // 9) font_metric_mode - mode 2758 // 10) bool - string escapement 2759 // 11) escapement_delta - additional delta 2760 // 12) int32 - numChars 2761 // 13) int32 - numBytes 2762 // 14) char - the char buffer with size numBytes 2763 2764 // Returns: 2765 // 1) BRect - rects with numChar entries 2766 2767 uint16 familyID, styleID; 2768 uint32 flags; 2769 float size, rotation, shear, falseBoldWidth; 2770 uint8 spacing; 2771 font_metric_mode mode; 2772 bool stringEscapement; 2773 2774 link.Read<uint16>(&familyID); 2775 link.Read<uint16>(&styleID); 2776 link.Read<float>(&size); 2777 link.Read<float>(&rotation); 2778 link.Read<float>(&shear); 2779 link.Read<float>(&falseBoldWidth); 2780 link.Read<uint8>(&spacing); 2781 link.Read<uint32>(&flags); 2782 link.Read<font_metric_mode>(&mode); 2783 link.Read<bool>(&stringEscapement); 2784 2785 escapement_delta delta; 2786 link.Read<escapement_delta>(&delta); 2787 2788 int32 numChars; 2789 link.Read<int32>(&numChars); 2790 2791 uint32 numBytes; 2792 link.Read<uint32>(&numBytes); 2793 2794 BStackOrHeapArray<char, 256> charArray(numBytes); 2795 BStackOrHeapArray<BRect, 64> rectArray(numChars); 2796 if (!charArray.IsValid() || !rectArray.IsValid()) { 2797 fLink.StartMessage(B_NO_MEMORY); 2798 fLink.Flush(); 2799 break; 2800 } 2801 2802 link.Read(charArray, numBytes); 2803 2804 // figure out escapements 2805 2806 ServerFont font; 2807 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2808 fAppFontManager); 2809 2810 if (status == B_OK) { 2811 font.SetSize(size); 2812 font.SetRotation(rotation); 2813 font.SetShear(shear); 2814 font.SetFalseBoldWidth(falseBoldWidth); 2815 font.SetSpacing(spacing); 2816 font.SetFlags(flags); 2817 2818 // TODO: implement for real 2819 status = font.GetBoundingBoxes(charArray, numBytes, 2820 numChars, rectArray, stringEscapement, mode, delta, 2821 code == AS_GET_BOUNDINGBOXES_STRING); 2822 if (status == B_OK) { 2823 fLink.StartMessage(B_OK); 2824 for (int32 i = 0; i < numChars; i++) 2825 fLink.Attach<BRect>(rectArray[i]); 2826 } 2827 } 2828 2829 if (status != B_OK) 2830 fLink.StartMessage(status); 2831 2832 fLink.Flush(); 2833 break; 2834 } 2835 2836 case AS_GET_BOUNDINGBOXES_STRINGS: 2837 { 2838 FTRACE(("ServerApp %s: AS_GET_BOUNDINGBOXES_STRINGS\n", 2839 Signature())); 2840 2841 // Attached Data: 2842 // 1) uint16 - family ID 2843 // 2) uint16 - style ID 2844 // 3) float - point size 2845 // 4) float - rotation 2846 // 5) float - shear 2847 // 6) float - false bold width 2848 // 7) uint8 - spacing 2849 // 8) uint32 - flags 2850 // 9) font_metric_mode - mode 2851 // 10) int32 numStrings 2852 // 11) escapement_delta - additional delta (numStrings times) 2853 // 12) int32 string length to measure (numStrings times) 2854 // 13) string - string (numStrings times) 2855 2856 // Returns: 2857 // 1) BRect - rects with numStrings entries 2858 2859 uint16 familyID, styleID; 2860 uint32 flags; 2861 float ptsize, rotation, shear, falseBoldWidth; 2862 uint8 spacing; 2863 font_metric_mode mode; 2864 2865 link.Read<uint16>(&familyID); 2866 link.Read<uint16>(&styleID); 2867 link.Read<float>(&ptsize); 2868 link.Read<float>(&rotation); 2869 link.Read<float>(&shear); 2870 link.Read<float>(&falseBoldWidth); 2871 link.Read<uint8>(&spacing); 2872 link.Read<uint32>(&flags); 2873 link.Read<font_metric_mode>(&mode); 2874 2875 int32 numStrings; 2876 link.Read<int32>(&numStrings); 2877 2878 BStackOrHeapArray<escapement_delta, 64> deltaArray(numStrings); 2879 BStackOrHeapArray<char*, 64> stringArray(numStrings); 2880 BStackOrHeapArray<size_t, 64> lengthArray(numStrings); 2881 BStackOrHeapArray<BRect, 64> rectArray(numStrings); 2882 if (!deltaArray.IsValid() || !stringArray.IsValid() 2883 || !lengthArray.IsValid() || !rectArray.IsValid()) { 2884 fLink.StartMessage(B_NO_MEMORY); 2885 fLink.Flush(); 2886 break; 2887 } 2888 2889 for (int32 i = 0; i < numStrings; i++) { 2890 // This version of ReadString allocates the strings, we free 2891 // them below 2892 link.ReadString(&stringArray[i], &lengthArray[i]); 2893 link.Read<escapement_delta>(&deltaArray[i]); 2894 } 2895 2896 ServerFont font; 2897 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2898 fAppFontManager); 2899 2900 if (status == B_OK) { 2901 font.SetSize(ptsize); 2902 font.SetRotation(rotation); 2903 font.SetShear(shear); 2904 font.SetFalseBoldWidth(falseBoldWidth); 2905 font.SetSpacing(spacing); 2906 font.SetFlags(flags); 2907 2908 status = font.GetBoundingBoxesForStrings(stringArray, 2909 lengthArray, numStrings, rectArray, mode, deltaArray); 2910 if (status == B_OK) { 2911 fLink.StartMessage(B_OK); 2912 fLink.Attach(rectArray, numStrings * sizeof(BRect)); 2913 } 2914 } 2915 2916 for (int32 i = 0; i < numStrings; i++) 2917 free(stringArray[i]); 2918 2919 if (status != B_OK) 2920 fLink.StartMessage(status); 2921 2922 fLink.Flush(); 2923 break; 2924 } 2925 2926 // Screen commands 2927 2928 case AS_VALID_SCREEN_ID: 2929 { 2930 // Attached data 2931 // 1) int32 screen 2932 2933 int32 id; 2934 if (link.Read<int32>(&id) == B_OK 2935 && id == B_MAIN_SCREEN_ID.id) 2936 fLink.StartMessage(B_OK); 2937 else 2938 fLink.StartMessage(B_ERROR); 2939 2940 fLink.Flush(); 2941 break; 2942 } 2943 2944 case AS_GET_NEXT_SCREEN_ID: 2945 { 2946 // Attached data 2947 // 1) int32 screen 2948 2949 int32 id; 2950 link.Read<int32>(&id); 2951 2952 // TODO: for now, just say we're the last one 2953 fLink.StartMessage(B_ENTRY_NOT_FOUND); 2954 fLink.Flush(); 2955 break; 2956 } 2957 2958 case AS_GET_SCREEN_ID_FROM_WINDOW: 2959 { 2960 status_t status = B_BAD_VALUE; 2961 2962 // Attached data 2963 // 1) int32 - window client token 2964 2965 int32 clientToken; 2966 if (link.Read<int32>(&clientToken) != B_OK) 2967 status = B_BAD_DATA; 2968 else { 2969 BAutolock locker(fWindowListLock); 2970 2971 for (int32 i = fWindowList.CountItems(); i-- > 0;) { 2972 ServerWindow* serverWindow = fWindowList.ItemAt(i); 2973 2974 if (serverWindow->ClientToken() == clientToken) { 2975 AutoReadLocker _(fDesktop->ScreenLocker()); 2976 2977 // found it! 2978 Window* window = serverWindow->Window(); 2979 const Screen* screen = NULL; 2980 if (window != NULL) 2981 screen = window->Screen(); 2982 2983 if (screen == NULL) { 2984 // The window hasn't been added to the desktop yet, 2985 // or it's an offscreen window 2986 break; 2987 } 2988 2989 fLink.StartMessage(B_OK); 2990 fLink.Attach<int32>(screen->ID()); 2991 status = B_OK; 2992 break; 2993 } 2994 } 2995 } 2996 2997 if (status != B_OK) 2998 fLink.StartMessage(status); 2999 fLink.Flush(); 3000 break; 3001 } 3002 3003 case AS_SCREEN_GET_MODE: 3004 { 3005 STRACE(("ServerApp %s: AS_SCREEN_GET_MODE\n", Signature())); 3006 3007 // Attached data 3008 // 1) int32 screen 3009 // 2) uint32 workspace index 3010 3011 int32 id; 3012 link.Read<int32>(&id); 3013 uint32 workspace; 3014 link.Read<uint32>(&workspace); 3015 3016 display_mode mode; 3017 status_t status = fDesktop->GetScreenMode(workspace, id, mode); 3018 3019 fLink.StartMessage(status); 3020 if (status == B_OK) 3021 fLink.Attach<display_mode>(mode); 3022 fLink.Flush(); 3023 break; 3024 } 3025 3026 case AS_SCREEN_SET_MODE: 3027 { 3028 STRACE(("ServerApp %s: AS_SCREEN_SET_MODE\n", Signature())); 3029 3030 // Attached data 3031 // 1) int32 screen 3032 // 2) workspace index 3033 // 3) display_mode to set 3034 // 4) 'makeDefault' boolean 3035 3036 int32 id; 3037 link.Read<int32>(&id); 3038 uint32 workspace; 3039 link.Read<uint32>(&workspace); 3040 3041 display_mode mode; 3042 link.Read<display_mode>(&mode); 3043 3044 bool makeDefault = false; 3045 status_t status = link.Read<bool>(&makeDefault); 3046 3047 if (status == B_OK) { 3048 status = fDesktop->SetScreenMode(workspace, id, mode, 3049 makeDefault); 3050 } 3051 if (status == B_OK) { 3052 if (workspace == (uint32)B_CURRENT_WORKSPACE_INDEX 3053 && fDesktop->LockSingleWindow()) { 3054 workspace = fDesktop->CurrentWorkspace(); 3055 fDesktop->UnlockSingleWindow(); 3056 } 3057 3058 if (!makeDefault) { 3059 // Memorize the screen change, so that it can be reverted 3060 // later 3061 fTemporaryDisplayModeChange |= 1 << workspace; 3062 } else 3063 fTemporaryDisplayModeChange &= ~(1 << workspace); 3064 } 3065 3066 fLink.StartMessage(status); 3067 fLink.Flush(); 3068 break; 3069 } 3070 3071 case AS_PROPOSE_MODE: 3072 { 3073 STRACE(("ServerApp %s: AS_PROPOSE_MODE\n", Signature())); 3074 int32 id; 3075 link.Read<int32>(&id); 3076 3077 display_mode target, low, high; 3078 link.Read<display_mode>(&target); 3079 link.Read<display_mode>(&low); 3080 link.Read<display_mode>(&high); 3081 status_t status = fDesktop->HWInterface()->ProposeMode(&target, 3082 &low, &high); 3083 3084 // ProposeMode() returns B_BAD_VALUE to hint that the candidate is 3085 // not within the given limits (but is supported) 3086 if (status == B_OK || status == B_BAD_VALUE) { 3087 fLink.StartMessage(B_OK); 3088 fLink.Attach<display_mode>(target); 3089 fLink.Attach<bool>(status == B_OK); 3090 } else 3091 fLink.StartMessage(status); 3092 3093 fLink.Flush(); 3094 break; 3095 } 3096 3097 case AS_GET_MODE_LIST: 3098 { 3099 int32 id; 3100 link.Read<int32>(&id); 3101 // TODO: use this screen id 3102 3103 display_mode* modeList; 3104 uint32 count; 3105 status_t status = fDesktop->HWInterface()->GetModeList(&modeList, 3106 &count); 3107 if (status == B_OK) { 3108 fLink.StartMessage(B_OK); 3109 fLink.Attach<uint32>(count); 3110 fLink.Attach(modeList, sizeof(display_mode) * count); 3111 3112 delete[] modeList; 3113 } else 3114 fLink.StartMessage(status); 3115 3116 fLink.Flush(); 3117 break; 3118 } 3119 3120 case AS_GET_SCREEN_FRAME: 3121 { 3122 STRACE(("ServerApp %s: AS_GET_SCREEN_FRAME\n", Signature())); 3123 3124 // Attached data 3125 // 1) int32 screen 3126 // 2) uint32 workspace index 3127 3128 int32 id; 3129 link.Read<int32>(&id); 3130 uint32 workspace; 3131 link.Read<uint32>(&workspace); 3132 3133 BRect frame; 3134 status_t status = fDesktop->GetScreenFrame(workspace, id, frame); 3135 3136 fLink.StartMessage(status); 3137 if (status == B_OK) 3138 fLink.Attach<BRect>(frame); 3139 3140 fLink.Flush(); 3141 break; 3142 } 3143 3144 case AS_SCREEN_GET_COLORMAP: 3145 { 3146 STRACE(("ServerApp %s: AS_SCREEN_GET_COLORMAP\n", Signature())); 3147 3148 int32 id; 3149 link.Read<int32>(&id); 3150 3151 const color_map* colorMap = SystemColorMap(); 3152 if (colorMap != NULL) { 3153 fLink.StartMessage(B_OK); 3154 fLink.Attach<color_map>(*colorMap); 3155 } else 3156 fLink.StartMessage(B_ERROR); 3157 3158 fLink.Flush(); 3159 break; 3160 } 3161 3162 case AS_GET_DESKTOP_COLOR: 3163 { 3164 STRACE(("ServerApp %s: get desktop color\n", Signature())); 3165 3166 uint32 index; 3167 link.Read<uint32>(&index); 3168 3169 fLink.StartMessage(B_OK); 3170 fDesktop->LockSingleWindow(); 3171 3172 // we're nice to our children (and also take the default case 3173 // into account which asks for the current workspace) 3174 if (index >= (uint32)kMaxWorkspaces) 3175 index = fDesktop->CurrentWorkspace(); 3176 3177 Workspace workspace(*fDesktop, index, true); 3178 fLink.Attach<rgb_color>(workspace.Color()); 3179 3180 fDesktop->UnlockSingleWindow(); 3181 fLink.Flush(); 3182 break; 3183 } 3184 3185 case AS_SET_DESKTOP_COLOR: 3186 { 3187 STRACE(("ServerApp %s: set desktop color\n", Signature())); 3188 3189 rgb_color color; 3190 uint32 index; 3191 bool makeDefault; 3192 3193 link.Read<rgb_color>(&color); 3194 link.Read<uint32>(&index); 3195 if (link.Read<bool>(&makeDefault) != B_OK) 3196 break; 3197 3198 fDesktop->LockAllWindows(); 3199 3200 // we're nice to our children (and also take the default case 3201 // into account which asks for the current workspace) 3202 if (index >= (uint32)kMaxWorkspaces) 3203 index = fDesktop->CurrentWorkspace(); 3204 3205 Workspace workspace(*fDesktop, index); 3206 workspace.SetColor(color, makeDefault); 3207 3208 fDesktop->UnlockAllWindows(); 3209 break; 3210 } 3211 3212 case AS_GET_ACCELERANT_INFO: 3213 { 3214 STRACE(("ServerApp %s: get accelerant info\n", Signature())); 3215 3216 // We aren't using the screen_id for now... 3217 int32 id; 3218 link.Read<int32>(&id); 3219 3220 accelerant_device_info accelerantInfo; 3221 // TODO: I wonder if there should be a "desktop" lock... 3222 status_t status 3223 = fDesktop->HWInterface()->GetDeviceInfo(&accelerantInfo); 3224 if (status == B_OK) { 3225 fLink.StartMessage(B_OK); 3226 fLink.Attach<accelerant_device_info>(accelerantInfo); 3227 } else 3228 fLink.StartMessage(status); 3229 3230 fLink.Flush(); 3231 break; 3232 } 3233 3234 case AS_GET_MONITOR_INFO: 3235 { 3236 STRACE(("ServerApp %s: get monitor info\n", Signature())); 3237 3238 // We aren't using the screen_id for now... 3239 int32 id; 3240 link.Read<int32>(&id); 3241 3242 monitor_info info; 3243 // TODO: I wonder if there should be a "desktop" lock... 3244 status_t status = fDesktop->HWInterface()->GetMonitorInfo(&info); 3245 if (status == B_OK) { 3246 fLink.StartMessage(B_OK); 3247 fLink.Attach<monitor_info>(info); 3248 } else 3249 fLink.StartMessage(status); 3250 3251 fLink.Flush(); 3252 break; 3253 } 3254 3255 case AS_GET_FRAME_BUFFER_CONFIG: 3256 { 3257 STRACE(("ServerApp %s: get frame buffer config\n", Signature())); 3258 3259 // We aren't using the screen_id for now... 3260 int32 id; 3261 link.Read<int32>(&id); 3262 3263 frame_buffer_config config; 3264 // TODO: I wonder if there should be a "desktop" lock... 3265 status_t status = fDesktop->HWInterface()->GetFrameBufferConfig(config); 3266 if (status == B_OK) { 3267 fLink.StartMessage(B_OK); 3268 fLink.Attach<frame_buffer_config>(config); 3269 } else 3270 fLink.StartMessage(status); 3271 3272 fLink.Flush(); 3273 break; 3274 } 3275 3276 case AS_GET_RETRACE_SEMAPHORE: 3277 { 3278 STRACE(("ServerApp %s: get retrace semaphore\n", Signature())); 3279 3280 // We aren't using the screen_id for now... 3281 int32 id; 3282 link.Read<int32>(&id); 3283 3284 fLink.StartMessage(B_OK); 3285 fLink.Attach<sem_id>(fDesktop->HWInterface()->RetraceSemaphore()); 3286 fLink.Flush(); 3287 break; 3288 } 3289 3290 case AS_GET_TIMING_CONSTRAINTS: 3291 { 3292 STRACE(("ServerApp %s: get timing constraints\n", Signature())); 3293 3294 // We aren't using the screen_id for now... 3295 int32 id; 3296 link.Read<int32>(&id); 3297 3298 display_timing_constraints constraints; 3299 status_t status = fDesktop->HWInterface()->GetTimingConstraints( 3300 &constraints); 3301 if (status == B_OK) { 3302 fLink.StartMessage(B_OK); 3303 fLink.Attach<display_timing_constraints>(constraints); 3304 } else 3305 fLink.StartMessage(status); 3306 3307 fLink.Flush(); 3308 break; 3309 } 3310 3311 case AS_GET_PIXEL_CLOCK_LIMITS: 3312 { 3313 STRACE(("ServerApp %s: get pixel clock limits\n", Signature())); 3314 // We aren't using the screen_id for now... 3315 int32 id; 3316 link.Read<int32>(&id); 3317 display_mode mode; 3318 link.Read<display_mode>(&mode); 3319 3320 uint32 low, high; 3321 status_t status = fDesktop->HWInterface()->GetPixelClockLimits(&mode, 3322 &low, &high); 3323 if (status == B_OK) { 3324 fLink.StartMessage(B_OK); 3325 fLink.Attach<uint32>(low); 3326 fLink.Attach<uint32>(high); 3327 } else 3328 fLink.StartMessage(status); 3329 3330 fLink.Flush(); 3331 break; 3332 } 3333 3334 case AS_SET_DPMS: 3335 { 3336 STRACE(("ServerApp %s: AS_SET_DPMS\n", Signature())); 3337 int32 id; 3338 link.Read<int32>(&id); 3339 3340 uint32 mode; 3341 link.Read<uint32>(&mode); 3342 3343 status_t status = fDesktop->HWInterface()->SetDPMSMode(mode); 3344 fLink.StartMessage(status); 3345 3346 fLink.Flush(); 3347 break; 3348 } 3349 3350 case AS_GET_DPMS_STATE: 3351 { 3352 STRACE(("ServerApp %s: AS_GET_DPMS_STATE\n", Signature())); 3353 3354 int32 id; 3355 link.Read<int32>(&id); 3356 3357 uint32 state = fDesktop->HWInterface()->DPMSMode(); 3358 fLink.StartMessage(B_OK); 3359 fLink.Attach<uint32>(state); 3360 fLink.Flush(); 3361 break; 3362 } 3363 3364 case AS_GET_DPMS_CAPABILITIES: 3365 { 3366 STRACE(("ServerApp %s: AS_GET_DPMS_CAPABILITIES\n", Signature())); 3367 int32 id; 3368 link.Read<int32>(&id); 3369 3370 uint32 capabilities = fDesktop->HWInterface()->DPMSCapabilities(); 3371 fLink.StartMessage(B_OK); 3372 fLink.Attach<uint32>(capabilities); 3373 fLink.Flush(); 3374 break; 3375 } 3376 3377 case AS_SCREEN_SET_BRIGHTNESS: 3378 { 3379 STRACE(("ServerApp %s: AS_SCREEN_SET_BRIGHTNESS\n", Signature())); 3380 int32 id; 3381 link.Read<int32>(&id); 3382 3383 float brightness; 3384 link.Read<float>(&brightness); 3385 3386 status_t status = fDesktop->SetBrightness(id, brightness); 3387 fLink.StartMessage(status); 3388 3389 fLink.Flush(); 3390 break; 3391 } 3392 3393 case AS_SCREEN_GET_BRIGHTNESS: 3394 { 3395 STRACE(("ServerApp %s: AS_SCREEN_GET_BRIGHTNESS\n", Signature())); 3396 int32 id; 3397 link.Read<int32>(&id); 3398 3399 float brightness; 3400 status_t result = fDesktop->HWInterface()->GetBrightness(&brightness); 3401 fLink.StartMessage(result); 3402 if (result == B_OK) 3403 fLink.Attach<float>(brightness); 3404 fLink.Flush(); 3405 break; 3406 } 3407 3408 case AS_READ_BITMAP: 3409 { 3410 STRACE(("ServerApp %s: AS_READ_BITMAP\n", Signature())); 3411 int32 token; 3412 link.Read<int32>(&token); 3413 3414 bool drawCursor = true; 3415 link.Read<bool>(&drawCursor); 3416 3417 BRect bounds; 3418 link.Read<BRect>(&bounds); 3419 3420 bool success = false; 3421 3422 BReference<ServerBitmap> bitmap(GetBitmap(token), true); 3423 if (bitmap != NULL) { 3424 if (fDesktop->GetDrawingEngine()->LockExclusiveAccess()) { 3425 success = fDesktop->GetDrawingEngine()->ReadBitmap(bitmap, 3426 drawCursor, bounds) == B_OK; 3427 fDesktop->GetDrawingEngine()->UnlockExclusiveAccess(); 3428 } 3429 } 3430 3431 if (success) 3432 fLink.StartMessage(B_OK); 3433 else 3434 fLink.StartMessage(B_BAD_VALUE); 3435 3436 fLink.Flush(); 3437 break; 3438 } 3439 3440 case AS_GET_ACCELERANT_PATH: 3441 { 3442 int32 id; 3443 fLink.Read<int32>(&id); 3444 3445 BString path; 3446 status_t status = fDesktop->HWInterface()->GetAccelerantPath(path); 3447 fLink.StartMessage(status); 3448 if (status == B_OK) 3449 fLink.AttachString(path.String()); 3450 3451 fLink.Flush(); 3452 break; 3453 } 3454 3455 case AS_GET_DRIVER_PATH: 3456 { 3457 int32 id; 3458 fLink.Read<int32>(&id); 3459 3460 BString path; 3461 status_t status = fDesktop->HWInterface()->GetDriverPath(path); 3462 fLink.StartMessage(status); 3463 if (status == B_OK) 3464 fLink.AttachString(path.String()); 3465 3466 fLink.Flush(); 3467 break; 3468 } 3469 3470 // BWindowScreen communication 3471 3472 case AS_DIRECT_SCREEN_LOCK: 3473 { 3474 bool lock; 3475 link.Read<bool>(&lock); 3476 3477 status_t status; 3478 if (lock) 3479 status = fDesktop->LockDirectScreen(ClientTeam()); 3480 else 3481 status = fDesktop->UnlockDirectScreen(ClientTeam()); 3482 3483 fLink.StartMessage(status); 3484 fLink.Flush(); 3485 break; 3486 } 3487 3488 // Hinting and aliasing 3489 3490 case AS_SET_SUBPIXEL_ANTIALIASING: 3491 { 3492 bool subpix; 3493 if (link.Read<bool>(&subpix) == B_OK) { 3494 LockedDesktopSettings settings(fDesktop); 3495 settings.SetSubpixelAntialiasing(subpix); 3496 } 3497 fDesktop->Redraw(); 3498 break; 3499 } 3500 3501 case AS_GET_SUBPIXEL_ANTIALIASING: 3502 { 3503 DesktopSettings settings(fDesktop); 3504 fLink.StartMessage(B_OK); 3505 fLink.Attach<bool>(settings.SubpixelAntialiasing()); 3506 fLink.Flush(); 3507 break; 3508 } 3509 3510 case AS_SET_HINTING: 3511 { 3512 uint8 hinting; 3513 if (link.Read<uint8>(&hinting) == B_OK && hinting < 3) { 3514 LockedDesktopSettings settings(fDesktop); 3515 if (hinting != settings.Hinting()) { 3516 settings.SetHinting(hinting); 3517 fDesktop->Redraw(); 3518 } 3519 } 3520 break; 3521 } 3522 3523 case AS_GET_HINTING: 3524 { 3525 DesktopSettings settings(fDesktop); 3526 fLink.StartMessage(B_OK); 3527 fLink.Attach<uint8>(settings.Hinting()); 3528 fLink.Flush(); 3529 break; 3530 } 3531 3532 case AS_SET_SUBPIXEL_AVERAGE_WEIGHT: 3533 { 3534 uint8 averageWeight; 3535 if (link.Read<uint8>(&averageWeight) == B_OK) { 3536 LockedDesktopSettings settings(fDesktop); 3537 settings.SetSubpixelAverageWeight(averageWeight); 3538 } 3539 fDesktop->Redraw(); 3540 break; 3541 } 3542 3543 case AS_GET_SUBPIXEL_AVERAGE_WEIGHT: 3544 { 3545 DesktopSettings settings(fDesktop); 3546 fLink.StartMessage(B_OK); 3547 fLink.Attach<uint8>(settings.SubpixelAverageWeight()); 3548 fLink.Flush(); 3549 break; 3550 } 3551 3552 case AS_SET_SUBPIXEL_ORDERING: 3553 { 3554 bool subpixelOrdering; 3555 if (link.Read<bool>(&subpixelOrdering) == B_OK) { 3556 LockedDesktopSettings settings(fDesktop); 3557 settings.SetSubpixelOrderingRegular(subpixelOrdering); 3558 } 3559 fDesktop->Redraw(); 3560 break; 3561 } 3562 3563 case AS_GET_SUBPIXEL_ORDERING: 3564 { 3565 DesktopSettings settings(fDesktop); 3566 fLink.StartMessage(B_OK); 3567 fLink.Attach<bool>(settings.IsSubpixelOrderingRegular()); 3568 fLink.Flush(); 3569 break; 3570 } 3571 3572 default: 3573 printf("ServerApp %s received unhandled message code %" B_PRId32 3574 "\n", Signature(), code); 3575 3576 if (link.NeedsReply()) { 3577 // the client is now blocking and waiting for a reply! 3578 fLink.StartMessage(B_ERROR); 3579 fLink.Flush(); 3580 } else 3581 puts("message doesn't need a reply!"); 3582 break; 3583 } 3584 } 3585 3586 3587 /*! \brief The thread function ServerApps use to monitor messages 3588 */ 3589 void 3590 ServerApp::_MessageLooper() 3591 { 3592 // Message-dispatching loop for the ServerApp 3593 3594 // get our own team ID 3595 thread_info threadInfo; 3596 get_thread_info(fThread, &threadInfo); 3597 3598 // First let's tell the client how to talk with us. 3599 fLink.StartMessage(B_OK); 3600 fLink.Attach<port_id>(fMessagePort); 3601 fLink.Attach<area_id>(fDesktop->SharedReadOnlyArea()); 3602 fLink.Attach<team_id>(threadInfo.team); 3603 fLink.Flush(); 3604 3605 BPrivate::LinkReceiver &receiver = fLink.Receiver(); 3606 3607 int32 code; 3608 status_t err = B_OK; 3609 3610 while (!fQuitting) { 3611 STRACE(("info: ServerApp::_MessageLooper() listening on port %" B_PRId32 3612 ".\n", fMessagePort)); 3613 3614 err = receiver.GetNextMessage(code); 3615 if (err != B_OK || code == B_QUIT_REQUESTED) { 3616 STRACE(("ServerApp: application seems to be gone...\n")); 3617 3618 // Tell desktop to quit us 3619 BPrivate::LinkSender link(fDesktop->MessagePort()); 3620 link.StartMessage(AS_DELETE_APP); 3621 link.Attach<thread_id>(Thread()); 3622 link.Flush(); 3623 break; 3624 } 3625 3626 switch (code) { 3627 case kMsgAppQuit: 3628 // we receive this from our destructor on quit 3629 fQuitting = true; 3630 break; 3631 3632 case AS_QUIT_APP: 3633 { 3634 // This message is received only when the app_server is asked 3635 // to shut down in test/debug mode. Of course, if we are testing 3636 // while using AccelerantDriver, we do NOT want to shut down 3637 // client applications. The server can be quit in this fashion 3638 // through the driver's interface, such as closing the 3639 // ViewDriver's window. 3640 3641 STRACE(("ServerApp %s:Server shutdown notification received\n", 3642 Signature())); 3643 3644 // If we are using the real, accelerated version of the 3645 // DrawingEngine, we do NOT want the user to be able shut down 3646 // the server. The results would NOT be pretty 3647 #if TEST_MODE 3648 BMessage pleaseQuit(B_QUIT_REQUESTED); 3649 SendMessageToClient(&pleaseQuit); 3650 #endif 3651 break; 3652 } 3653 3654 default: 3655 STRACE(("ServerApp %s: Got a Message to dispatch\n", 3656 Signature())); 3657 _DispatchMessage(code, receiver); 3658 break; 3659 } 3660 } 3661 3662 // Quit() will send us a message; we're handling the exiting procedure 3663 thread_id sender; 3664 sem_id shutdownSemaphore; 3665 receive_data(&sender, &shutdownSemaphore, sizeof(sem_id)); 3666 3667 delete this; 3668 3669 if (shutdownSemaphore >= B_OK) 3670 release_sem(shutdownSemaphore); 3671 } 3672 3673 3674 status_t 3675 ServerApp::_CreateWindow(int32 code, BPrivate::LinkReceiver& link, 3676 port_id& clientReplyPort) 3677 { 3678 // Attached data: 3679 // 1) int32 bitmap token (only for AS_CREATE_OFFSCREEN_WINDOW) 3680 // 2) BRect window frame 3681 // 3) uint32 window look 3682 // 4) uint32 window feel 3683 // 5) uint32 window flags 3684 // 6) uint32 workspace index 3685 // 7) int32 BHandler token of the window 3686 // 8) port_id window's reply port 3687 // 9) port_id window's looper port 3688 // 10) const char * title 3689 3690 BRect frame; 3691 int32 bitmapToken; 3692 uint32 look; 3693 uint32 feel; 3694 uint32 flags; 3695 uint32 workspaces; 3696 int32 token; 3697 port_id looperPort; 3698 char* title; 3699 3700 if (code == AS_CREATE_OFFSCREEN_WINDOW) 3701 link.Read<int32>(&bitmapToken); 3702 3703 link.Read<BRect>(&frame); 3704 link.Read<uint32>(&look); 3705 link.Read<uint32>(&feel); 3706 link.Read<uint32>(&flags); 3707 link.Read<uint32>(&workspaces); 3708 link.Read<int32>(&token); 3709 link.Read<port_id>(&clientReplyPort); 3710 link.Read<port_id>(&looperPort); 3711 if (link.ReadString(&title) != B_OK) 3712 return B_ERROR; 3713 3714 if (!frame.IsValid()) { 3715 // make sure we pass a valid rectangle to ServerWindow 3716 frame.right = frame.left + 1; 3717 frame.bottom = frame.top + 1; 3718 } 3719 3720 status_t status = B_NO_MEMORY; 3721 ServerWindow *window = NULL; 3722 3723 if (code == AS_CREATE_OFFSCREEN_WINDOW) { 3724 ServerBitmap* bitmap = GetBitmap(bitmapToken); 3725 3726 if (bitmap != NULL) { 3727 window = new (nothrow) OffscreenServerWindow(title, this, 3728 clientReplyPort, looperPort, token, bitmap); 3729 } else 3730 status = B_ERROR; 3731 } else { 3732 window = new (nothrow) ServerWindow(title, this, clientReplyPort, 3733 looperPort, token); 3734 STRACE(("\nServerApp %s: New Window %s (%g:%g, %g:%g)\n", 3735 Signature(), title, frame.left, frame.top, 3736 frame.right, frame.bottom)); 3737 } 3738 3739 free(title); 3740 3741 // NOTE: the reply to the client is handled in ServerWindow::Run() 3742 if (window != NULL) { 3743 status = window->Init(frame, (window_look)look, (window_feel)feel, 3744 flags, workspaces); 3745 if (status == B_OK) { 3746 status = window->Run(); 3747 if (status != B_OK) { 3748 syslog(LOG_ERR, "ServerApp::_CreateWindow() - failed to run " 3749 "the window thread\n"); 3750 } 3751 } 3752 3753 if (status != B_OK) 3754 delete window; 3755 } 3756 3757 return status; 3758 } 3759 3760 3761 bool 3762 ServerApp::_HasWindowUnderMouse() 3763 { 3764 BAutolock locker(fWindowListLock); 3765 3766 for (int32 i = fWindowList.CountItems(); i-- > 0;) { 3767 ServerWindow* serverWindow = fWindowList.ItemAt(i); 3768 3769 if (fDesktop->ViewUnderMouse(serverWindow->Window()) != B_NULL_TOKEN) 3770 return true; 3771 } 3772 3773 return false; 3774 } 3775 3776 3777 bool 3778 ServerApp::_AddBitmap(ServerBitmap* bitmap) 3779 { 3780 BAutolock _(fMapLocker); 3781 3782 try { 3783 fBitmapMap.insert(std::make_pair(bitmap->Token(), BReference<ServerBitmap>(bitmap, false))); 3784 } catch (std::bad_alloc& exception) { 3785 return false; 3786 } 3787 3788 bitmap->SetOwner(this); 3789 return true; 3790 } 3791 3792 3793 void 3794 ServerApp::_DeleteBitmap(ServerBitmap* bitmap) 3795 { 3796 ASSERT(fMapLocker.IsLocked()); 3797 3798 gBitmapManager->BitmapRemoved(bitmap); 3799 fBitmapMap.erase(bitmap->Token()); 3800 } 3801 3802 3803 ServerBitmap* 3804 ServerApp::_FindBitmap(int32 token) const 3805 { 3806 ASSERT(fMapLocker.IsLocked()); 3807 3808 BitmapMap::const_iterator iterator = fBitmapMap.find(token); 3809 if (iterator == fBitmapMap.end()) 3810 return NULL; 3811 3812 return iterator->second; 3813 } 3814 3815 3816 ServerPicture* 3817 ServerApp::_FindPicture(int32 token) const 3818 { 3819 ASSERT(fMapLocker.IsLocked()); 3820 3821 PictureMap::const_iterator iterator = fPictureMap.find(token); 3822 if (iterator == fPictureMap.end()) 3823 return NULL; 3824 3825 return iterator->second; 3826 } 3827