From ff32e5158c98c4dd9eab938af32667fff625786e Mon Sep 17 00:00:00 2001 From: Stefano Ceccherini Date: Thu, 3 May 2007 14:52:13 +0000 Subject: [PATCH] ServerPicture now uses a BPositionIO object as internal storage instead of BMallocIO. Added an additional constructor to handle a file. This is in preparation of implementing BView::SetDiskMode(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20996 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/Jamfile | 2 +- src/servers/app/ServerApp.cpp | 8 +- src/servers/app/ServerPicture.cpp | 126 +++++++++++++++++++++++++++--- src/servers/app/ServerPicture.h | 11 ++- src/servers/app/ServerWindow.cpp | 1 - src/servers/app/ViewLayer.cpp | 2 - 6 files changed, 126 insertions(+), 24 deletions(-) diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index b780a701ab..7e8eea8739 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -1,7 +1,7 @@ SubDir HAIKU_TOP src servers app ; UseLibraryHeaders png zlib ; -UsePrivateHeaders app graphics input interface kernel shared ; +UsePrivateHeaders app graphics input interface kernel shared storage ; UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing ] ; UseFreeTypeHeaders ; diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 1de0f1cfd9..c50214ff19 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -740,12 +740,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) link.Read(&token); ServerPicture *picture = FindPicture(token); if (picture != NULL) { - fLink.StartMessage(B_OK); - - // TODO: support nested pictures (subpictures) - fLink.Attach(0); // number of subpictures - fLink.Attach(picture->DataLength()); - fLink.Attach(picture->Data(), picture->DataLength()); + picture->ExportData(fLink); + // ExportData() calls StartMessage() already } else fLink.StartMessage(B_ERROR); diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index f9db8b8168..888cc8da76 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -17,8 +17,10 @@ #include "WindowLayer.h" #include +#include #include #include +#include #include #include @@ -661,23 +663,61 @@ const void *tableEntries[] = { // ServerPicture ServerPicture::ServerPicture() - :PictureDataWriter(&fData) + : + PictureDataWriter(), + fData(NULL) { fToken = gTokenSpace.NewToken(kPictureToken, this); + fData = new (std::nothrow) BMallocIO(); + + PictureDataWriter::SetTo(fData); } ServerPicture::ServerPicture(const ServerPicture &picture) - :PictureDataWriter(&fData) + : + PictureDataWriter(), + fData(NULL) { fToken = gTokenSpace.NewToken(kPictureToken, this); - fData.Write(picture.Data(), picture.DataLength()); + BMallocIO *mallocIO = new (std::nothrow) BMallocIO(); + if (mallocIO == NULL) + return; + + fData = mallocIO; + + const off_t size = picture.DataLength(); + if (mallocIO->SetSize(size) < B_OK) + return; + + picture.fData->ReadAt(0, const_cast(mallocIO->Buffer()), size); + + PictureDataWriter::SetTo(fData); +} + + +ServerPicture::ServerPicture(const char *fileName, const int32 &offset) + : + PictureDataWriter(), + fData(NULL) +{ + BPrivate::Storage::OffsetFile *file = + new BPrivate::Storage::OffsetFile(new BFile(fileName, B_READ_WRITE), (off_t)offset); + + if (file == NULL || file->InitCheck() != B_OK) + return; + + fData = file; + fToken = gTokenSpace.NewToken(kPictureToken, this); + + PictureDataWriter::SetTo(fData); } ServerPicture::~ServerPicture() { + delete fData; gTokenSpace.RemoveToken(fToken); } @@ -717,11 +757,30 @@ ServerPicture::SyncState(ViewLayer *view) void ServerPicture::Play(ViewLayer *view) { - PicturePlayer player(fData.Buffer(), fData.BufferLength(), NULL); + // TODO: for now: then change PicturePlayer to accept a BPositionIO object + BMallocIO *mallocIO = dynamic_cast(fData); + if (mallocIO == NULL) + return; + + PicturePlayer player(mallocIO->Buffer(), mallocIO->BufferLength(), NULL); player.Play(const_cast(tableEntries), sizeof(tableEntries) / sizeof(void *), view); } +off_t +ServerPicture::DataLength() const +{ + if (fData == NULL) + return 0; + off_t size; + fData->GetSize(&size); + return size; +} + + +#define BUFFER_SIZE 4096 + + status_t ServerPicture::ImportData(BPrivate::LinkReceiver &link) { @@ -733,14 +792,59 @@ ServerPicture::ImportData(BPrivate::LinkReceiver &link) int32 size = 0; link.Read(&size); - if (fData.SetSize(size) != B_OK) - return B_ERROR; - // TODO: The best way to do this would be to read the data into - // a temporary buffer, and then use the BMallocIO::Write() method, - // but this way we avoid an extra copy. Unfortunately BMallocIO::Write() - // only accepts a pointer to raw data... - link.Read(const_cast(fData.Buffer()), size); + off_t oldPosition = fData->Position(); + fData->Seek(0, SEEK_SET); + + ssize_t toWrite = size; + // TODO: For some reason, this doesn't work. Bug in LinkReceiver ? + /*char buffer[BUFFER_SIZE]; + while (toWrite > 0) { + ssize_t read = link.Read(buffer, toWrite > BUFFER_SIZE ? BUFFER_SIZE : toWrite); + if (read < B_OK) + return (status_t)read; + fData->Write(buffer, read); + toWrite -= read; + }*/ + + char buffer[toWrite]; + link.Read(buffer, toWrite); + fData->Write(buffer, toWrite); + + fData->Seek(oldPosition, SEEK_SET); + + return B_OK; +} + + +status_t +ServerPicture::ExportData(BPrivate::PortLink &link) +{ + link.StartMessage(B_OK); + + off_t oldPosition = fData->Position(); + fData->Seek(0, SEEK_SET); + + int32 subPicturesCount = 0; + link.Attach(subPicturesCount); + + off_t size = 0; + fData->GetSize(&size); + link.Attach((int32)size); + + ssize_t toWrite = size; + char buffer[BUFFER_SIZE]; + while (toWrite > 0) { + ssize_t read = fData->Read(buffer, toWrite > BUFFER_SIZE ? BUFFER_SIZE : toWrite); + if (read < B_OK) + return (status_t)read; + link.Attach(buffer, read); + toWrite -= read; + } + + fData->Seek(oldPosition, SEEK_SET); return B_OK; } + + diff --git a/src/servers/app/ServerPicture.h b/src/servers/app/ServerPicture.h index 867f808fe3..ca986f4adb 100644 --- a/src/servers/app/ServerPicture.h +++ b/src/servers/app/ServerPicture.h @@ -5,6 +5,10 @@ #include +#include + // TODO: For some reason, the forward declaration "class BPrivate::PortLink" causes compiling errors + + class ServerApp; class ViewLayer; class BPrivate::LinkReceiver; @@ -22,20 +26,21 @@ public: void Play(ViewLayer *view); - const void *Data() const { return fData.Buffer(); } - int32 DataLength() const { return fData.BufferLength(); } + off_t DataLength() const; status_t ImportData(BPrivate::LinkReceiver &link); + status_t ExportData(BPrivate::PortLink &link); private: friend class ServerApp; ServerPicture(); ServerPicture(const ServerPicture &); + ServerPicture(const char *fileName, const int32 &offset); ~ServerPicture(); int32 fToken; - BMallocIO fData; + BPositionIO *fData; // DrawState *fState; }; diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index c3f50b22dd..f5b486defc 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -2783,7 +2783,6 @@ ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState) fDirectWindowData->buffer_info->pixel_format = buffer->ColorSpace(); fDirectWindowData->buffer_info->layout = B_BUFFER_NONINTERLEAVED; fDirectWindowData->buffer_info->orientation = B_BUFFER_TOP_TO_BOTTOM; // TODO - fDirectWindowData->buffer_info->window_bounds = to_clipping_rect(fWindowLayer->Frame()); // TODO: Review this diff --git a/src/servers/app/ViewLayer.cpp b/src/servers/app/ViewLayer.cpp index b83d765ca3..a49aa8dafb 100644 --- a/src/servers/app/ViewLayer.cpp +++ b/src/servers/app/ViewLayer.cpp @@ -125,8 +125,6 @@ ViewLayer::~ViewLayer() // if (fWindow && this == fWindow->TopLayer()) // fWindow->SetTopLayer(NULL); -// - // TODO: Don't know yet if we should also delete fPicture if (fCursor) fCursor->Release();