In the Client BWindow_InitData function after getting the reply from the app server. There is the task for the view creation.
void
BWindow::_InitData(BRect frame, const char* title, window_look look,
window_feel feel, uint32 flags, uint32 workspace, int32 bitmapToken)
{
STRACE(("BWindow::InitData()\n"));
if (be_app == NULL) {
debugger("You need a valid BApplication object before interacting with "
"the app_server");
return;
}
frame.left = roundf(frame.left);
frame.top = roundf(frame.top);
frame.right = roundf(frame.right);
frame.bottom = roundf(frame.bottom);
fFrame = frame;
if (title == NULL)
title = "";
fTitle = strdup(title);
_SetName(title);
fFeel = feel;
fLook = look;
fFlags = flags | B_ASYNCHRONOUS_CONTROLS;
fInTransaction = bitmapToken >= 0;
fUpdateRequested = false;
fActive = false;
fShowLevel = 1;
fTopView = NULL;
fFocus = NULL;
fLastMouseMovedView = NULL;
fKeyMenuBar = NULL;
fDefaultButton = NULL;
// Shortcut 'Q' is handled in _HandleKeyDown() directly, as its message
// get sent to the application, and not one of our handlers.
// It is only installed for non-modal windows, though.
fNoQuitShortcut = IsModal();
if ((fFlags & B_NOT_CLOSABLE) == 0 && !IsModal()) {
// Modal windows default to non-closable, but you can add the
// shortcut manually, if a different behaviour is wanted
AddShortcut('W', B_COMMAND_KEY, new BMessage(B_QUIT_REQUESTED));
}
// Edit modifier keys
AddShortcut('X', B_COMMAND_KEY, new BMessage(B_CUT), NULL);
AddShortcut('C', B_COMMAND_KEY, new BMessage(B_COPY), NULL);
AddShortcut('V', B_COMMAND_KEY, new BMessage(B_PASTE), NULL);
AddShortcut('A', B_COMMAND_KEY, new BMessage(B_SELECT_ALL), NULL);
// Window modifier keys
AddShortcut('M', B_COMMAND_KEY | B_CONTROL_KEY,
new BMessage(_MINIMIZE_), NULL);
AddShortcut('Z', B_COMMAND_KEY | B_CONTROL_KEY,
new BMessage(_ZOOM_), NULL);
AddShortcut('Z', B_SHIFT_KEY | B_COMMAND_KEY | B_CONTROL_KEY,
new BMessage(_ZOOM_), NULL);
AddShortcut('H', B_COMMAND_KEY | B_CONTROL_KEY,
new BMessage(B_HIDE_APPLICATION), NULL);
AddShortcut('F', B_COMMAND_KEY | B_CONTROL_KEY,
new BMessage(_SEND_TO_FRONT_), NULL);
AddShortcut('B', B_COMMAND_KEY | B_CONTROL_KEY,
new BMessage(_SEND_BEHIND_), NULL);
// We set the default pulse rate, but we don't start the pulse
fPulseRate = 500000;
fPulseRunner = NULL;
fIsFilePanel = false;
fMenuSem = -1;
fMinimized = false;
fMaxZoomHeight = 32768.0;
fMaxZoomWidth = 32768.0;
fMinHeight = 0.0;
fMinWidth = 0.0;
fMaxHeight = 32768.0;
fMaxWidth = 32768.0;
fLastViewToken = B_NULL_TOKEN;
// TODO: other initializations!
fOffscreen = false;
// Create the server-side window
port_id receivePort = create_port(B_LOOPER_PORT_DEFAULT_CAPACITY,
"w<app_server");
if (receivePort < B_OK) {
// TODO: huh?
debugger("Could not create BWindow's receive port, used for "
"interacting with the app_server!");
delete this;
return;
}
STRACE(("BWindow::InitData(): contacting app_server...\n"));
// let app_server know that a window has been created.
fLink = new(std::nothrow) BPrivate::PortLink(
BApplication::Private::ServerLink()->SenderPort(), receivePort);
if (fLink == NULL) {
// Zombie!
return;
}
{
BPrivate::AppServerLink lockLink;
// we're talking to the server application using our own
// communication channel (fLink) - we better make sure no one
// interferes by locking that channel (which AppServerLink does
// implicetly)
if (bitmapToken < 0) {
fLink->StartMessage(AS_CREATE_WINDOW);
} else {
fLink->StartMessage(AS_CREATE_OFFSCREEN_WINDOW);
fLink->Attach<int32>(bitmapToken);
fOffscreen = true;
}
fLink->Attach<BRect>(fFrame);
fLink->Attach<uint32>((uint32)fLook);
fLink->Attach<uint32>((uint32)fFeel);
fLink->Attach<uint32>(fFlags);
fLink->Attach<uint32>(workspace);
fLink->Attach<int32>(_get_object_token_(this));
fLink->Attach<port_id>(receivePort);
fLink->Attach<port_id>(fMsgPort);
fLink->AttachString(title);
port_id sendPort;
int32 code;
if (fLink->FlushWithReply(code) == B_OK
&& code == B_OK
&& fLink->Read<port_id>(&sendPort) == B_OK) {
// read the frame size and its limits that were really
// enforced on the server side
fLink->Read<BRect>(&fFrame);
fLink->Read<float>(&fMinWidth);
fLink->Read<float>(&fMaxWidth);
fLink->Read<float>(&fMinHeight);
fLink->Read<float>(&fMaxHeight);
fMaxZoomWidth = fMaxWidth;
fMaxZoomHeight = fMaxHeight;
} else
sendPort = -1;
// Redirect our link to the new window connection
fLink->SetSenderPort(sendPort);
STRACE(("Server says that our send port is %ld\n", sendPort));
}
STRACE(("Window locked?: %s\n", IsLocked() ? "True" : "False"));
_CreateTopView();
}In the last chapter we have explored all the function of this snippet but _CreateTopView() is left. Now it's time to explore this one.
#1 _CreateTopView()
This function is defined at: src/kits/interface/Window.cpp
void
BWindow::_CreateTopView()
{
STRACE(("_CreateTopView(): enter\n"));
BRect frame = fFrame.OffsetToCopy(B_ORIGIN);
// TODO: what to do here about std::nothrow?
fTopView = new BView(frame, "fTopView", B_FOLLOW_ALL, B_WILL_DRAW);
fTopView->fTopLevelView = true;
//inhibit check_lock()
fLastViewToken = _get_object_token_(fTopView);
// set fTopView's owner, add it to window's eligible handler list
// and also set its next handler to be this window.
STRACE(("Calling setowner fTopView = %p this = %p.\n",
fTopView, this));
fTopView->_SetOwner(this);
// we can't use AddChild() because this is the top view
fTopView->_CreateSelf();
STRACE(("BuildTopView ended\n"));
}In the _CreateTopView function of the BWindow class, a top-level BView is created and initialized. Here's what happens in this function:
BRect frame = fFrame.OffsetToCopy(B_ORIGIN);- It creates a BRect named frame by copying the window's frame and offsetting it to the origin (0,0).
fTopView = new BView(frame, "fTopView", B_FOLLOW_ALL, B_WILL_DRAW);- It creates a new
BViewnamedfTopViewusing the frame calculated earlier. The view is given the name"fTopView",follows all resizing of its parent, and will draw its content.
fTopView->fTopLevelView = true;- It sets the
fTopLevelViewmember variable of thefTopViewtotrue. This likely indicates that this view is the top-level view within the window.
//inhibit check_lock()
fLastViewToken = _get_object_token_(fTopView);- It inhibits the check for locks on the view by setting the
fLastViewTokenmember variable to the object token offTopView.
fTopView->_SetOwner(this);- It sets the owner of
fTopViewto the window itself by calling_SetOwner(this)onfTopView. This associates the window with the view.
fTopView->_CreateSelf();- It then calls
_CreateSelf()onfTopViewto initialize the view. This function likely performs internal setup and initialization for the view.
#2 BView(BRect frame, const char* name, uint32 resizingMode, uint32 flags) Constructor
This constructor is defined at: src/kits/interface/View.cpp
BView::BView(BRect frame, const char* name, uint32 resizingMode, uint32 flags)
:
BHandler(name)
{
_InitData(frame, name, resizingMode, flags);
}The constructor BView::BView initializes a BView object with the provided parameters. Here's what it does:
- It calls the constructor of the base class
BHandlerwith the provided name, initializing the handler part of theBView. - It then calls the
_InitDatafunction with the provided frame, name, resizing mode, and flags. This function initializes the data members of theBViewobject.
#3 _InitData(BRect frame, const char* name, uint32 resizingMode, uint32 flags)
This function is defined at: src/kits/interface/View.cpp
void
BView::_InitData(BRect frame, const char* name, uint32 resizingMode,
uint32 flags)
{
// Info: The name of the view is set by BHandler constructor
STRACE(("BView::_InitData: enter\n"));
// initialize members
if ((resizingMode & ~_RESIZE_MASK_) || (flags & _RESIZE_MASK_))
printf("%s BView::_InitData(): resizing mode or flags swapped\n", name);
// There are applications that swap the resize mask and the flags in the
// BView constructor. This does not cause problems under BeOS as it just
// ors the two fields to one 32bit flag.
// For now we do the same but print the above warning message.
// TODO: this should be removed at some point and the original
// version restored:
// fFlags = (resizingMode & _RESIZE_MASK_) | (flags & ~_RESIZE_MASK_);
fFlags = resizingMode | flags;
// handle rounding
frame.left = roundf(frame.left);
frame.top = roundf(frame.top);
frame.right = roundf(frame.right);
frame.bottom = roundf(frame.bottom);
fParentOffset.Set(frame.left, frame.top);
fOwner = NULL;
fParent = NULL;
fNextSibling = NULL;
fPreviousSibling = NULL;
fFirstChild = NULL;
fShowLevel = 0;
fTopLevelView = false;
fCurrentPicture = NULL;
fCommArray = NULL;
fVerScroller = NULL;
fHorScroller = NULL;
fIsPrinting = false;
fAttached = false;
// TODO: Since we cannot communicate failure, we don't use std::nothrow here
// TODO: Maybe we could auto-delete those views on AddChild() instead?
fState = new BPrivate::ViewState;
fBounds = frame.OffsetToCopy(B_ORIGIN);
fShelf = NULL;
fEventMask = 0;
fEventOptions = 0;
fMouseEventOptions = 0;
fLayoutData = new LayoutData;
fToolTip = NULL;
if ((flags & B_SUPPORTS_LAYOUT) != 0) {
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
SetLowUIColor(ViewUIColor());
SetHighUIColor(B_PANEL_TEXT_COLOR);
}
} fFlags = resizingMode | flags;- It combines the resizing mode and flags to set the view's flags.
// handle rounding
frame.left = roundf(frame.left);
frame.top = roundf(frame.top);
frame.right = roundf(frame.right);
frame.bottom = roundf(frame.bottom);- It rounds the coordinates of the frame to integer values using the
roundffunction.
#4 _CreateSelf()
This function is defined at: src/kits/interface/View.cpp
bool
BView::_CreateSelf()
{
// AS_VIEW_CREATE & AS_VIEW_CREATE_ROOT do not use the
// current view mechanism via _CheckLockAndSwitchCurrent() - the token
// of the view and its parent are both send to the server.
if (fTopLevelView)
fOwner->fLink->StartMessage(AS_VIEW_CREATE_ROOT);
else
fOwner->fLink->StartMessage(AS_VIEW_CREATE);
fOwner->fLink->Attach<int32>(_get_object_token_(this));
fOwner->fLink->AttachString(Name());
fOwner->fLink->Attach<BRect>(Frame());
fOwner->fLink->Attach<BPoint>(LeftTop());
fOwner->fLink->Attach<uint32>(ResizingMode());
fOwner->fLink->Attach<uint32>(fEventMask);
fOwner->fLink->Attach<uint32>(fEventOptions);
fOwner->fLink->Attach<uint32>(Flags());
fOwner->fLink->Attach<bool>(IsHidden(this));
fOwner->fLink->Attach<rgb_color>(fState->view_color);
if (fTopLevelView)
fOwner->fLink->Attach<int32>(B_NULL_TOKEN);
else
fOwner->fLink->Attach<int32>(_get_object_token_(fParent));
fOwner->fLink->Flush();
_CheckOwnerLockAndSwitchCurrent();
fState->UpdateServerState(*fOwner->fLink);
// we create all its children, too
for (BView* child = fFirstChild; child != NULL;
child = child->fNextSibling) {
child->_CreateSelf();
}
fOwner->fLink->Flush();
return true;
}Determining Creation Type:
- The function distinguishes between creating a top-level view (
fTopLevelView) and creating a regular view. - For top-level view, a special message (
AS_VIEW_CREATE_ROOT) is sent to the server. Otherwise, the standardAS_VIEW_CREATEmessage is used.
Preparing Message:
- The function starts constructing the message to create the view by using the appropriate message type (
AS_VIEW_CREATE_ROOTorAS_VIEW_CREATE). - It attaches various parameters to the message, including:
- Token of the view: Identifies the view uniquely.
- Name of the view.
- Frame: Defines the position and size of the view.
- Position (Left-Top): Specifies the top-left corner of the view within its parent's coordinate system.
- Resizing mode: Determines how the view behaves when its parent is resized.
- Event mask: Specifies which types of events the view should receive.
- Event options: Additional options related to event handling.
- Flags: Various flags indicating properties and behavior of the view.
- Visibility: Indicates whether the view is hidden.
- View color: Specifies the color of the view.
- Token of the parent view: Identifies the parent view of the current view.
Sending Message:
- The constructed message, along with all attached parameters, is sent to the server via the owner's message link (fOwner->fLink).
- This communication with the server initializes the view's representation on the screen.
Updating Server State:
- After sending the creation message, the function updates the server-side state of the view based on any changes that occurred during creation.
- This ensures that the server's representation of the view is synchronized with the client-side representation.
Creating Children:
- The function iterates over all child views of the current view (
fFirstChild) and recursively calls_CreateSelf()for each child. - This process ensures that all child views are also created and properly initialized.
Finalizing Message:
- Once all child views are created, another flush operation is performed on the message link to ensure all pending messages are sent to the server.
Returning Success:
- Finally, the function returns
trueto indicate that the view creation process was successful.

Join the discussion
Sign in with your account to post comments, reply to others, and participate in the conversation.
Login to Comment