In the last chapter we flushed the message AS_CREATE_ROOT
for the view root and AS_VIEW_CREATE
for the normal view. These messages are received by ServerWindow
in _DispatchMessage
function.
void
ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
{
switch (code) {
// other cases...
case AS_VIEW_CREATE_ROOT:
{
DTRACE(("ServerWindow %s: Message AS_VIEW_CREATE_ROOT\n", fTitle));
// Start receiving top_view data -- pass NULL as the parent view.
// This should be the *only* place where this happens.
if (fCurrentView != NULL) {
debug_printf("ServerWindow %s: Message "
"AS_VIEW_CREATE_ROOT: fCurrentView already set!!\n",
fTitle);
break;
}
_SetCurrentView(_CreateView(link, NULL));
fWindow->SetTopView(fCurrentView);
break;
}
case AS_VIEW_CREATE:
{
DTRACE(("ServerWindow %s: Message AS_VIEW_CREATE: View name: "
"%s\n", fTitle, fCurrentView->Name()));
View* parent = NULL;
View* newView = _CreateView(link, &parent);
if (parent != NULL && newView != NULL)
parent->AddChild(newView);
else {
delete newView;
debug_printf("ServerWindow %s: Message AS_VIEW_CREATE: "
"parent or newView NULL!!\n", fTitle);
}
break;
}
// Other cases...
- AS_VIEW_CREATE_ROOT:
- This case handles the creation of a top-level view, meaning a view that does not have a parent. It's the first view to be created in the window.
- The function checks if
fCurrentView
is already set. If it is, it prints a debug message and breaks the execution. - If
fCurrentView
is not set, it calls_CreateView()
passingNULL
as the parent view, indicating that this is the root/top-level view. - The newly created view is then set as the current view (
fCurrentView
) and is also set as the top view of the window (fWindow->SetTopView()
).
- AS_VIEW_CREATE:
- This case handles the creation of a regular view, i.e., a view that has a parent.
- The function begins by printing a debug message indicating the reception of the
AS_VIEW_CREATE
message and the name of the current view. - It then calls
_CreateView()
passing a pointer to a parent view (&parent
) as an argument. This function returns the newly created view. - If both the parent and the new view are not
NULL
, indicating successful creation, it adds the new view as a child to the parent view using theAddChild()
method. - If either the parent or the new view is
NULL
, it prints a debug message indicating the failure of view creation and deletes the new view to avoid memory leaks.
#1 _CreateView(link, NULL)
This function is defined: src/servers/app/ServerWindow.cpp
View*
ServerWindow::_CreateView(BPrivate::LinkReceiver& link, View** _parent)
{
// NOTE: no need to check for a lock. This is a private method.
int32 token;
BRect frame;
uint32 resizeMask;
uint32 eventMask;
uint32 eventOptions;
uint32 flags;
bool hidden;
int32 parentToken;
char* name = NULL;
rgb_color viewColor;
BPoint scrollingOffset;
link.Read<int32>(&token);
link.ReadString(&name);
link.Read<BRect>(&frame);
link.Read<BPoint>(&scrollingOffset);
link.Read<uint32>(&resizeMask);
link.Read<uint32>(&eventMask);
link.Read<uint32>(&eventOptions);
link.Read<uint32>(&flags);
link.Read<bool>(&hidden);
link.Read<rgb_color>(&viewColor);
link.Read<int32>(&parentToken);
STRACE(("ServerWindow(%s)::_CreateView()-> view %s, token %" B_PRId32 "\n",
fTitle, name, token));
View* newView;
if ((flags & kWorkspacesViewFlag) != 0) {
newView = new (nothrow) WorkspacesView(frame, scrollingOffset, name,
token, resizeMask, flags);
} else {
newView = new (nothrow) View(frame, scrollingOffset, name, token,
resizeMask, flags);
}
free(name);
if (newView == NULL)
return NULL;
if (newView->InitCheck() != B_OK) {
delete newView;
return NULL;
}
// there is no way of setting this, other than manually :-)
newView->SetViewColor(viewColor);
newView->SetHidden(hidden);
newView->SetEventMask(eventMask, eventOptions);
if (eventMask != 0 || eventOptions != 0) {
// fDesktop->UnlockSingleWindow();
// fDesktop->LockAllWindows();
fDesktop->UnlockAllWindows();
// TODO: possible deadlock
fDesktop->EventDispatcher().AddListener(EventTarget(),
newView->Token(), eventMask, eventOptions);
fDesktop->LockAllWindows();
// fDesktop->UnlockAllWindows();
// fDesktop->LockSingleWindow();
}
// Initialize the view with the current application plain font.
// NOTE: This might be out of sync with the global app_server plain
// font, but that is so on purpose! The client needs to resync itself
// with the app_server fonts upon notification, but if we just use
// the current font here, the be_plain_font on the client may still
// hold old values. So this needs to be an update initiated by the
// client application.
newView->CurrentState()->SetFont(App()->PlainFont());
if (_parent) {
View *parent;
if (App()->ViewTokens().GetToken(parentToken, B_HANDLER_TOKEN,
(void**)&parent) != B_OK
|| parent->Window()->ServerWindow() != this) {
debug_printf("View token not found!\n");
parent = NULL;
}
*_parent = parent;
}
return newView;
}
This function _CreateView
is responsible for creating views within the ServerWindow
.
- Reading Data from Message:
- It reads various pieces of information about the view from the incoming message received via the
link
. This includes:- token: An identifier for the view.
- name: The name of the view.
- frame: The position and size of the view.
- scrollingOffset: The scrolling offset of the view.
- resizeMask: Resizing behavior flags.
- eventMask and eventOptions: Event handling flags.
- flags: Additional flags for the view.
- hidden: Whether the view is initially hidden.
- viewColor: The color of the view.
- parentToken: Token of the parent view.
- It reads various pieces of information about the view from the incoming message received via the