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
fCurrentViewis already set. If it is, it prints a debug message and breaks the execution. - If
fCurrentViewis not set, it calls_CreateView()passingNULLas 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_CREATEmessage 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

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