bool StackAndTile::_HandleMessage(BPrivate::LinkReceiver& link, BPrivate::LinkSender& reply) { int32 what; link.Read<int32>(&what); switch (what) { case BPrivate::kSaveAllGroups: { BMessage allGroupsArchive; GroupIterator groups(this, fDesktop); while (true) { SATGroup* group = groups.NextGroup(); if (group == NULL) break; if (group->CountItems() <= 1) continue; BMessage groupArchive; if (group->ArchiveGroup(groupArchive) != B_OK) continue; allGroupsArchive.AddMessage("group", &groupArchive); } int32 size = allGroupsArchive.FlattenedSize(); char buffer[size]; if (allGroupsArchive.Flatten(buffer, size) == B_OK) { reply.StartMessage(B_OK); reply.Attach<int32>(size); reply.Attach(buffer, size); } else reply.StartMessage(B_ERROR); reply.Flush(); break; } case BPrivate::kRestoreGroup: { int32 size; if (link.Read<int32>(&size) == B_OK) { char buffer[size]; BMessage group; if (link.Read(buffer, size) == B_OK && group.Unflatten(buffer) == B_OK) { status_t status = SATGroup::RestoreGroup(group, this); reply.StartMessage(status); reply.Flush(); } } break; } default: return false; } return true; }
status_t ServerPicture::ImportData(BPrivate::LinkReceiver& link) { int32 size = 0; link.Read<int32>(&size); off_t oldPosition = fData->Position(); fData->Seek(0, SEEK_SET); status_t status = B_NO_MEMORY; char* buffer = new(std::nothrow) char[size]; if (buffer) { status = B_OK; ssize_t read = link.Read(buffer, size); if (read < B_OK || fData->Write(buffer, size) < B_OK) status = B_ERROR; delete [] buffer; } fData->Seek(oldPosition, SEEK_SET); return status; }
/*! \brief Message handling function for all messages sent to the app_server \param code ID of the message sent \param buffer Attachment buffer for the message. */ void AppServer::_DispatchMessage(int32 code, BPrivate::LinkReceiver& msg) { switch (code) { case AS_GET_DESKTOP: { Desktop* desktop = NULL; port_id replyPort; msg.Read<port_id>(&replyPort); int32 userID; msg.Read<int32>(&userID); char* targetScreen = NULL; msg.ReadString(&targetScreen); if (targetScreen != NULL && strlen(targetScreen) == 0) { free(targetScreen); targetScreen = NULL; } int32 version; if (msg.Read<int32>(&version) < B_OK || version != AS_PROTOCOL_VERSION) { syslog(LOG_ERR, "Application for user %ld with port %ld does " "not support the current server protocol.\n", userID, replyPort); } else { desktop = _FindDesktop(userID, targetScreen); if (desktop == NULL) { // we need to create a new desktop object for this user // TODO: test if the user exists on the system // TODO: maybe have a separate AS_START_DESKTOP_SESSION for // authorizing the user desktop = _CreateDesktop(userID, targetScreen); } } free(targetScreen); BPrivate::LinkSender reply(replyPort); if (desktop != NULL) { reply.StartMessage(B_OK); reply.Attach<port_id>(desktop->MessagePort()); } else reply.StartMessage(B_ERROR); reply.Flush(); break; } #if TEST_MODE case B_QUIT_REQUESTED: { // We've been asked to quit, so (for now) broadcast to all // desktops to quit. This situation will occur only when the server // is compiled as a regular Be application. fQuitting = true; while (fDesktops.CountItems() > 0) { Desktop *desktop = fDesktops.RemoveItemAt(0); thread_id thread = desktop->Thread(); desktop->PostMessage(B_QUIT_REQUESTED); // we just wait for the desktop to kill itself status_t status; wait_for_thread(thread, &status); } delete this; // we are now clear to exit exit(0); break; } #endif default: STRACE(("Server::MainLoop received unexpected code %ld (offset %ld)\n", code, code - SERVER_TRUE)); break; } }