ServerApp class###############ServerApps are the server-side counterpart to BApplications. Theymonitor for messages for the BApplication, create BWindows and BBitmaps,and provide a channel for the app_server to send messages to a userapplication without having a window.Member Functions================- ServerApp(port_id sendport, port_id rcvport, const char\*signature, thread_id thread_bapp)- ~ServerApp(void)- bool Run(void)- static int32 MonitorApp(void \*data)- void Lock(void)- void Unlock(void)- bool IsLocked(void)- void WindowBroadcast(int32 code)- bool IsActive(void)- bool PingTarget(void)- void DispatchMessage(int32 code, int8 \*buffer)ServerApp(port_id sendport, port_id rcvport, const char \*sig, thread_id thread_bapp)-------------------------------------------------------------------------------------1. Create the window list as empty2. Save sendport, rcvport, sig, and thread_bapp to the respectiveServerApp members3. Set quit_app flag to false4. Create the window list lock~ServerApp(void)----------------1. Empty and delete window list and accompanying windows2. Wait for the monitoring thread to exit3. Call CursorManager::RemoveAppCursors(this)4. Delete the window list lock5. If monitoring thread still active, kill it (in case app is deletedwithout a quit message)bool Run(void)--------------Run() simply makes a ServerApp start monitoring for messages from itsBApplication, telling it to quit if there is a problem.1. Spawn the monitoring thread (which utilizes MonitorApp()) 2) If anyerror, tell the BApplication to quit, spit an error to stderr, andreturn false2. Resume the monitoring thread3. Return truestatic int32 MonitorApp(void \*data)------------------------------------Thread function for monitoring for messages from the ServerApp'sBApplication.1. Call port_buffer_size - which will block if the port is empty2. Allocate a buffer on the heap if the port buffer size is greater than 03. Read the port4. Pass specified messages to DispatchMessage() for processing, spittingout an error message to stderr if the message's code is unrecognized5. Return from DispatchMessage() and free the message buffer if one wasallocated6. If the message code matches the B_QUIT_REQUESTED definition and thequit_app flag is true, fall out of the infinite message-monitoring loop.Otherwise continue to next iteration7. Send a DELETE_APP message to the server's main message to forcedeleting of the ServerApp instance and exitbool IsActive(void)-------------------Used for determining whether the application is the active one. Simplyreturns the isactive flag.void PingTarget(void)---------------------PingTarget() is called only from the Picasso thread of the app_serverin order to determine whether its respective BApplication stillexists. BApplications have been known to crash from time to timewithout the common courtesy of notifying the server of its intentions.;D1. Call get_thread_info() with the app's thread_id2. if it returns anything but B_OK, return false. Otherwise, returntrue.void DispatchMessage(int32 code, int8 \*buffer)-----------------------------------------------DispatchMessage implements all the code necessary to respond to agiven message sent to the ServerApp on its receiving message port.This allows for clearer and more manageable code.CREATE_WINDOW.............Sent by a new BWindow object via synchronous PortLink messaging. Setup the corresponding ServerWindow and reply to the BWindow with thenew port to which it will send future communications with the AppServer.Attached Data:+-----------------------------------+-----------------------------------+| port_id reply_port | port to which the server is to || | reply in response to the current || | message |+-----------------------------------+-----------------------------------+| BRect wframe | frame of the requesting BWindow |+-----------------------------------+-----------------------------------+| uint32 wflags | flag data of the requesting || | BWindow |+-----------------------------------+-----------------------------------+| port_id win_port | receiver port of the requesting || | BWindow |+-----------------------------------+-----------------------------------+| uint32 workspaces | workspaces on which the BWindow || | is to appear |+-----------------------------------+-----------------------------------+| const char \*title | title of the requesting BWindow |+-----------------------------------+-----------------------------------+1. Get all attached data2. Acquire the window list lock3. Allocate a ServerWindow object and add it to the list4. Release window list lock5. Send the message SET_SERVER_PORT (with the ServerWindow's receiverport attached to the reply portDELETE_APP..........Sent by a ServerWindow when told to quit. It is identified by theunique ID assigned to its thread.Attached Data:+-----------------------------------+-----------------------------------+| thread_id win_thread | Thread id of the ServerWindow || | sending this message |+-----------------------------------+-----------------------------------+1. Get window's thread_id2. Acquire window list lock3. Iterate through the window list, searching for the ServerWindowobject with the sent thread_id4. Remove the object from the list and delete it5. Release window list lockSET_CURSOR_DATA...............Received from the ServerApp's BApplication when SetCursor(const void\*) is called.Attached Data:+-----------------------------------+-----------------------------------+| int8 cursor[68] | Cursor data in the format as || | defined in the BeBook |+-----------------------------------+-----------------------------------+1. Create a ServerCursor from the attached cursor data2. Add the new ServerCursor to the CursorManager and then callCursorManager::SetCursorSET_CURSOR_BCURSOR..................Received from the ServerApp's BApplication when SetCursor(BCursor \*,bool) is called.Attached Data:+-----------------------------------+-----------------------------------+| int32 token | Token identifier of cursor in the || | BCursor class |+-----------------------------------+-----------------------------------+1) Get the attached token and call CursorManager::SetCursor(token)B_QUIT_REQUESTED................Received from the BApplication when quits, so set the quit flag andask the server to delete the objectAttached Data: None1) Set quit_app flag to trueUPDATE_DECORATOR................Received from the poller thread when the window decorator for thesystem has changed.Attached Data: None1) Call WindowBroadcast(UPDATE_DECORATOR)void WindowBroadcast(int32 code)--------------------------------Similar to AppServer::Broadcast(), this sends a message to allServerWindows which belong to the ServerApp.1) Acquire window list lock2) Create a PortLink instance and set its message code to the passedparameter.3) Iterate through the window list, targeting the PortLink instance toeach ServerWindow's message port and calling Flush().4) Release window list lockvoid Lock(void), void Unlock(void), bool IsLocked(void)-------------------------------------------------------These functions are used to regulate access to the ServerApp's datamembers. Lock() acquires the internal semaphore, Unlock() releases it,and IsLocked returns true only if the semaphore's value is positive.