status_t SATGroup::RestoreGroup(const BMessage& archive, StackAndTile* sat) { // create new group SATGroup* group = new (std::nothrow)SATGroup; if (!group) return B_NO_MEMORY; BReference<SATGroup> groupRef; groupRef.SetTo(group, true); int32 nHTabs, nVTabs; status_t status; status = archive.FindInt32("htab_count", &nHTabs); if (status != B_OK) return status; status = archive.FindInt32("vtab_count", &nVTabs); if (status != B_OK) return status; vector<BReference<Tab> > tempHTabs; for (int i = 0; i < nHTabs; i++) { BReference<Tab> tab = group->_AddHorizontalTab(); if (!tab) return B_NO_MEMORY; tempHTabs.push_back(tab); } vector<BReference<Tab> > tempVTabs; for (int i = 0; i < nVTabs; i++) { BReference<Tab> tab = group->_AddVerticalTab(); if (!tab) return B_NO_MEMORY; tempVTabs.push_back(tab); } BMessage areaArchive; for (int32 i = 0; archive.FindMessage("area", i, &areaArchive) == B_OK; i++) { uint32 leftTab, rightTab, topTab, bottomTab; if (areaArchive.FindInt32("left_tab", (int32*)&leftTab) != B_OK || areaArchive.FindInt32("right_tab", (int32*)&rightTab) != B_OK || areaArchive.FindInt32("top_tab", (int32*)&topTab) != B_OK || areaArchive.FindInt32("bottom_tab", (int32*)&bottomTab) != B_OK) return B_ERROR; if (leftTab >= tempVTabs.size() || rightTab >= tempVTabs.size()) return B_BAD_VALUE; if (topTab >= tempHTabs.size() || bottomTab >= tempHTabs.size()) return B_BAD_VALUE; Tab* left = tempVTabs[leftTab]; Tab* right = tempVTabs[rightTab]; Tab* top = tempHTabs[topTab]; Tab* bottom = tempHTabs[bottomTab]; // adding windows to area uint64 windowId; SATWindow* prevWindow = NULL; for (int32 i = 0; areaArchive.FindInt64("window", i, (int64*)&windowId) == B_OK; i++) { SATWindow* window = sat->FindSATWindow(windowId); if (!window) continue; if (prevWindow == NULL) { if (!group->AddWindow(window, left, top, right, bottom)) continue; prevWindow = window; } else { if (!prevWindow->StackWindow(window)) continue; prevWindow = window; } } } return B_OK; }
bool StackingEventHandler::HandleMessage(SATWindow* sender, BPrivate::LinkReceiver& link, BPrivate::LinkSender& reply) { Desktop* desktop = sender->GetDesktop(); StackAndTile* stackAndTile = sender->GetStackAndTile(); int32 what; link.Read<int32>(&what); switch (what) { case kAddWindowToStack: { port_id port; int32 token; team_id team; link.Read<port_id>(&port); link.Read<int32>(&token); link.Read<team_id>(&team); int32 position; if (link.Read<int32>(&position) != B_OK) return false; WindowArea* area = sender->GetWindowArea(); if (!area) return false; if (position < 0) position = area->WindowList().CountItems() - 1; SATWindow* parent = area->WindowList().ItemAt(position); Window* window = desktop->WindowForClientLooperPort(port); if (!parent || !window) { reply.StartMessage(B_BAD_VALUE); reply.Flush(); break; } SATWindow* candidate = stackAndTile->GetSATWindow(window); if (!candidate) return false; if (!parent->StackWindow(candidate)) return false; reply.StartMessage(B_OK); reply.Flush(); break; } case kRemoveWindowFromStack: { port_id port; int32 token; team_id team; link.Read<port_id>(&port); link.Read<int32>(&token); if (link.Read<team_id>(&team) != B_OK) return false; SATGroup* group = sender->GetGroup(); if (!group) return false; Window* window = desktop->WindowForClientLooperPort(port); if (!window) { reply.StartMessage(B_BAD_VALUE); reply.Flush(); break; } SATWindow* candidate = stackAndTile->GetSATWindow(window); if (!candidate) return false; if (!group->RemoveWindow(candidate, false)) return false; break; } case kRemoveWindowFromStackAt: { int32 position; if (link.Read<int32>(&position) != B_OK) return false; SATGroup* group = sender->GetGroup(); WindowArea* area = sender->GetWindowArea(); if (!area || !group) return false; SATWindow* removeWindow = area->WindowList().ItemAt(position); if (!removeWindow) { reply.StartMessage(B_BAD_VALUE); reply.Flush(); break; } if (!group->RemoveWindow(removeWindow, false)) return false; ServerWindow* window = removeWindow->GetWindow()->ServerWindow(); reply.StartMessage(B_OK); reply.Attach<port_id>(window->ClientLooperPort()); reply.Attach<int32>(window->ClientToken()); reply.Attach<team_id>(window->ClientTeam()); reply.Flush(); break; } case kCountWindowsOnStack: { WindowArea* area = sender->GetWindowArea(); if (!area) return false; reply.StartMessage(B_OK); reply.Attach<int32>(area->WindowList().CountItems()); reply.Flush(); break; } case kWindowOnStackAt: { int32 position; if (link.Read<int32>(&position) != B_OK) return false; WindowArea* area = sender->GetWindowArea(); if (!area) return false; SATWindow* satWindow = area->WindowList().ItemAt(position); if (!satWindow) { reply.StartMessage(B_BAD_VALUE); reply.Flush(); break; } ServerWindow* window = satWindow->GetWindow()->ServerWindow(); reply.StartMessage(B_OK); reply.Attach<port_id>(window->ClientLooperPort()); reply.Attach<int32>(window->ClientToken()); reply.Attach<team_id>(window->ClientTeam()); reply.Flush(); break; } case kStackHasWindow: { port_id port; int32 token; team_id team; link.Read<port_id>(&port); link.Read<int32>(&token); if (link.Read<team_id>(&team) != B_OK) return false; Window* window = desktop->WindowForClientLooperPort(port); if (!window) { reply.StartMessage(B_BAD_VALUE); reply.Flush(); break; } SATWindow* candidate = stackAndTile->GetSATWindow(window); if (!candidate) return false; WindowArea* area = sender->GetWindowArea(); if (!area) return false; reply.StartMessage(B_OK); reply.Attach<bool>(area->WindowList().HasItem(candidate)); reply.Flush(); break; } default: return false; } return true; }