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 // 2) uint16 - index in font file 1585 // 3) uint16 - instance 1586 1587 // Returns: 1588 // 1) uint16 - family ID of added font 1589 // 2) uint16 - style ID of added font 1590 // 3) uint16 - face of added font 1591 1592 AutoLocker< ::FontManager> fontLock(fAppFontManager); 1593 1594 if (fAppFontManager->CountFamilies() > MAX_USER_FONTS) { 1595 fLink.StartMessage(B_NOT_ALLOWED); 1596 fLink.Flush(); 1597 break; 1598 } 1599 1600 uint16 familyID, styleID; 1601 char* fontPath; 1602 uint16 index, instance; 1603 link.ReadString(&fontPath); 1604 link.Read<uint16>(&index); 1605 link.Read<uint16>(&instance); 1606 1607 status_t status = fAppFontManager->AddUserFontFromFile(fontPath, index, instance, 1608 familyID, styleID); 1609 1610 if (status != B_OK) { 1611 fLink.StartMessage(status); 1612 } else { 1613 ServerFont font; 1614 status = font.SetFamilyAndStyle(familyID, styleID, 1615 fAppFontManager); 1616 1617 fLink.StartMessage(status); 1618 if (status == B_OK) { 1619 fLink.Attach<uint16>(font.FamilyID()); 1620 fLink.Attach<uint16>(font.StyleID()); 1621 fLink.Attach<uint16>(font.Face()); 1622 } 1623 } 1624 1625 fLink.Flush(); 1626 break; 1627 } 1628 1629 case AS_ADD_FONT_MEMORY: 1630 { 1631 FTRACE(("ServerApp %s: Received BFont memory creation request\n", 1632 Signature())); 1633 1634 // Add a font for an application from a memory area 1635 1636 // Attached Data: 1637 // 1) area_id - id of memory area where font resides 1638 // 2) size_t - size of memory area for font 1639 // 3) size_t - offset to start of font memory 1640 // 4) uint16 - index in font buffer 1641 1642 // Returns: 1643 // 1) uint16 - family ID of added font 1644 // 2) uint16 - style ID of added font 1645 // 3) uint16 - face of added font 1646 1647 AutoLocker< ::FontManager> fontLock(fAppFontManager); 1648 1649 if (fAppFontManager->CountFamilies() > MAX_USER_FONTS) { 1650 fLink.StartMessage(B_NOT_ALLOWED); 1651 fLink.Flush(); 1652 break; 1653 } 1654 1655 area_id fontAreaID, fontAreaCloneID; 1656 area_info fontAreaInfo; 1657 char* area_addr; 1658 size_t size, offset; 1659 uint16 index; 1660 1661 link.Read<int32>(&fontAreaID); 1662 link.Read<size_t>(&size); 1663 link.Read<size_t>(&offset); 1664 link.Read<uint16>(&index); 1665 fontAreaCloneID = clone_area("user font", 1666 (void **)&area_addr, 1667 B_ANY_ADDRESS, 1668 B_READ_AREA, 1669 fontAreaID); 1670 1671 if (fontAreaCloneID < B_OK) { 1672 fLink.StartMessage(fontAreaCloneID); 1673 fLink.Flush(); 1674 break; 1675 } 1676 1677 status_t status = get_area_info(fontAreaCloneID, &fontAreaInfo); 1678 if (status != B_OK) { 1679 fLink.StartMessage(status); 1680 fLink.Flush(); 1681 delete_area(fontAreaCloneID); 1682 break; 1683 } 1684 1685 size_t fontMemorySize = fontAreaInfo.size - offset; 1686 1687 if (size == 0) 1688 size = fontMemorySize; 1689 1690 // Check size of font area and reject if it's too large 1691 if (size > MAX_FONT_DATA_SIZE_BYTES 1692 || size > fontMemorySize) { 1693 fLink.StartMessage(B_BAD_DATA); 1694 fLink.Flush(); 1695 delete_area(fontAreaCloneID); 1696 break; 1697 } 1698 1699 FT_Byte* fontData = (FT_Byte*)(malloc (sizeof(FT_Byte) * size)); 1700 if (fontData == NULL) { 1701 delete_area(fontAreaCloneID); 1702 fLink.StartMessage(B_BAD_DATA); 1703 fLink.Flush(); 1704 break; 1705 } 1706 1707 memcpy(fontData, (FT_Byte*)fontAreaInfo.address + offset, size); 1708 1709 delete_area(fontAreaCloneID); 1710 1711 uint16 familyID, styleID; 1712 1713 status = fAppFontManager->AddUserFontFromMemory(fontData, size, index, 1714 familyID, styleID); 1715 1716 if (status != B_OK) { 1717 fLink.StartMessage(status); 1718 free(fontData); 1719 } else { 1720 ServerFont font; 1721 status = font.SetFamilyAndStyle(familyID, styleID, 1722 fAppFontManager); 1723 1724 if (status == B_OK) { 1725 font.SetFontData(fontData, size); 1726 fLink.StartMessage(B_OK); 1727 fLink.Attach<uint16>(font.FamilyID()); 1728 fLink.Attach<uint16>(font.StyleID()); 1729 fLink.Attach<uint16>(font.Face()); 1730 } else { 1731 fLink.StartMessage(status); 1732 free(fontData); 1733 } 1734 } 1735 1736 fLink.Flush(); 1737 break; 1738 } 1739 1740 case AS_REMOVE_FONT: 1741 { 1742 STRACE(("ServerApp %s: Received BFont removal request\n", 1743 Signature())); 1744 1745 // Remove an application-added font 1746 1747 // Attached Data: 1748 // 1) uint16 - familyID of font to remove 1749 // 2) uint16 - styleID of font to remove 1750 1751 uint16 familyID, styleID; 1752 link.Read<uint16>(&familyID); 1753 link.Read<uint16>(&styleID); 1754 1755 status_t status = B_OK; 1756 1757 AutoLocker< ::FontManager> fontLock(fAppFontManager); 1758 status = fAppFontManager->RemoveUserFont(familyID, styleID); 1759 1760 fLink.StartMessage(status); 1761 fLink.Flush(); 1762 break; 1763 } 1764 1765 case AS_SET_SYSTEM_FONT: 1766 { 1767 FTRACE(("ServerApp %s: AS_SET_SYSTEM_FONT\n", Signature())); 1768 // gets: 1769 // 1) string - font type ("plain", ...) 1770 // 2) string - family 1771 // 3) string - style 1772 // 4) float - size 1773 1774 char type[B_OS_NAME_LENGTH]; 1775 font_family familyName; 1776 font_style styleName; 1777 float size; 1778 1779 if (link.ReadString(type, sizeof(type)) == B_OK 1780 && link.ReadString(familyName, sizeof(familyName)) == B_OK 1781 && link.ReadString(styleName, sizeof(styleName)) == B_OK 1782 && link.Read<float>(&size) == B_OK) { 1783 gFontManager->Lock(); 1784 1785 FontStyle* style 1786 = gFontManager->GetStyle(familyName, styleName); 1787 if (style != NULL) { 1788 ServerFont font(*style, size); 1789 gFontManager->Unlock(); 1790 // We must not have locked the font manager when 1791 // locking the desktop (through LockedDesktopSettings 1792 // below) 1793 1794 LockedDesktopSettings settings(fDesktop); 1795 1796 // TODO: Should we also update our internal copies now? 1797 if (strcmp(type, "plain") == 0) 1798 settings.SetDefaultPlainFont(font); 1799 else if (strcmp(type, "bold") == 0) 1800 settings.SetDefaultBoldFont(font); 1801 else if (strcmp(type, "fixed") == 0) 1802 settings.SetDefaultFixedFont(font); 1803 } else 1804 gFontManager->Unlock(); 1805 } 1806 break; 1807 } 1808 1809 case AS_GET_SYSTEM_DEFAULT_FONT: 1810 { 1811 // input: 1812 // 1) string - font type ("plain", ...) 1813 1814 ServerFont font; 1815 1816 char type[B_OS_NAME_LENGTH]; 1817 status_t status = link.ReadString(type, sizeof(type)); 1818 if (status == B_OK) { 1819 if (strcmp(type, "plain") == 0) 1820 font = *gFontManager->DefaultPlainFont(); 1821 else if (strcmp(type, "bold") == 0) 1822 font = *gFontManager->DefaultBoldFont(); 1823 else if (strcmp(type, "fixed") == 0) 1824 font = *gFontManager->DefaultFixedFont(); 1825 else 1826 status = B_BAD_VALUE; 1827 } 1828 1829 if (status == B_OK) { 1830 // returns: 1831 // 1) string - family 1832 // 2) string - style 1833 // 3) float - size 1834 1835 fLink.StartMessage(B_OK); 1836 fLink.AttachString(font.Family()); 1837 fLink.AttachString(font.Style()); 1838 fLink.Attach<float>(font.Size()); 1839 } else 1840 fLink.StartMessage(status); 1841 1842 fLink.Flush(); 1843 break; 1844 } 1845 1846 case AS_GET_SYSTEM_FONTS: 1847 { 1848 FTRACE(("ServerApp %s: AS_GET_SYSTEM_FONTS\n", Signature())); 1849 // Returns: 1850 // 1) uint16 - family ID 1851 // 2) uint16 - style ID 1852 // 3) float - size in points 1853 // 4) uint16 - face flags 1854 // 5) uint32 - font flags 1855 1856 if (!fDesktop->LockSingleWindow()) { 1857 fLink.StartMessage(B_OK); 1858 fLink.Flush(); 1859 break; 1860 } 1861 1862 // The client is requesting the system fonts, this 1863 // could have happened either at application start up, 1864 // or because the client is resyncing with the global 1865 // fonts. So we record the current system wide fonts 1866 // into our own copies at this point. 1867 DesktopSettings settings(fDesktop); 1868 1869 settings.GetDefaultPlainFont(fPlainFont); 1870 settings.GetDefaultBoldFont(fBoldFont); 1871 settings.GetDefaultFixedFont(fFixedFont); 1872 1873 fLink.StartMessage(B_OK); 1874 1875 for (int32 i = 0; i < 3; i++) { 1876 ServerFont* font = NULL; 1877 switch (i) { 1878 case 0: 1879 font = &fPlainFont; 1880 fLink.AttachString("plain"); 1881 break; 1882 1883 case 1: 1884 font = &fBoldFont; 1885 fLink.AttachString("bold"); 1886 break; 1887 1888 case 2: 1889 font = &fFixedFont; 1890 fLink.AttachString("fixed"); 1891 break; 1892 } 1893 1894 fLink.Attach<uint16>(font->FamilyID()); 1895 fLink.Attach<uint16>(font->StyleID()); 1896 fLink.Attach<float>(font->Size()); 1897 fLink.Attach<uint16>(font->Face()); 1898 fLink.Attach<uint32>(font->Flags()); 1899 } 1900 1901 fDesktop->UnlockSingleWindow(); 1902 fLink.Flush(); 1903 break; 1904 } 1905 1906 case AS_GET_FONT_LIST_REVISION: 1907 { 1908 FTRACE(("ServerApp %s: AS_GET_FONT_LIST_REVISION\n", Signature())); 1909 1910 fLink.StartMessage(B_OK); 1911 fLink.Attach<int32>( 1912 gFontManager->CheckRevision(fDesktop->UserID())); 1913 fLink.Flush(); 1914 break; 1915 } 1916 1917 case AS_GET_FAMILY_AND_STYLES: 1918 { 1919 FTRACE(("ServerApp %s: AS_GET_FAMILY_AND_STYLES\n", Signature())); 1920 1921 // Attached Data: 1922 // 1) int32 the index of the font family to get 1923 1924 // Returns: 1925 // 1) string - name of family 1926 // 2) uint32 - flags of font family (B_IS_FIXED || B_HAS_TUNED_FONT) 1927 // 3) count of styles in that family 1928 // For each style: 1929 // 1) string - name of style 1930 // 2) uint16 - face of style 1931 // 3) uint32 - flags of style 1932 1933 int32 index; 1934 link.Read<int32>(&index); 1935 1936 AutoLocker< ::FontManager> fontLock(gFontManager); 1937 1938 FontFamily* family = gFontManager->FamilyAt(index); 1939 if (family == NULL) { 1940 fontLock.SetTo(fAppFontManager, false); 1941 1942 family = fAppFontManager->FamilyAt(index); 1943 } 1944 1945 if (family) { 1946 fLink.StartMessage(B_OK); 1947 fLink.AttachString(family->Name()); 1948 fLink.Attach<uint32>(family->Flags()); 1949 1950 int32 count = family->CountStyles(); 1951 1952 fLink.Attach<int32>(count); 1953 1954 for (int32 i = 0; i < count; i++) { 1955 FontStyle* style = family->StyleAt(i); 1956 1957 fLink.AttachString(style->Name()); 1958 fLink.Attach<uint16>(style->Face()); 1959 fLink.Attach<uint32>(style->Flags()); 1960 } 1961 } else 1962 fLink.StartMessage(B_BAD_VALUE); 1963 1964 1965 fLink.Flush(); 1966 break; 1967 } 1968 1969 case AS_GET_FAMILY_AND_STYLE: 1970 { 1971 FTRACE(("ServerApp %s: AS_GET_FAMILY_AND_STYLE\n", Signature())); 1972 1973 // Attached Data: 1974 // 1) uint16 - family ID 1975 // 2) uint16 - style ID 1976 1977 // Returns: 1978 // 1) font_family The name of the font family 1979 // 2) font_style - name of the style 1980 1981 uint16 familyID, styleID; 1982 link.Read<uint16>(&familyID); 1983 link.Read<uint16>(&styleID); 1984 1985 AutoLocker< ::FontManager> fontLock(gFontManager); 1986 1987 FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID); 1988 if (fontStyle == NULL) { 1989 fontLock.SetTo(fAppFontManager, false); 1990 1991 fontStyle = fAppFontManager->GetStyle(familyID, styleID); 1992 } 1993 1994 if (fontStyle != NULL) { 1995 fLink.StartMessage(B_OK); 1996 fLink.AttachString(fontStyle->Family()->Name()); 1997 fLink.AttachString(fontStyle->Name()); 1998 } else 1999 fLink.StartMessage(B_BAD_VALUE); 2000 2001 fLink.Flush(); 2002 2003 break; 2004 } 2005 2006 case AS_GET_FAMILY_AND_STYLE_IDS: 2007 { 2008 FTRACE(("ServerApp %s: AS_GET_FAMILY_AND_STYLE_IDS\n", 2009 Signature())); 2010 2011 // Attached Data: 2012 // 1) font_family - name of font family to use 2013 // 2) font_style - name of style in family 2014 // 3) family ID - only used if 1) is empty 2015 // 4) style ID - only used if 2) is empty 2016 // 5) face - the font's current face 2017 2018 // Returns: 2019 // 1) uint16 - family ID 2020 // 2) uint16 - style ID 2021 // 3) uint16 - face 2022 2023 font_family family; 2024 font_style style; 2025 uint16 familyID, styleID; 2026 uint16 face; 2027 if (link.ReadString(family, sizeof(font_family)) == B_OK 2028 && link.ReadString(style, sizeof(font_style)) == B_OK 2029 && link.Read<uint16>(&familyID) == B_OK 2030 && link.Read<uint16>(&styleID) == B_OK 2031 && link.Read<uint16>(&face) == B_OK) { 2032 // get the font and return IDs and face 2033 AutoLocker< ::FontManager> fontLock(gFontManager); 2034 2035 FontStyle* fontStyle = gFontManager->GetStyle(family, style, 2036 familyID, styleID, face); 2037 if (fontStyle == NULL) { 2038 fontLock.SetTo(fAppFontManager, false); 2039 2040 fontStyle = fAppFontManager->GetStyle(family, style, 2041 familyID, styleID, face); 2042 } 2043 2044 if (fontStyle != NULL) { 2045 fLink.StartMessage(B_OK); 2046 fLink.Attach<uint16>(fontStyle->Family()->ID()); 2047 fLink.Attach<uint16>(fontStyle->ID()); 2048 2049 // we try to keep the font face close to what we got 2050 face = fontStyle->PreservedFace(face); 2051 2052 fLink.Attach<uint16>(face); 2053 } else 2054 fLink.StartMessage(B_NAME_NOT_FOUND); 2055 } else 2056 fLink.StartMessage(B_BAD_VALUE); 2057 2058 fLink.Flush(); 2059 break; 2060 } 2061 2062 case AS_GET_FONT_FILE_FORMAT: 2063 { 2064 FTRACE(("ServerApp %s: AS_GET_FONT_FILE_FORMAT\n", Signature())); 2065 2066 // Attached Data: 2067 // 1) uint16 - family ID 2068 // 2) uint16 - style ID 2069 2070 // Returns: 2071 // 1) uint16 font_file_format of font 2072 2073 int32 familyID, styleID; 2074 link.Read<int32>(&familyID); 2075 link.Read<int32>(&styleID); 2076 2077 AutoLocker< ::FontManager> fontLock(gFontManager); 2078 2079 FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID); 2080 if (fontStyle == NULL) { 2081 fontLock.SetTo(fAppFontManager, false); 2082 2083 fontStyle = fAppFontManager->GetStyle(familyID, styleID); 2084 } 2085 2086 if (fontStyle != NULL) { 2087 fLink.StartMessage(B_OK); 2088 fLink.Attach<uint16>((uint16)fontStyle->FileFormat()); 2089 } else 2090 fLink.StartMessage(B_BAD_VALUE); 2091 2092 fLink.Flush(); 2093 break; 2094 } 2095 2096 case AS_GET_STRING_WIDTHS: 2097 { 2098 FTRACE(("ServerApp %s: AS_GET_STRING_WIDTHS\n", Signature())); 2099 2100 // Attached Data: 2101 // 1) uint16 ID of family 2102 // 2) uint16 ID of style 2103 // 3) float point size of font 2104 // 4) uint8 spacing to use 2105 // 5) int32 numStrings 2106 // 6) int32 string length to measure (numStrings times) 2107 // 7) string String to measure (numStrings times) 2108 2109 // Returns: 2110 // 1) float - width of the string in pixels (numStrings times) 2111 2112 uint16 familyID, styleID; 2113 float size; 2114 uint8 spacing; 2115 2116 link.Read<uint16>(&familyID); 2117 link.Read<uint16>(&styleID); 2118 link.Read<float>(&size); 2119 link.Read<uint8>(&spacing); 2120 int32 numStrings; 2121 if (link.Read<int32>(&numStrings) != B_OK) { 2122 // this results in a B_BAD_VALUE return 2123 numStrings = 0; 2124 size = 0.0f; 2125 } 2126 2127 BStackOrHeapArray<float, 64> widthArray(numStrings); 2128 BStackOrHeapArray<int32, 64> lengthArray(numStrings); 2129 BStackOrHeapArray<char*, 64> stringArray(numStrings); 2130 if (!widthArray.IsValid() || !lengthArray.IsValid() 2131 || !stringArray.IsValid()) { 2132 fLink.StartMessage(B_NO_MEMORY); 2133 fLink.Flush(); 2134 break; 2135 } 2136 2137 for (int32 i = 0; i < numStrings; i++) { 2138 // This version of ReadString allocates the strings, we free 2139 // them below 2140 link.ReadString(&stringArray[i], (size_t *)&lengthArray[i]); 2141 } 2142 2143 ServerFont font; 2144 2145 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2146 fAppFontManager); 2147 2148 if (status == B_OK && size > 0) { 2149 font.SetSize(size); 2150 font.SetSpacing(spacing); 2151 2152 for (int32 i = 0; i < numStrings; i++) { 2153 if (!stringArray[i] || lengthArray[i] <= 0) 2154 widthArray[i] = 0.0; 2155 else { 2156 widthArray[i] = font.StringWidth(stringArray[i], 2157 lengthArray[i]); 2158 } 2159 } 2160 2161 fLink.StartMessage(B_OK); 2162 fLink.Attach(widthArray, numStrings * sizeof(float)); 2163 } else 2164 fLink.StartMessage(B_BAD_VALUE); 2165 2166 fLink.Flush(); 2167 2168 for (int32 i = 0; i < numStrings; i++) 2169 free(stringArray[i]); 2170 break; 2171 } 2172 2173 case AS_GET_FONT_BOUNDING_BOX: 2174 { 2175 FTRACE(("ServerApp %s: AS_GET_BOUNDING_BOX\n", 2176 Signature())); 2177 2178 // Attached Data: 2179 // 1) uint16 - family ID 2180 // 2) uint16 - style ID 2181 // 3) float - font size 2182 2183 // Returns: 2184 // 1) BRect - box holding entire font 2185 2186 uint16 familyID, styleID; 2187 float size; 2188 2189 link.Read<uint16>(&familyID); 2190 link.Read<uint16>(&styleID); 2191 link.Read<float>(&size); 2192 2193 ServerFont font; 2194 2195 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2196 fAppFontManager); 2197 2198 if (status == B_OK && size > 0) { 2199 font.SetSize(size); 2200 2201 fLink.StartMessage(B_OK); 2202 fLink.Attach<BRect>(font.BoundingBox()); 2203 } else 2204 fLink.StartMessage(B_BAD_VALUE); 2205 2206 fLink.Flush(); 2207 break; 2208 } 2209 2210 case AS_GET_TUNED_COUNT: 2211 { 2212 FTRACE(("ServerApp %s: AS_GET_TUNED_COUNT\n", Signature())); 2213 2214 // Attached Data: 2215 // 1) uint16 - family ID 2216 // 2) uint16 - style ID 2217 2218 // Returns: 2219 // 1) int32 - number of font strikes available 2220 2221 uint16 familyID, styleID; 2222 link.Read<uint16>(&familyID); 2223 link.Read<uint16>(&styleID); 2224 2225 AutoLocker< ::FontManager> fontLock(gFontManager); 2226 2227 FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID); 2228 if (fontStyle == NULL) { 2229 fontLock.SetTo(fAppFontManager, false); 2230 2231 fontStyle = fAppFontManager->GetStyle(familyID, styleID); 2232 } 2233 2234 if (fontStyle != NULL) { 2235 fLink.StartMessage(B_OK); 2236 fLink.Attach<int32>(fontStyle->TunedCount()); 2237 } else 2238 fLink.StartMessage(B_BAD_VALUE); 2239 2240 fLink.Flush(); 2241 break; 2242 } 2243 2244 case AS_GET_TUNED_INFO: 2245 { 2246 FTRACE(("ServerApp %s: AS_GET_TUNED_INFO unimplmemented\n", 2247 Signature())); 2248 2249 // Attached Data: 2250 // 1) uint16 - family ID 2251 // 2) uint16 - style ID 2252 // 3) uint32 - index of the particular font strike 2253 2254 // Returns: 2255 // 1) tuned_font_info - info on the strike specified 2256 // ToDo: implement me! 2257 2258 fLink.StartMessage(B_ERROR); 2259 fLink.Flush(); 2260 break; 2261 } 2262 2263 case AS_GET_EXTRA_FONT_FLAGS: 2264 { 2265 FTRACE(("ServerApp %s: AS_GET_EXTRA_FONT_FLAGS\n", 2266 Signature())); 2267 2268 // Attached Data: 2269 // 1) uint16 - family ID 2270 // 2) uint16 - style ID 2271 2272 // Returns: 2273 // 1) uint32 - extra font flags 2274 2275 uint16 familyID, styleID; 2276 link.Read<uint16>(&familyID); 2277 link.Read<uint16>(&styleID); 2278 2279 AutoLocker< ::FontManager> fontLock(gFontManager); 2280 2281 FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID); 2282 if (fontStyle == NULL) { 2283 fontLock.SetTo(fAppFontManager, false); 2284 2285 fontStyle = fAppFontManager->GetStyle(familyID, styleID); 2286 } 2287 2288 if (fontStyle != NULL) { 2289 fLink.StartMessage(B_OK); 2290 fLink.Attach<uint32>(fontStyle->Flags()); 2291 } else 2292 fLink.StartMessage(B_BAD_VALUE); 2293 2294 fLink.Flush(); 2295 break; 2296 } 2297 2298 case AS_GET_FONT_HEIGHT: 2299 { 2300 FTRACE(("ServerApp %s: AS_GET_FONT_HEIGHT\n", Signature())); 2301 2302 // Attached Data: 2303 // 1) uint16 family ID 2304 // 2) uint16 style ID 2305 // 3) float size 2306 2307 uint16 familyID, styleID; 2308 float size; 2309 link.Read<uint16>(&familyID); 2310 link.Read<uint16>(&styleID); 2311 link.Read<float>(&size); 2312 2313 AutoLocker< ::FontManager> fontLock(gFontManager); 2314 2315 FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID); 2316 if (fontStyle == NULL) { 2317 fontLock.SetTo(fAppFontManager, false); 2318 2319 fontStyle = fAppFontManager->GetStyle(familyID, styleID); 2320 } 2321 2322 if (fontStyle != NULL) { 2323 font_height height; 2324 fontStyle->GetHeight(size, height); 2325 2326 fLink.StartMessage(B_OK); 2327 fLink.Attach<font_height>(height); 2328 } else 2329 fLink.StartMessage(B_BAD_VALUE); 2330 2331 fLink.Flush(); 2332 break; 2333 } 2334 2335 case AS_GET_UNICODE_BLOCKS: 2336 { 2337 FTRACE(("ServerApp %s: AS_GET_UNICODE_BLOCKS\n", Signature())); 2338 2339 // Attached Data: 2340 // 1) uint16 family ID 2341 // 2) uint16 style ID 2342 2343 // Returns: 2344 // 1) unicode_block - bitfield of Unicode blocks in font 2345 2346 uint16 familyID, styleID; 2347 link.Read<uint16>(&familyID); 2348 link.Read<uint16>(&styleID); 2349 2350 ServerFont font; 2351 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2352 fAppFontManager); 2353 2354 if (status == B_OK) { 2355 unicode_block blocksForFont; 2356 font.GetUnicodeBlocks(blocksForFont); 2357 2358 fLink.StartMessage(B_OK); 2359 fLink.Attach<unicode_block>(blocksForFont); 2360 } else 2361 fLink.StartMessage(status); 2362 2363 fLink.Flush(); 2364 break; 2365 } 2366 2367 case AS_GET_HAS_UNICODE_BLOCK: 2368 { 2369 FTRACE(("ServerApp %s: AS_INCLUDES_UNICODE_BLOCK\n", Signature())); 2370 2371 // Attached Data: 2372 // 1) uint16 family ID 2373 // 2) uint16 style ID 2374 // 3) uint32 start of unicode block 2375 // 4) uint32 end of unicode block 2376 2377 // Returns: 2378 // 1) bool - whether or not font includes specified block range 2379 2380 uint16 familyID, styleID; 2381 uint32 start, end; 2382 link.Read<uint16>(&familyID); 2383 link.Read<uint16>(&styleID); 2384 link.Read<uint32>(&start); 2385 link.Read<uint32>(&end); 2386 2387 ServerFont font; 2388 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2389 fAppFontManager); 2390 2391 if (status == B_OK) { 2392 bool hasBlock; 2393 2394 status = font.IncludesUnicodeBlock(start, end, hasBlock); 2395 fLink.StartMessage(status); 2396 fLink.Attach<bool>(hasBlock); 2397 } else 2398 fLink.StartMessage(status); 2399 2400 fLink.Flush(); 2401 break; 2402 } 2403 2404 case AS_GET_GLYPH_SHAPES: 2405 { 2406 FTRACE(("ServerApp %s: AS_GET_GLYPH_SHAPES\n", Signature())); 2407 2408 // Attached Data: 2409 // 1) uint16 - family ID 2410 // 2) uint16 - style ID 2411 // 3) float - point size 2412 // 4) float - shear 2413 // 5) float - rotation 2414 // 6) float - false bold width 2415 // 6) uint32 - flags 2416 // 7) int32 - numChars 2417 // 8) int32 - numBytes 2418 // 8) char - chars (numBytes times) 2419 2420 // Returns: 2421 // 1) BShape - glyph shape 2422 // numChars times 2423 2424 uint16 familyID, styleID; 2425 uint32 flags; 2426 float size, shear, rotation, falseBoldWidth; 2427 2428 link.Read<uint16>(&familyID); 2429 link.Read<uint16>(&styleID); 2430 link.Read<float>(&size); 2431 link.Read<float>(&shear); 2432 link.Read<float>(&rotation); 2433 link.Read<float>(&falseBoldWidth); 2434 link.Read<uint32>(&flags); 2435 2436 int32 numChars, numBytes; 2437 link.Read<int32>(&numChars); 2438 link.Read<int32>(&numBytes); 2439 2440 BStackOrHeapArray<char, 256> charArray(numBytes); 2441 BStackOrHeapArray<BShape*, 64> shapes(numChars); 2442 if (!charArray.IsValid() || !shapes.IsValid()) { 2443 fLink.StartMessage(B_NO_MEMORY); 2444 fLink.Flush(); 2445 break; 2446 } 2447 2448 link.Read(charArray, numBytes); 2449 2450 ServerFont font; 2451 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2452 fAppFontManager); 2453 2454 if (status == B_OK) { 2455 font.SetSize(size); 2456 font.SetShear(shear); 2457 font.SetRotation(rotation); 2458 font.SetFalseBoldWidth(falseBoldWidth); 2459 font.SetFlags(flags); 2460 2461 status = font.GetGlyphShapes(charArray, numChars, shapes); 2462 if (status == B_OK) { 2463 fLink.StartMessage(B_OK); 2464 for (int32 i = 0; i < numChars; i++) { 2465 fLink.AttachShape(*shapes[i]); 2466 delete shapes[i]; 2467 } 2468 } 2469 } 2470 2471 if (status != B_OK) 2472 fLink.StartMessage(status); 2473 2474 fLink.Flush(); 2475 break; 2476 } 2477 2478 case AS_GET_HAS_GLYPHS: 2479 { 2480 FTRACE(("ServerApp %s: AS_GET_HAS_GLYPHS\n", Signature())); 2481 2482 // Attached Data: 2483 // 1) uint16 - family ID 2484 // 2) uint16 - style ID 2485 // 3) int32 - numChars 2486 // 4) int32 - numBytes 2487 // 5) char - the char buffer with size numBytes 2488 2489 uint16 familyID, styleID; 2490 link.Read<uint16>(&familyID); 2491 link.Read<uint16>(&styleID); 2492 2493 int32 numChars, numBytes; 2494 link.Read<int32>(&numChars); 2495 link.Read<int32>(&numBytes); 2496 2497 BStackOrHeapArray<char, 256> charArray(numBytes); 2498 BStackOrHeapArray<bool, 256> hasArray(numChars); 2499 if (!charArray.IsValid() || !hasArray.IsValid()) { 2500 fLink.StartMessage(B_NO_MEMORY); 2501 fLink.Flush(); 2502 break; 2503 } 2504 2505 link.Read(charArray, numBytes); 2506 2507 ServerFont font; 2508 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2509 fAppFontManager); 2510 2511 if (status == B_OK) { 2512 status = font.GetHasGlyphs(charArray, numBytes, numChars, 2513 hasArray); 2514 if (status == B_OK) { 2515 fLink.StartMessage(B_OK); 2516 fLink.Attach(hasArray, numChars * sizeof(bool)); 2517 } 2518 } 2519 2520 if (status != B_OK) 2521 fLink.StartMessage(status); 2522 2523 fLink.Flush(); 2524 break; 2525 } 2526 2527 case AS_GET_EDGES: 2528 { 2529 FTRACE(("ServerApp %s: AS_GET_EDGES\n", Signature())); 2530 2531 // Attached Data: 2532 // 1) uint16 - family ID 2533 // 2) uint16 - style ID 2534 // 3) int32 - numChars 2535 // 4) int32 - numBytes 2536 // 5) char - the char buffer with size numBytes 2537 2538 uint16 familyID, styleID; 2539 link.Read<uint16>(&familyID); 2540 link.Read<uint16>(&styleID); 2541 2542 int32 numChars; 2543 link.Read<int32>(&numChars); 2544 2545 uint32 numBytes; 2546 link.Read<uint32>(&numBytes); 2547 2548 BStackOrHeapArray<char, 256> charArray(numBytes); 2549 BStackOrHeapArray<edge_info, 64> edgeArray(numChars); 2550 if (!charArray.IsValid() || !edgeArray.IsValid()) { 2551 fLink.StartMessage(B_NO_MEMORY); 2552 fLink.Flush(); 2553 break; 2554 } 2555 2556 link.Read(charArray, numBytes); 2557 2558 ServerFont font; 2559 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2560 fAppFontManager); 2561 2562 if (status == B_OK) { 2563 status = font.GetEdges(charArray, numBytes, numChars, 2564 edgeArray); 2565 if (status == B_OK) { 2566 fLink.StartMessage(B_OK); 2567 fLink.Attach(edgeArray, numChars * sizeof(edge_info)); 2568 } 2569 } 2570 2571 if (status != B_OK) 2572 fLink.StartMessage(status); 2573 2574 fLink.Flush(); 2575 break; 2576 } 2577 2578 case AS_GET_ESCAPEMENTS: 2579 { 2580 FTRACE(("ServerApp %s: AS_GET_ESCAPEMENTS\n", Signature())); 2581 2582 // Attached Data: 2583 // 1) uint16 - family ID 2584 // 2) uint16 - style ID 2585 // 3) float - point size 2586 // 4) uint8 - spacing 2587 // 5) float - rotation 2588 // 6) uint32 - flags 2589 // 7) int32 - numChars 2590 // 8) char - char -\ both 2591 // 9) BPoint - offset -/ (numChars times) 2592 2593 // Returns: 2594 // 1) BPoint - escapement 2595 // numChars times 2596 2597 uint16 familyID, styleID; 2598 uint32 flags; 2599 float size, rotation; 2600 uint8 spacing; 2601 2602 link.Read<uint16>(&familyID); 2603 link.Read<uint16>(&styleID); 2604 link.Read<float>(&size); 2605 link.Read<uint8>(&spacing); 2606 link.Read<float>(&rotation); 2607 link.Read<uint32>(&flags); 2608 2609 escapement_delta delta; 2610 link.Read<float>(&delta.nonspace); 2611 link.Read<float>(&delta.space); 2612 2613 bool wantsOffsets; 2614 link.Read<bool>(&wantsOffsets); 2615 2616 int32 numChars; 2617 link.Read<int32>(&numChars); 2618 2619 uint32 numBytes; 2620 link.Read<uint32>(&numBytes); 2621 2622 BStackOrHeapArray<char, 256> charArray(numBytes); 2623 BStackOrHeapArray<BPoint, 64> escapements(numChars); 2624 BPoint* offsets = NULL; 2625 if (wantsOffsets) 2626 offsets = new(std::nothrow) BPoint[numChars]; 2627 2628 if (!charArray.IsValid() || !escapements.IsValid() 2629 || (offsets == NULL && wantsOffsets)) { 2630 delete[] offsets; 2631 fLink.StartMessage(B_NO_MEMORY); 2632 fLink.Flush(); 2633 break; 2634 } 2635 2636 link.Read(charArray, numBytes); 2637 2638 ServerFont font; 2639 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2640 fAppFontManager); 2641 2642 if (status == B_OK) { 2643 font.SetSize(size); 2644 font.SetSpacing(spacing); 2645 font.SetRotation(rotation); 2646 font.SetFlags(flags); 2647 2648 status = font.GetEscapements(charArray, numBytes, numChars, 2649 delta, escapements, offsets); 2650 2651 if (status == B_OK) { 2652 fLink.StartMessage(B_OK); 2653 for (int32 i = 0; i < numChars; i++) 2654 fLink.Attach<BPoint>(escapements[i]); 2655 2656 if (wantsOffsets) { 2657 for (int32 i = 0; i < numChars; i++) 2658 fLink.Attach<BPoint>(offsets[i]); 2659 } 2660 } 2661 } 2662 2663 if (status != B_OK) 2664 fLink.StartMessage(status); 2665 2666 delete[] offsets; 2667 fLink.Flush(); 2668 break; 2669 } 2670 2671 case AS_GET_ESCAPEMENTS_AS_FLOATS: 2672 { 2673 FTRACE(("ServerApp %s: AS_GET_ESCAPEMENTS_AS_FLOATS\n", Signature())); 2674 2675 // Attached Data: 2676 // 1) uint16 - family ID 2677 // 2) uint16 - style ID 2678 // 3) float - point size 2679 // 4) uint8 - spacing 2680 // 5) float - rotation 2681 // 6) uint32 - flags 2682 // 7) float - additional "nonspace" delta 2683 // 8) float - additional "space" delta 2684 // 9) int32 - numChars 2685 // 10) int32 - numBytes 2686 // 11) char - the char buffer with size numBytes 2687 2688 // Returns: 2689 // 1) float - escapement buffer with numChar entries 2690 2691 uint16 familyID, styleID; 2692 uint32 flags; 2693 float size, rotation; 2694 uint8 spacing; 2695 2696 link.Read<uint16>(&familyID); 2697 link.Read<uint16>(&styleID); 2698 link.Read<float>(&size); 2699 link.Read<uint8>(&spacing); 2700 link.Read<float>(&rotation); 2701 link.Read<uint32>(&flags); 2702 2703 escapement_delta delta; 2704 link.Read<float>(&delta.nonspace); 2705 link.Read<float>(&delta.space); 2706 2707 int32 numChars; 2708 link.Read<int32>(&numChars); 2709 2710 uint32 numBytes; 2711 link.Read<uint32>(&numBytes); 2712 2713 BStackOrHeapArray<char, 256> charArray(numBytes); 2714 BStackOrHeapArray<float, 64> escapements(numChars); 2715 if (!charArray.IsValid() || !escapements.IsValid()) { 2716 fLink.StartMessage(B_NO_MEMORY); 2717 fLink.Flush(); 2718 break; 2719 } 2720 2721 link.Read(charArray, numBytes); 2722 2723 // figure out escapements 2724 2725 ServerFont font; 2726 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2727 fAppFontManager); 2728 2729 if (status == B_OK) { 2730 font.SetSize(size); 2731 font.SetSpacing(spacing); 2732 font.SetRotation(rotation); 2733 font.SetFlags(flags); 2734 2735 status = font.GetEscapements(charArray, numBytes, numChars, 2736 delta, escapements); 2737 2738 if (status == B_OK) { 2739 fLink.StartMessage(B_OK); 2740 fLink.Attach(escapements, numChars * sizeof(float)); 2741 } 2742 } 2743 2744 if (status != B_OK) 2745 fLink.StartMessage(status); 2746 2747 fLink.Flush(); 2748 break; 2749 } 2750 2751 case AS_GET_BOUNDINGBOXES_CHARS: 2752 case AS_GET_BOUNDINGBOXES_STRING: 2753 { 2754 FTRACE(("ServerApp %s: AS_GET_BOUNDINGBOXES_CHARS\n", Signature())); 2755 2756 // Attached Data: 2757 // 1) uint16 - family ID 2758 // 2) uint16 - style ID 2759 // 3) float - point size 2760 // 4) float - rotation 2761 // 5) float - shear 2762 // 6) float - false bold width 2763 // 7) uint8 - spacing 2764 // 8) uint32 - flags 2765 // 9) font_metric_mode - mode 2766 // 10) bool - string escapement 2767 // 11) escapement_delta - additional delta 2768 // 12) int32 - numChars 2769 // 13) int32 - numBytes 2770 // 14) char - the char buffer with size numBytes 2771 2772 // Returns: 2773 // 1) BRect - rects with numChar entries 2774 2775 uint16 familyID, styleID; 2776 uint32 flags; 2777 float size, rotation, shear, falseBoldWidth; 2778 uint8 spacing; 2779 font_metric_mode mode; 2780 bool stringEscapement; 2781 2782 link.Read<uint16>(&familyID); 2783 link.Read<uint16>(&styleID); 2784 link.Read<float>(&size); 2785 link.Read<float>(&rotation); 2786 link.Read<float>(&shear); 2787 link.Read<float>(&falseBoldWidth); 2788 link.Read<uint8>(&spacing); 2789 link.Read<uint32>(&flags); 2790 link.Read<font_metric_mode>(&mode); 2791 link.Read<bool>(&stringEscapement); 2792 2793 escapement_delta delta; 2794 link.Read<escapement_delta>(&delta); 2795 2796 int32 numChars; 2797 link.Read<int32>(&numChars); 2798 2799 uint32 numBytes; 2800 link.Read<uint32>(&numBytes); 2801 2802 BStackOrHeapArray<char, 256> charArray(numBytes); 2803 BStackOrHeapArray<BRect, 64> rectArray(numChars); 2804 if (!charArray.IsValid() || !rectArray.IsValid()) { 2805 fLink.StartMessage(B_NO_MEMORY); 2806 fLink.Flush(); 2807 break; 2808 } 2809 2810 link.Read(charArray, numBytes); 2811 2812 // figure out escapements 2813 2814 ServerFont font; 2815 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2816 fAppFontManager); 2817 2818 if (status == B_OK) { 2819 font.SetSize(size); 2820 font.SetRotation(rotation); 2821 font.SetShear(shear); 2822 font.SetFalseBoldWidth(falseBoldWidth); 2823 font.SetSpacing(spacing); 2824 font.SetFlags(flags); 2825 2826 // TODO: implement for real 2827 status = font.GetBoundingBoxes(charArray, numBytes, 2828 numChars, rectArray, stringEscapement, mode, delta, 2829 code == AS_GET_BOUNDINGBOXES_STRING); 2830 if (status == B_OK) { 2831 fLink.StartMessage(B_OK); 2832 for (int32 i = 0; i < numChars; i++) 2833 fLink.Attach<BRect>(rectArray[i]); 2834 } 2835 } 2836 2837 if (status != B_OK) 2838 fLink.StartMessage(status); 2839 2840 fLink.Flush(); 2841 break; 2842 } 2843 2844 case AS_GET_BOUNDINGBOXES_STRINGS: 2845 { 2846 FTRACE(("ServerApp %s: AS_GET_BOUNDINGBOXES_STRINGS\n", 2847 Signature())); 2848 2849 // Attached Data: 2850 // 1) uint16 - family ID 2851 // 2) uint16 - style ID 2852 // 3) float - point size 2853 // 4) float - rotation 2854 // 5) float - shear 2855 // 6) float - false bold width 2856 // 7) uint8 - spacing 2857 // 8) uint32 - flags 2858 // 9) font_metric_mode - mode 2859 // 10) int32 numStrings 2860 // 11) escapement_delta - additional delta (numStrings times) 2861 // 12) int32 string length to measure (numStrings times) 2862 // 13) string - string (numStrings times) 2863 2864 // Returns: 2865 // 1) BRect - rects with numStrings entries 2866 2867 uint16 familyID, styleID; 2868 uint32 flags; 2869 float ptsize, rotation, shear, falseBoldWidth; 2870 uint8 spacing; 2871 font_metric_mode mode; 2872 2873 link.Read<uint16>(&familyID); 2874 link.Read<uint16>(&styleID); 2875 link.Read<float>(&ptsize); 2876 link.Read<float>(&rotation); 2877 link.Read<float>(&shear); 2878 link.Read<float>(&falseBoldWidth); 2879 link.Read<uint8>(&spacing); 2880 link.Read<uint32>(&flags); 2881 link.Read<font_metric_mode>(&mode); 2882 2883 int32 numStrings; 2884 link.Read<int32>(&numStrings); 2885 2886 BStackOrHeapArray<escapement_delta, 64> deltaArray(numStrings); 2887 BStackOrHeapArray<char*, 64> stringArray(numStrings); 2888 BStackOrHeapArray<size_t, 64> lengthArray(numStrings); 2889 BStackOrHeapArray<BRect, 64> rectArray(numStrings); 2890 if (!deltaArray.IsValid() || !stringArray.IsValid() 2891 || !lengthArray.IsValid() || !rectArray.IsValid()) { 2892 fLink.StartMessage(B_NO_MEMORY); 2893 fLink.Flush(); 2894 break; 2895 } 2896 2897 for (int32 i = 0; i < numStrings; i++) { 2898 // This version of ReadString allocates the strings, we free 2899 // them below 2900 link.ReadString(&stringArray[i], &lengthArray[i]); 2901 link.Read<escapement_delta>(&deltaArray[i]); 2902 } 2903 2904 ServerFont font; 2905 status_t status = font.SetFamilyAndStyle(familyID, styleID, 2906 fAppFontManager); 2907 2908 if (status == B_OK) { 2909 font.SetSize(ptsize); 2910 font.SetRotation(rotation); 2911 font.SetShear(shear); 2912 font.SetFalseBoldWidth(falseBoldWidth); 2913 font.SetSpacing(spacing); 2914 font.SetFlags(flags); 2915 2916 status = font.GetBoundingBoxesForStrings(stringArray, 2917 lengthArray, numStrings, rectArray, mode, deltaArray); 2918 if (status == B_OK) { 2919 fLink.StartMessage(B_OK); 2920 fLink.Attach(rectArray, numStrings * sizeof(BRect)); 2921 } 2922 } 2923 2924 for (int32 i = 0; i < numStrings; i++) 2925 free(stringArray[i]); 2926 2927 if (status != B_OK) 2928 fLink.StartMessage(status); 2929 2930 fLink.Flush(); 2931 break; 2932 } 2933 2934 // Screen commands 2935 2936 case AS_VALID_SCREEN_ID: 2937 { 2938 // Attached data 2939 // 1) int32 screen 2940 2941 int32 id; 2942 if (link.Read<int32>(&id) == B_OK 2943 && id == B_MAIN_SCREEN_ID.id) 2944 fLink.StartMessage(B_OK); 2945 else 2946 fLink.StartMessage(B_ERROR); 2947 2948 fLink.Flush(); 2949 break; 2950 } 2951 2952 case AS_GET_NEXT_SCREEN_ID: 2953 { 2954 // Attached data 2955 // 1) int32 screen 2956 2957 int32 id; 2958 link.Read<int32>(&id); 2959 2960 // TODO: for now, just say we're the last one 2961 fLink.StartMessage(B_ENTRY_NOT_FOUND); 2962 fLink.Flush(); 2963 break; 2964 } 2965 2966 case AS_GET_SCREEN_ID_FROM_WINDOW: 2967 { 2968 status_t status = B_BAD_VALUE; 2969 2970 // Attached data 2971 // 1) int32 - window client token 2972 2973 int32 clientToken; 2974 if (link.Read<int32>(&clientToken) != B_OK) 2975 status = B_BAD_DATA; 2976 else { 2977 BAutolock locker(fWindowListLock); 2978 2979 for (int32 i = fWindowList.CountItems(); i-- > 0;) { 2980 ServerWindow* serverWindow = fWindowList.ItemAt(i); 2981 2982 if (serverWindow->ClientToken() == clientToken) { 2983 AutoReadLocker _(fDesktop->ScreenLocker()); 2984 2985 // found it! 2986 Window* window = serverWindow->Window(); 2987 const Screen* screen = NULL; 2988 if (window != NULL) 2989 screen = window->Screen(); 2990 2991 if (screen == NULL) { 2992 // The window hasn't been added to the desktop yet, 2993 // or it's an offscreen window 2994 break; 2995 } 2996 2997 fLink.StartMessage(B_OK); 2998 fLink.Attach<int32>(screen->ID()); 2999 status = B_OK; 3000 break; 3001 } 3002 } 3003 } 3004 3005 if (status != B_OK) 3006 fLink.StartMessage(status); 3007 fLink.Flush(); 3008 break; 3009 } 3010 3011 case AS_SCREEN_GET_MODE: 3012 { 3013 STRACE(("ServerApp %s: AS_SCREEN_GET_MODE\n", Signature())); 3014 3015 // Attached data 3016 // 1) int32 screen 3017 // 2) uint32 workspace index 3018 3019 int32 id; 3020 link.Read<int32>(&id); 3021 uint32 workspace; 3022 link.Read<uint32>(&workspace); 3023 3024 display_mode mode; 3025 status_t status = fDesktop->GetScreenMode(workspace, id, mode); 3026 3027 fLink.StartMessage(status); 3028 if (status == B_OK) 3029 fLink.Attach<display_mode>(mode); 3030 fLink.Flush(); 3031 break; 3032 } 3033 3034 case AS_SCREEN_SET_MODE: 3035 { 3036 STRACE(("ServerApp %s: AS_SCREEN_SET_MODE\n", Signature())); 3037 3038 // Attached data 3039 // 1) int32 screen 3040 // 2) workspace index 3041 // 3) display_mode to set 3042 // 4) 'makeDefault' boolean 3043 3044 int32 id; 3045 link.Read<int32>(&id); 3046 uint32 workspace; 3047 link.Read<uint32>(&workspace); 3048 3049 display_mode mode; 3050 link.Read<display_mode>(&mode); 3051 3052 bool makeDefault = false; 3053 status_t status = link.Read<bool>(&makeDefault); 3054 3055 if (status == B_OK) { 3056 status = fDesktop->SetScreenMode(workspace, id, mode, 3057 makeDefault); 3058 } 3059 if (status == B_OK) { 3060 if (workspace == (uint32)B_CURRENT_WORKSPACE_INDEX 3061 && fDesktop->LockSingleWindow()) { 3062 workspace = fDesktop->CurrentWorkspace(); 3063 fDesktop->UnlockSingleWindow(); 3064 } 3065 3066 if (!makeDefault) { 3067 // Memorize the screen change, so that it can be reverted 3068 // later 3069 fTemporaryDisplayModeChange |= 1 << workspace; 3070 } else 3071 fTemporaryDisplayModeChange &= ~(1 << workspace); 3072 } 3073 3074 fLink.StartMessage(status); 3075 fLink.Flush(); 3076 break; 3077 } 3078 3079 case AS_PROPOSE_MODE: 3080 { 3081 STRACE(("ServerApp %s: AS_PROPOSE_MODE\n", Signature())); 3082 int32 id; 3083 link.Read<int32>(&id); 3084 3085 display_mode target, low, high; 3086 link.Read<display_mode>(&target); 3087 link.Read<display_mode>(&low); 3088 link.Read<display_mode>(&high); 3089 status_t status = fDesktop->HWInterface()->ProposeMode(&target, 3090 &low, &high); 3091 3092 // ProposeMode() returns B_BAD_VALUE to hint that the candidate is 3093 // not within the given limits (but is supported) 3094 if (status == B_OK || status == B_BAD_VALUE) { 3095 fLink.StartMessage(B_OK); 3096 fLink.Attach<display_mode>(target); 3097 fLink.Attach<bool>(status == B_OK); 3098 } else 3099 fLink.StartMessage(status); 3100 3101 fLink.Flush(); 3102 break; 3103 } 3104 3105 case AS_GET_MODE_LIST: 3106 { 3107 int32 id; 3108 link.Read<int32>(&id); 3109 // TODO: use this screen id 3110 3111 display_mode* modeList; 3112 uint32 count; 3113 status_t status = fDesktop->HWInterface()->GetModeList(&modeList, 3114 &count); 3115 if (status == B_OK) { 3116 fLink.StartMessage(B_OK); 3117 fLink.Attach<uint32>(count); 3118 fLink.Attach(modeList, sizeof(display_mode) * count); 3119 3120 delete[] modeList; 3121 } else 3122 fLink.StartMessage(status); 3123 3124 fLink.Flush(); 3125 break; 3126 } 3127 3128 case AS_GET_SCREEN_FRAME: 3129 { 3130 STRACE(("ServerApp %s: AS_GET_SCREEN_FRAME\n", Signature())); 3131 3132 // Attached data 3133 // 1) int32 screen 3134 // 2) uint32 workspace index 3135 3136 int32 id; 3137 link.Read<int32>(&id); 3138 uint32 workspace; 3139 link.Read<uint32>(&workspace); 3140 3141 BRect frame; 3142 status_t status = fDesktop->GetScreenFrame(workspace, id, frame); 3143 3144 fLink.StartMessage(status); 3145 if (status == B_OK) 3146 fLink.Attach<BRect>(frame); 3147 3148 fLink.Flush(); 3149 break; 3150 } 3151 3152 case AS_SCREEN_GET_COLORMAP: 3153 { 3154 STRACE(("ServerApp %s: AS_SCREEN_GET_COLORMAP\n", Signature())); 3155 3156 int32 id; 3157 link.Read<int32>(&id); 3158 3159 const color_map* colorMap = SystemColorMap(); 3160 if (colorMap != NULL) { 3161 fLink.StartMessage(B_OK); 3162 fLink.Attach<color_map>(*colorMap); 3163 } else 3164 fLink.StartMessage(B_ERROR); 3165 3166 fLink.Flush(); 3167 break; 3168 } 3169 3170 case AS_GET_DESKTOP_COLOR: 3171 { 3172 STRACE(("ServerApp %s: get desktop color\n", Signature())); 3173 3174 uint32 index; 3175 link.Read<uint32>(&index); 3176 3177 fLink.StartMessage(B_OK); 3178 fDesktop->LockSingleWindow(); 3179 3180 // we're nice to our children (and also take the default case 3181 // into account which asks for the current workspace) 3182 if (index >= (uint32)kMaxWorkspaces) 3183 index = fDesktop->CurrentWorkspace(); 3184 3185 Workspace workspace(*fDesktop, index, true); 3186 fLink.Attach<rgb_color>(workspace.Color()); 3187 3188 fDesktop->UnlockSingleWindow(); 3189 fLink.Flush(); 3190 break; 3191 } 3192 3193 case AS_SET_DESKTOP_COLOR: 3194 { 3195 STRACE(("ServerApp %s: set desktop color\n", Signature())); 3196 3197 rgb_color color; 3198 uint32 index; 3199 bool makeDefault; 3200 3201 link.Read<rgb_color>(&color); 3202 link.Read<uint32>(&index); 3203 if (link.Read<bool>(&makeDefault) != B_OK) 3204 break; 3205 3206 fDesktop->LockAllWindows(); 3207 3208 // we're nice to our children (and also take the default case 3209 // into account which asks for the current workspace) 3210 if (index >= (uint32)kMaxWorkspaces) 3211 index = fDesktop->CurrentWorkspace(); 3212 3213 Workspace workspace(*fDesktop, index); 3214 workspace.SetColor(color, makeDefault); 3215 3216 fDesktop->UnlockAllWindows(); 3217 break; 3218 } 3219 3220 case AS_GET_ACCELERANT_INFO: 3221 { 3222 STRACE(("ServerApp %s: get accelerant info\n", Signature())); 3223 3224 // We aren't using the screen_id for now... 3225 int32 id; 3226 link.Read<int32>(&id); 3227 3228 accelerant_device_info accelerantInfo; 3229 // TODO: I wonder if there should be a "desktop" lock... 3230 status_t status 3231 = fDesktop->HWInterface()->GetDeviceInfo(&accelerantInfo); 3232 if (status == B_OK) { 3233 fLink.StartMessage(B_OK); 3234 fLink.Attach<accelerant_device_info>(accelerantInfo); 3235 } else 3236 fLink.StartMessage(status); 3237 3238 fLink.Flush(); 3239 break; 3240 } 3241 3242 case AS_GET_MONITOR_INFO: 3243 { 3244 STRACE(("ServerApp %s: get monitor info\n", Signature())); 3245 3246 // We aren't using the screen_id for now... 3247 int32 id; 3248 link.Read<int32>(&id); 3249 3250 monitor_info info; 3251 // TODO: I wonder if there should be a "desktop" lock... 3252 status_t status = fDesktop->HWInterface()->GetMonitorInfo(&info); 3253 if (status == B_OK) { 3254 fLink.StartMessage(B_OK); 3255 fLink.Attach<monitor_info>(info); 3256 } else 3257 fLink.StartMessage(status); 3258 3259 fLink.Flush(); 3260 break; 3261 } 3262 3263 case AS_GET_FRAME_BUFFER_CONFIG: 3264 { 3265 STRACE(("ServerApp %s: get frame buffer config\n", Signature())); 3266 3267 // We aren't using the screen_id for now... 3268 int32 id; 3269 link.Read<int32>(&id); 3270 3271 frame_buffer_config config; 3272 // TODO: I wonder if there should be a "desktop" lock... 3273 status_t status = fDesktop->HWInterface()->GetFrameBufferConfig(config); 3274 if (status == B_OK) { 3275 fLink.StartMessage(B_OK); 3276 fLink.Attach<frame_buffer_config>(config); 3277 } else 3278 fLink.StartMessage(status); 3279 3280 fLink.Flush(); 3281 break; 3282 } 3283 3284 case AS_GET_RETRACE_SEMAPHORE: 3285 { 3286 STRACE(("ServerApp %s: get retrace semaphore\n", Signature())); 3287 3288 // We aren't using the screen_id for now... 3289 int32 id; 3290 link.Read<int32>(&id); 3291 3292 fLink.StartMessage(B_OK); 3293 fLink.Attach<sem_id>(fDesktop->HWInterface()->RetraceSemaphore()); 3294 fLink.Flush(); 3295 break; 3296 } 3297 3298 case AS_GET_TIMING_CONSTRAINTS: 3299 { 3300 STRACE(("ServerApp %s: get timing constraints\n", Signature())); 3301 3302 // We aren't using the screen_id for now... 3303 int32 id; 3304 link.Read<int32>(&id); 3305 3306 display_timing_constraints constraints; 3307 status_t status = fDesktop->HWInterface()->GetTimingConstraints( 3308 &constraints); 3309 if (status == B_OK) { 3310 fLink.StartMessage(B_OK); 3311 fLink.Attach<display_timing_constraints>(constraints); 3312 } else 3313 fLink.StartMessage(status); 3314 3315 fLink.Flush(); 3316 break; 3317 } 3318 3319 case AS_GET_PIXEL_CLOCK_LIMITS: 3320 { 3321 STRACE(("ServerApp %s: get pixel clock limits\n", Signature())); 3322 // We aren't using the screen_id for now... 3323 int32 id; 3324 link.Read<int32>(&id); 3325 display_mode mode; 3326 link.Read<display_mode>(&mode); 3327 3328 uint32 low, high; 3329 status_t status = fDesktop->HWInterface()->GetPixelClockLimits(&mode, 3330 &low, &high); 3331 if (status == B_OK) { 3332 fLink.StartMessage(B_OK); 3333 fLink.Attach<uint32>(low); 3334 fLink.Attach<uint32>(high); 3335 } else 3336 fLink.StartMessage(status); 3337 3338 fLink.Flush(); 3339 break; 3340 } 3341 3342 case AS_SET_DPMS: 3343 { 3344 STRACE(("ServerApp %s: AS_SET_DPMS\n", Signature())); 3345 int32 id; 3346 link.Read<int32>(&id); 3347 3348 uint32 mode; 3349 link.Read<uint32>(&mode); 3350 3351 status_t status = fDesktop->HWInterface()->SetDPMSMode(mode); 3352 fLink.StartMessage(status); 3353 3354 fLink.Flush(); 3355 break; 3356 } 3357 3358 case AS_GET_DPMS_STATE: 3359 { 3360 STRACE(("ServerApp %s: AS_GET_DPMS_STATE\n", Signature())); 3361 3362 int32 id; 3363 link.Read<int32>(&id); 3364 3365 uint32 state = fDesktop->HWInterface()->DPMSMode(); 3366 fLink.StartMessage(B_OK); 3367 fLink.Attach<uint32>(state); 3368 fLink.Flush(); 3369 break; 3370 } 3371 3372 case AS_GET_DPMS_CAPABILITIES: 3373 { 3374 STRACE(("ServerApp %s: AS_GET_DPMS_CAPABILITIES\n", Signature())); 3375 int32 id; 3376 link.Read<int32>(&id); 3377 3378 uint32 capabilities = fDesktop->HWInterface()->DPMSCapabilities(); 3379 fLink.StartMessage(B_OK); 3380 fLink.Attach<uint32>(capabilities); 3381 fLink.Flush(); 3382 break; 3383 } 3384 3385 case AS_SCREEN_SET_BRIGHTNESS: 3386 { 3387 STRACE(("ServerApp %s: AS_SCREEN_SET_BRIGHTNESS\n", Signature())); 3388 int32 id; 3389 link.Read<int32>(&id); 3390 3391 float brightness; 3392 link.Read<float>(&brightness); 3393 3394 status_t status = fDesktop->SetBrightness(id, brightness); 3395 fLink.StartMessage(status); 3396 3397 fLink.Flush(); 3398 break; 3399 } 3400 3401 case AS_SCREEN_GET_BRIGHTNESS: 3402 { 3403 STRACE(("ServerApp %s: AS_SCREEN_GET_BRIGHTNESS\n", Signature())); 3404 int32 id; 3405 link.Read<int32>(&id); 3406 3407 float brightness; 3408 status_t result = fDesktop->HWInterface()->GetBrightness(&brightness); 3409 fLink.StartMessage(result); 3410 if (result == B_OK) 3411 fLink.Attach<float>(brightness); 3412 fLink.Flush(); 3413 break; 3414 } 3415 3416 case AS_READ_BITMAP: 3417 { 3418 STRACE(("ServerApp %s: AS_READ_BITMAP\n", Signature())); 3419 int32 token; 3420 link.Read<int32>(&token); 3421 3422 bool drawCursor = true; 3423 link.Read<bool>(&drawCursor); 3424 3425 BRect bounds; 3426 link.Read<BRect>(&bounds); 3427 3428 bool success = false; 3429 3430 BReference<ServerBitmap> bitmap(GetBitmap(token), true); 3431 if (bitmap != NULL) { 3432 if (fDesktop->GetDrawingEngine()->LockExclusiveAccess()) { 3433 success = fDesktop->GetDrawingEngine()->ReadBitmap(bitmap, 3434 drawCursor, bounds) == B_OK; 3435 fDesktop->GetDrawingEngine()->UnlockExclusiveAccess(); 3436 } 3437 } 3438 3439 if (success) 3440 fLink.StartMessage(B_OK); 3441 else 3442 fLink.StartMessage(B_BAD_VALUE); 3443 3444 fLink.Flush(); 3445 break; 3446 } 3447 3448 case AS_GET_ACCELERANT_PATH: 3449 { 3450 int32 id; 3451 fLink.Read<int32>(&id); 3452 3453 BString path; 3454 status_t status = fDesktop->HWInterface()->GetAccelerantPath(path); 3455 fLink.StartMessage(status); 3456 if (status == B_OK) 3457 fLink.AttachString(path.String()); 3458 3459 fLink.Flush(); 3460 break; 3461 } 3462 3463 case AS_GET_DRIVER_PATH: 3464 { 3465 int32 id; 3466 fLink.Read<int32>(&id); 3467 3468 BString path; 3469 status_t status = fDesktop->HWInterface()->GetDriverPath(path); 3470 fLink.StartMessage(status); 3471 if (status == B_OK) 3472 fLink.AttachString(path.String()); 3473 3474 fLink.Flush(); 3475 break; 3476 } 3477 3478 // BWindowScreen communication 3479 3480 case AS_DIRECT_SCREEN_LOCK: 3481 { 3482 bool lock; 3483 link.Read<bool>(&lock); 3484 3485 status_t status; 3486 if (lock) 3487 status = fDesktop->LockDirectScreen(ClientTeam()); 3488 else 3489 status = fDesktop->UnlockDirectScreen(ClientTeam()); 3490 3491 fLink.StartMessage(status); 3492 fLink.Flush(); 3493 break; 3494 } 3495 3496 // Hinting and aliasing 3497 3498 case AS_SET_SUBPIXEL_ANTIALIASING: 3499 { 3500 bool subpix; 3501 if (link.Read<bool>(&subpix) == B_OK) { 3502 LockedDesktopSettings settings(fDesktop); 3503 settings.SetSubpixelAntialiasing(subpix); 3504 } 3505 fDesktop->Redraw(); 3506 break; 3507 } 3508 3509 case AS_GET_SUBPIXEL_ANTIALIASING: 3510 { 3511 DesktopSettings settings(fDesktop); 3512 fLink.StartMessage(B_OK); 3513 fLink.Attach<bool>(settings.SubpixelAntialiasing()); 3514 fLink.Flush(); 3515 break; 3516 } 3517 3518 case AS_SET_HINTING: 3519 { 3520 uint8 hinting; 3521 if (link.Read<uint8>(&hinting) == B_OK && hinting < 3) { 3522 LockedDesktopSettings settings(fDesktop); 3523 if (hinting != settings.Hinting()) { 3524 settings.SetHinting(hinting); 3525 fDesktop->Redraw(); 3526 } 3527 } 3528 break; 3529 } 3530 3531 case AS_GET_HINTING: 3532 { 3533 DesktopSettings settings(fDesktop); 3534 fLink.StartMessage(B_OK); 3535 fLink.Attach<uint8>(settings.Hinting()); 3536 fLink.Flush(); 3537 break; 3538 } 3539 3540 case AS_SET_SUBPIXEL_AVERAGE_WEIGHT: 3541 { 3542 uint8 averageWeight; 3543 if (link.Read<uint8>(&averageWeight) == B_OK) { 3544 LockedDesktopSettings settings(fDesktop); 3545 settings.SetSubpixelAverageWeight(averageWeight); 3546 } 3547 fDesktop->Redraw(); 3548 break; 3549 } 3550 3551 case AS_GET_SUBPIXEL_AVERAGE_WEIGHT: 3552 { 3553 DesktopSettings settings(fDesktop); 3554 fLink.StartMessage(B_OK); 3555 fLink.Attach<uint8>(settings.SubpixelAverageWeight()); 3556 fLink.Flush(); 3557 break; 3558 } 3559 3560 case AS_SET_SUBPIXEL_ORDERING: 3561 { 3562 bool subpixelOrdering; 3563 if (link.Read<bool>(&subpixelOrdering) == B_OK) { 3564 LockedDesktopSettings settings(fDesktop); 3565 settings.SetSubpixelOrderingRegular(subpixelOrdering); 3566 } 3567 fDesktop->Redraw(); 3568 break; 3569 } 3570 3571 case AS_GET_SUBPIXEL_ORDERING: 3572 { 3573 DesktopSettings settings(fDesktop); 3574 fLink.StartMessage(B_OK); 3575 fLink.Attach<bool>(settings.IsSubpixelOrderingRegular()); 3576 fLink.Flush(); 3577 break; 3578 } 3579 3580 default: 3581 printf("ServerApp %s received unhandled message code %" B_PRId32 3582 "\n", Signature(), code); 3583 3584 if (link.NeedsReply()) { 3585 // the client is now blocking and waiting for a reply! 3586 fLink.StartMessage(B_ERROR); 3587 fLink.Flush(); 3588 } else 3589 puts("message doesn't need a reply!"); 3590 break; 3591 } 3592 } 3593 3594 3595 /*! \brief The thread function ServerApps use to monitor messages 3596 */ 3597 void 3598 ServerApp::_MessageLooper() 3599 { 3600 // Message-dispatching loop for the ServerApp 3601 3602 // get our own team ID 3603 thread_info threadInfo; 3604 get_thread_info(fThread, &threadInfo); 3605 3606 // First let's tell the client how to talk with us. 3607 fLink.StartMessage(B_OK); 3608 fLink.Attach<port_id>(fMessagePort); 3609 fLink.Attach<area_id>(fDesktop->SharedReadOnlyArea()); 3610 fLink.Attach<team_id>(threadInfo.team); 3611 fLink.Flush(); 3612 3613 BPrivate::LinkReceiver &receiver = fLink.Receiver(); 3614 3615 int32 code; 3616 status_t err = B_OK; 3617 3618 while (!fQuitting) { 3619 STRACE(("info: ServerApp::_MessageLooper() listening on port %" B_PRId32 3620 ".\n", fMessagePort)); 3621 3622 err = receiver.GetNextMessage(code); 3623 if (err != B_OK || code == B_QUIT_REQUESTED) { 3624 STRACE(("ServerApp: application seems to be gone...\n")); 3625 3626 // Tell desktop to quit us 3627 BPrivate::LinkSender link(fDesktop->MessagePort()); 3628 link.StartMessage(AS_DELETE_APP); 3629 link.Attach<thread_id>(Thread()); 3630 link.Flush(); 3631 break; 3632 } 3633 3634 switch (code) { 3635 case kMsgAppQuit: 3636 // we receive this from our destructor on quit 3637 fQuitting = true; 3638 break; 3639 3640 case AS_QUIT_APP: 3641 { 3642 // This message is received only when the app_server is asked 3643 // to shut down in test/debug mode. Of course, if we are testing 3644 // while using AccelerantDriver, we do NOT want to shut down 3645 // client applications. The server can be quit in this fashion 3646 // through the driver's interface, such as closing the 3647 // ViewDriver's window. 3648 3649 STRACE(("ServerApp %s:Server shutdown notification received\n", 3650 Signature())); 3651 3652 // If we are using the real, accelerated version of the 3653 // DrawingEngine, we do NOT want the user to be able shut down 3654 // the server. The results would NOT be pretty 3655 #if TEST_MODE 3656 BMessage pleaseQuit(B_QUIT_REQUESTED); 3657 SendMessageToClient(&pleaseQuit); 3658 #endif 3659 break; 3660 } 3661 3662 default: 3663 STRACE(("ServerApp %s: Got a Message to dispatch\n", 3664 Signature())); 3665 _DispatchMessage(code, receiver); 3666 break; 3667 } 3668 } 3669 3670 // Quit() will send us a message; we're handling the exiting procedure 3671 thread_id sender; 3672 sem_id shutdownSemaphore; 3673 receive_data(&sender, &shutdownSemaphore, sizeof(sem_id)); 3674 3675 delete this; 3676 3677 if (shutdownSemaphore >= B_OK) 3678 release_sem(shutdownSemaphore); 3679 } 3680 3681 3682 status_t 3683 ServerApp::_CreateWindow(int32 code, BPrivate::LinkReceiver& link, 3684 port_id& clientReplyPort) 3685 { 3686 // Attached data: 3687 // 1) int32 bitmap token (only for AS_CREATE_OFFSCREEN_WINDOW) 3688 // 2) BRect window frame 3689 // 3) uint32 window look 3690 // 4) uint32 window feel 3691 // 5) uint32 window flags 3692 // 6) uint32 workspace index 3693 // 7) int32 BHandler token of the window 3694 // 8) port_id window's reply port 3695 // 9) port_id window's looper port 3696 // 10) const char * title 3697 3698 BRect frame; 3699 int32 bitmapToken; 3700 uint32 look; 3701 uint32 feel; 3702 uint32 flags; 3703 uint32 workspaces; 3704 int32 token; 3705 port_id looperPort; 3706 char* title; 3707 3708 if (code == AS_CREATE_OFFSCREEN_WINDOW) 3709 link.Read<int32>(&bitmapToken); 3710 3711 link.Read<BRect>(&frame); 3712 link.Read<uint32>(&look); 3713 link.Read<uint32>(&feel); 3714 link.Read<uint32>(&flags); 3715 link.Read<uint32>(&workspaces); 3716 link.Read<int32>(&token); 3717 link.Read<port_id>(&clientReplyPort); 3718 link.Read<port_id>(&looperPort); 3719 if (link.ReadString(&title) != B_OK) 3720 return B_ERROR; 3721 3722 if (!frame.IsValid()) { 3723 // make sure we pass a valid rectangle to ServerWindow 3724 frame.right = frame.left + 1; 3725 frame.bottom = frame.top + 1; 3726 } 3727 3728 status_t status = B_NO_MEMORY; 3729 ServerWindow *window = NULL; 3730 3731 if (code == AS_CREATE_OFFSCREEN_WINDOW) { 3732 ServerBitmap* bitmap = GetBitmap(bitmapToken); 3733 3734 if (bitmap != NULL) { 3735 window = new (nothrow) OffscreenServerWindow(title, this, 3736 clientReplyPort, looperPort, token, bitmap); 3737 } else 3738 status = B_ERROR; 3739 } else { 3740 window = new (nothrow) ServerWindow(title, this, clientReplyPort, 3741 looperPort, token); 3742 STRACE(("\nServerApp %s: New Window %s (%g:%g, %g:%g)\n", 3743 Signature(), title, frame.left, frame.top, 3744 frame.right, frame.bottom)); 3745 } 3746 3747 free(title); 3748 3749 // NOTE: the reply to the client is handled in ServerWindow::Run() 3750 if (window != NULL) { 3751 status = window->Init(frame, (window_look)look, (window_feel)feel, 3752 flags, workspaces); 3753 if (status == B_OK) { 3754 status = window->Run(); 3755 if (status != B_OK) { 3756 syslog(LOG_ERR, "ServerApp::_CreateWindow() - failed to run " 3757 "the window thread\n"); 3758 } 3759 } 3760 3761 if (status != B_OK) 3762 delete window; 3763 } 3764 3765 return status; 3766 } 3767 3768 3769 bool 3770 ServerApp::_HasWindowUnderMouse() 3771 { 3772 BAutolock locker(fWindowListLock); 3773 3774 for (int32 i = fWindowList.CountItems(); i-- > 0;) { 3775 ServerWindow* serverWindow = fWindowList.ItemAt(i); 3776 3777 if (fDesktop->ViewUnderMouse(serverWindow->Window()) != B_NULL_TOKEN) 3778 return true; 3779 } 3780 3781 return false; 3782 } 3783 3784 3785 bool 3786 ServerApp::_AddBitmap(ServerBitmap* bitmap) 3787 { 3788 BAutolock _(fMapLocker); 3789 3790 try { 3791 fBitmapMap.insert(std::make_pair(bitmap->Token(), BReference<ServerBitmap>(bitmap, false))); 3792 } catch (std::bad_alloc& exception) { 3793 return false; 3794 } 3795 3796 bitmap->SetOwner(this); 3797 return true; 3798 } 3799 3800 3801 void 3802 ServerApp::_DeleteBitmap(ServerBitmap* bitmap) 3803 { 3804 ASSERT(fMapLocker.IsLocked()); 3805 3806 gBitmapManager->BitmapRemoved(bitmap); 3807 fBitmapMap.erase(bitmap->Token()); 3808 } 3809 3810 3811 ServerBitmap* 3812 ServerApp::_FindBitmap(int32 token) const 3813 { 3814 ASSERT(fMapLocker.IsLocked()); 3815 3816 BitmapMap::const_iterator iterator = fBitmapMap.find(token); 3817 if (iterator == fBitmapMap.end()) 3818 return NULL; 3819 3820 return iterator->second; 3821 } 3822 3823 3824 ServerPicture* 3825 ServerApp::_FindPicture(int32 token) const 3826 { 3827 ASSERT(fMapLocker.IsLocked()); 3828 3829 PictureMap::const_iterator iterator = fPictureMap.find(token); 3830 if (iterator == fPictureMap.end()) 3831 return NULL; 3832 3833 return iterator->second; 3834 } 3835