1ServerApp class 2############### 3 4ServerApps are the server-side counterpart to BApplications. They 5monitor for messages for the BApplication, create BWindows and BBitmaps, 6and provide a channel for the app_server to send messages to a user 7application without having a window. 8 9Member Functions 10================ 11 12- ServerApp(port_id sendport, port_id rcvport, const char\*signature, thread_id thread_bapp) 13- ~ServerApp(void) 14- bool Run(void) 15- static int32 MonitorApp(void \*data) 16- void Lock(void) 17- void Unlock(void) 18- bool IsLocked(void) 19- void WindowBroadcast(int32 code) 20- bool IsActive(void) 21- bool PingTarget(void) 22- void DispatchMessage(int32 code, int8 \*buffer) 23 24ServerApp(port_id sendport, port_id rcvport, const char \*sig, thread_id thread_bapp) 25------------------------------------------------------------------------------------- 26 271. Create the window list as empty 282. Save sendport, rcvport, sig, and thread_bapp to the respective 29 ServerApp members 303. Set quit_app flag to false 314. Create the window list lock 32 33~ServerApp(void) 34---------------- 35 361. Empty and delete window list and accompanying windows 372. Wait for the monitoring thread to exit 383. Call CursorManager::RemoveAppCursors(this) 394. Delete the window list lock 405. If monitoring thread still active, kill it (in case app is deleted 41 without a quit message) 42 43bool Run(void) 44-------------- 45 46Run() simply makes a ServerApp start monitoring for messages from its 47BApplication, telling it to quit if there is a problem. 48 491. Spawn the monitoring thread (which utilizes MonitorApp()) 2) If any 50 error, tell the BApplication to quit, spit an error to stderr, and 51 return false 522. Resume the monitoring thread 533. Return true 54 55static int32 MonitorApp(void \*data) 56------------------------------------ 57 58Thread function for monitoring for messages from the ServerApp's 59BApplication. 60 611. Call port_buffer_size - which will block if the port is empty 622. Allocate a buffer on the heap if the port buffer size is greater than 0 633. Read the port 644. Pass specified messages to DispatchMessage() for processing, spitting 65 out an error message to stderr if the message's code is unrecognized 665. Return from DispatchMessage() and free the message buffer if one was 67 allocated 686. If the message code matches the B_QUIT_REQUESTED definition and the 69 quit_app flag is true, fall out of the infinite message-monitoring loop. 70 Otherwise continue to next iteration 717. Send a DELETE_APP message to the server's main message to force 72 deleting of the ServerApp instance and exit 73 74bool IsActive(void) 75------------------- 76 77Used for determining whether the application is the active one. Simply 78returns the isactive flag. 79 80void PingTarget(void) 81--------------------- 82 83PingTarget() is called only from the Picasso thread of the app_server 84in order to determine whether its respective BApplication still 85exists. BApplications have been known to crash from time to time 86without the common courtesy of notifying the server of its intentions. 87;D 88 891. Call get_thread_info() with the app's thread_id 902. if it returns anything but B_OK, return false. Otherwise, return 91 true. 92 93void DispatchMessage(int32 code, int8 \*buffer) 94----------------------------------------------- 95 96DispatchMessage implements all the code necessary to respond to a 97given message sent to the ServerApp on its receiving message port. 98This allows for clearer and more manageable code. 99 100CREATE_WINDOW 101............. 102 103Sent by a new BWindow object via synchronous PortLink messaging. Set 104up the corresponding ServerWindow and reply to the BWindow with the 105new port to which it will send future communications with the App 106Server. 107 108Attached Data: 109 110+-----------------------------------+-----------------------------------+ 111| port_id reply_port | port to which the server is to | 112| | reply in response to the current | 113| | message | 114+-----------------------------------+-----------------------------------+ 115| BRect wframe | frame of the requesting BWindow | 116+-----------------------------------+-----------------------------------+ 117| uint32 wflags | flag data of the requesting | 118| | BWindow | 119+-----------------------------------+-----------------------------------+ 120| port_id win_port | receiver port of the requesting | 121| | BWindow | 122+-----------------------------------+-----------------------------------+ 123| uint32 workspaces | workspaces on which the BWindow | 124| | is to appear | 125+-----------------------------------+-----------------------------------+ 126| const char \*title | title of the requesting BWindow | 127+-----------------------------------+-----------------------------------+ 128 1291. Get all attached data 1302. Acquire the window list lock 1313. Allocate a ServerWindow object and add it to the list 1324. Release window list lock 1335. Send the message SET_SERVER_PORT (with the ServerWindow's receiver 134 port attached to the reply port 135 136DELETE_APP 137.......... 138 139Sent by a ServerWindow when told to quit. It is identified by the 140unique ID assigned to its thread. 141 142Attached Data: 143 144+-----------------------------------+-----------------------------------+ 145| thread_id win_thread | Thread id of the ServerWindow | 146| | sending this message | 147+-----------------------------------+-----------------------------------+ 148 1491. Get window's thread_id 1502. Acquire window list lock 1513. Iterate through the window list, searching for the ServerWindow 152 object with the sent thread_id 1534. Remove the object from the list and delete it 1545. Release window list lock 155 156SET_CURSOR_DATA 157............... 158 159Received from the ServerApp's BApplication when SetCursor(const void\*) is called. 160 161Attached Data: 162 163+-----------------------------------+-----------------------------------+ 164| int8 cursor[68] | Cursor data in the format as | 165| | defined in the BeBook | 166+-----------------------------------+-----------------------------------+ 167 1681. Create a ServerCursor from the attached cursor data 1692. Add the new ServerCursor to the CursorManager and then call 170 CursorManager::SetCursor 171 172SET_CURSOR_BCURSOR 173.................. 174 175Received from the ServerApp's BApplication when SetCursor(BCursor \*, 176bool) is called. 177 178Attached Data: 179 180+-----------------------------------+-----------------------------------+ 181| int32 token | Token identifier of cursor in the | 182| | BCursor class | 183+-----------------------------------+-----------------------------------+ 184 1851) Get the attached token and call CursorManager::SetCursor(token) 186 187B_QUIT_REQUESTED 188................ 189 190Received from the BApplication when quits, so set the quit flag and 191ask the server to delete the object 192 193Attached Data: None 194 195 1961) Set quit_app flag to true 197 198UPDATE_DECORATOR 199................ 200 201Received from the poller thread when the window decorator for the 202system has changed. 203 204Attached Data: None 205 2061) Call WindowBroadcast(UPDATE_DECORATOR) 207 208void WindowBroadcast(int32 code) 209-------------------------------- 210 211Similar to AppServer::Broadcast(), this sends a message to all 212ServerWindows which belong to the ServerApp. 213 2141) Acquire window list lock 2152) Create a PortLink instance and set its message code to the passed 216 parameter. 2173) Iterate through the window list, targeting the PortLink instance to 218 each ServerWindow's message port and calling Flush(). 2194) Release window list lock 220 221void Lock(void), void Unlock(void), bool IsLocked(void) 222------------------------------------------------------- 223 224These functions are used to regulate access to the ServerApp's data 225members. Lock() acquires the internal semaphore, Unlock() releases it, 226and IsLocked returns true only if the semaphore's value is positive. 227