1 2AppServer class 3############### 4 5The AppServer class sits at the top of the hierarchy, starting and 6stopping services, monitoring for messages, and so forth. 7 8Member Functions 9================ 10 11- AppServer(void) 12- ~AppServer(void) 13- static int32 Poller(void \*data) 14- static int32 Picasso(void \*data) 15- thread_id Run(void) 16- void MainLoop(void) 17- bool LoadDecorator(const char\*path) 18- void DispatchMessage(int32 code,int8 \*buffer) 19- void Broadcast(int32 code) 20- void HandleKeyMessage(int32 code, int8 \*buffer) 21 22Global Functions 23================ 24 25Decorator \* instantiate_decorator(Layer \*owner, uint32 wflags, uint32 wlook) 26 27AppServer(void) 28=============== 29 301. Create the message and input ports 312. Create any necessary semaphores for regulating the 3 main threads 323. Initialize all member variables 334. Allocate the application BList 345. Read in and process all configuration data 356. Initialize the desktop 367. Spawn the Picasso and Poller threads 37 38~AppServer(void) 39================ 40 411. Shut down the desktop 422. Empty and delete the application list 433. Wait for Picasso and Poller to exit 444. Free any allocated heap space 45 46void MainLoop(void) 47=================== 48 49MainLoop is one large loop used to monitor the main message port in 50the app_server thread. This is a standard port-monitoring loop code: 51 52 531. Call port_buffer_size - which will block if the port is empty 542. Allocate a buffer on the heap if the port buffer size is greater than 0 553. Read the port 564. Pass specified messages to DispatchMessage() for processing, spitting 57 out an error message to stderr if the message's code is unrecognized 585. Return from DispatchMessage() and free the message buffer if one was 59 allocated 606. If the message code matches the B_QUIT_REQUESTED definition and the 61 quit_server flag is true, fall out of the infinite message-monitoring 62 loop 63 64void DispatchMessage(int32 code, int8 \*buffer) 65=============================================== 66 67DispatchMessage implements all the code necessary to respond to a 68given message sent to the app_server on its main port. This allows for 69clearer and more manageable code. 70 71 72CREATE_APP 73---------- 74 75Sent by a new BApplication object via synchronous PortLink messaging. 76Set up the corresponding ServerApp and reply to the BApplication with 77the new port to which it will send future communications with the App 78Server. 79 80Attached Data: 81 82+-----------------------------------+-----------------------------------+ 83| port_id reply_port | port to which the server is to | 84| | reply in response to the current | 85| | message | 86+-----------------------------------+-----------------------------------+ 87| port_id app_port | message port for the requesting | 88| | BApplication | 89+-----------------------------------+-----------------------------------+ 90| int16 sig_length | length of the following | 91| | application signature | 92+-----------------------------------+-----------------------------------+ 93| const char \*signature | Signature of the requesting | 94| | BApplication | 95+-----------------------------------+-----------------------------------+ 96 97 981. Get all attached data 992. Acquire the application list lock 1003. Allocate a ServerApp object and add it to the list 1014. Release application list lock 1025. Acquire active application pointer lock 1036. Update active application pointer 1047. Release active application lock 1058. Send the message SET_SERVER_PORT (with the ServerApp's receiver port 106 attached) to the reply port 1079. Run() the new ServerApp instance 108 109DELETE_APP 110---------- 111 112Sent by a ServerApp when told to quit either by its BApplication or 113the Server itself (during shutdown). It is identified by the unique ID 114assigned to its thread. 115 116Attached Data: 117 118+-----------------------------------+-----------------------------------+ 119| thread_id app_thread | Thread id of the ServerApp | 120| | sending this message | 121+-----------------------------------+-----------------------------------+ 122 1231. Get app's thread_id 1242. Acquire application list lock 1253. Iterate through the application list, searching for the ServerApp 126 object with the sent thread_id 1274. Remove the object from the list and delete it 1285. Acquire active application lock 1296. Check to see if the application is active 1307. If application is/was active, set it to the previous application in 131 the list or NULL if there are no other active applications 1328. Release application list lock 1339. Release active application lock 134 135GET_SCREEN_MODE 136--------------- 137 138Received from the OpenBeOS Input Server when requesting the current 139screen settings via synchronous PortLink messaging. This is a 140temporary solution which will be deprecated as soon as the BScreen 141class is complete. 142 143Attached Data: 144 145+-----------------------------------+-----------------------------------+ 146| port_id reply_port | port to which the server is to | 147| | reply in response to the current | 148| | message | 149+-----------------------------------+-----------------------------------+ 150 1511. Get height, width, and color depth from the global graphics driver 152 object 1532. Attach via PortLink and reply to sender 154 155B_QUIT_REQUESTED 156---------------- 157 158Encountered only under testing situations where the Server is told to 159quit. 160 161Attached Data: None 162 1631. Set quit_server flag to true 1642. Call Broadcast(QUIT_APP) 165 166SET_DECORATOR 167------------- 168 169Received from just about anything when a new window decorator is 170chosen 171 172Attached Data: 173 174+-----------------------------------+-----------------------------------+ 175| const char \*path | Path to the proposed new | 176| | decorator | 177+-----------------------------------+-----------------------------------+ 178 1791. Get the path from the buffer 1802. Call LoadDecorator() 181 182void Run(void) 183============== 184 185Run() exists mostly for consistency with other regular applications. 186 1871) Call MainLoop() 188 189bool LoadDecorator(const char \*path) 190===================================== 191 192Allows for a simple way to change the current window decorator 193systemwide simply by specifying the path to the desired Decorator 194addon. 195 1961. Load the passed string as the path to an addon. 1972. Load all necessary symbols for the decorator 1983. Return false if things didn't go so well 1994. Call Broadcast(UPDATE_DECORATOR) 2005. Return true 201 202static int32 Picasso(void \*data) 203================================= 204 205Picasso is a function, despite its name, dedicated to ensuring that 206the server deallocates resources to a dead application. It consists of 207a while(!quit_server) loop as follows: 208 2091) Acquire the appliction list lock 2102) Iterate through the list, calling each ServerApp object's 211 PingTarget() method. 2123) If PingTarget returns false, remove the ServerApp from the list and 213 delete it. 2144) Release the appliction list lock 2155) snooze for 3 seconds 216 217static int32 Poller(void \*data) 218================================ 219 220Poller is the main workhorse of the AppServer class, polling the 221Server's input port constantly for any messages from the Input Server 222and calling the appropriate handlers. Like Picasso, it, too, is mostly 223a while(!quit_server) loop. 224 2251. Call port_buffer_size_etc() with a timeout of 3 seconds. 2262. Check to see if the port_buffer_size_etc() timed out and do a 227 continue to next iteration if it did. 2283. Allocate a buffer on the heap if the port buffer size is greater than 0 2294. Read the port 2305. Pass specified messages to DispatchMessage() for processing, spitting 231 out an error message to stderr if the message's code is unrecognized 2326. Return from DispatchMessage() and free the message buffer if one was 233 allocated 234 235Decorator \* instantiate_decorator(Layer \*owner, uint32 wflags, uint32 wlook) 236============================================================================== 237 238instantiate_decorator returns a new instance of the decorator 239currently in use. The caller is responsible for the memory allocated 240for the returned object. 241 2421. Acquire the decorator lock 2432. If create_decorator is NULL, create a new instance of the default 244 decorator 2453. If create_decorator is non-NULL, create a new decorator instance by 246 calling AppServer::create_decorator(). 2474. Release the decorator lock 2485. Return the newly allocated instance 249 250void Broadcast(int32 code) 251========================== 252 253Broadcast() provides the AppServer class with an easy way to send a 254quick message to all ServerApps. Primarily, this is called when a font 255or decorator has changed, or when the server is shutting down. It is 256not intended to do anything except send a quick message which requires 257no extra data, such as for some upadate signalling. 258 2591. Acquire application list lock 2602. Create a PortLink instance and set its message code to the passed 261 parameter. 2623. Iterate through the application list, targeting the PortLink instance 263 to each ServerApp's message port and calling Flush(). 2644. Release application list lock 265 266void HandleKeyMessage(int32 code, int8 \*buffer) 267================================================ 268 269Called from DispatchMessage to filter out App Server events and 270otherwise send keystrokes to the active application. 271 272B_KEY_DOWN 273---------- 274 275Sent when the user presses (or holds down) a key that's been mapped to 276a character. 277 278Attached Data: 279 280+-----------------------------------+-----------------------------------+ 281| int64 when | event time in seconds since | 282| | 1/1/70 | 283+-----------------------------------+-----------------------------------+ 284| int32 rawcode | code for the physical key pressed | 285+-----------------------------------+-----------------------------------+ 286| int32 repeat_count | number of times a key has been | 287| | repeated | 288+-----------------------------------+-----------------------------------+ 289| int32 modifiers | flags signifying the states of | 290| | the modifier keys | 291+-----------------------------------+-----------------------------------+ 292| int32 state_count | number of bytes to follow | 293| | containing the state of all keys | 294+-----------------------------------+-----------------------------------+ 295| int8 \*states | array of the state of all keys at | 296| | the time of the event | 297+-----------------------------------+-----------------------------------+ 298| int8 utf8data[3] | UTF-8 data generated | 299+-----------------------------------+-----------------------------------+ 300| int8 charcount | number of bytes to follow | 301| | containing the string generated | 302| | (usually 1) | 303+-----------------------------------+-----------------------------------+ 304| const char \*string | null-terminated string generated | 305| | by the keystroke | 306+-----------------------------------+-----------------------------------+ 307| int32 raw_char | modifier-independent ASCII code | 308| | for the character | 309+-----------------------------------+-----------------------------------+ 310 3111. Get all attached data 3122. If the command modifier is down, check for Left Ctrl+Left Alt+Left 313 Shift+F12 and reset the workspace to 640 x 480 x 256 @ 60Hz and return 314 if true 3153. If the command modifier is down, check for Alt+F1 through Alt+F12 and 316 set workspace and return if true 3174. If the control modifier is true, check for B_CONTROL_KEY+Tab and, if 318 true, find and send to the Deskbar. 3195. Acquire the active application lock 3206. Create a PortLink instance, target the active ServerApp's sender 321 port, set the opcode to B_KEY_DOWN, attach the buffer en masse, and send 322 it to the BApplication. 3237. Release the active application lock 324 325B_KEY_UP 326-------- 327 328Sent when the user releases a key that's been mapped to a character. 329 330Attached Data: 331 332+-----------------------------------+-----------------------------------+ 333| int64 when | event time in seconds since | 334| | 1/1/70 | 335+-----------------------------------+-----------------------------------+ 336| int32 rawcode | code for the physical key pressed | 337+-----------------------------------+-----------------------------------+ 338| int32 modifiers | flags signifying the states of | 339| | the modifier keys | 340+-----------------------------------+-----------------------------------+ 341| int32 state_count | number of bytes to follow | 342| | containing the state of all keys | 343+-----------------------------------+-----------------------------------+ 344| int8 \*states | array of the state of all keys at | 345| | the time of the event | 346+-----------------------------------+-----------------------------------+ 347| int8 utf8data[3] | UTF-8 data generated | 348+-----------------------------------+-----------------------------------+ 349| int8 charcount | number of bytes to follow | 350| | containing the string generated | 351| | (usually 1) | 352+-----------------------------------+-----------------------------------+ 353| const char \*string | null-terminated string generated | 354| | by the keystroke | 355+-----------------------------------+-----------------------------------+ 356| int32 raw_char | modifier-independent ASCII code | 357| | for the character | 358+-----------------------------------+-----------------------------------+ 359 3601. Get all attached data 3612. Acquire the active application lock 3623. Create a PortLink instance, target the active ServerApp's sender 363 port, set the opcode to B_KEY_UP, attach the buffer en masse, and send 364 it to the BApplication. 3654. Release the active application lock 366 367B_UNMAPPED_KEY_DOWN 368------------------- 369 370Sent when the user presses a key that has not been mapped to a 371character. 372 373Attached Data: 374 375+-----------------------------------+-----------------------------------+ 376| int64 when | event time in seconds since | 377| | 1/1/70 | 378+-----------------------------------+-----------------------------------+ 379| int32 rawcode | code for the physical key pressed | 380+-----------------------------------+-----------------------------------+ 381| int32 modifiers | flags signifying the states of | 382| | the modifier keys | 383+-----------------------------------+-----------------------------------+ 384| int8 state_count | number of bytes to follow | 385| | containing the state of all keys | 386+-----------------------------------+-----------------------------------+ 387| int8 \*states | array of the state of all keys at | 388| | the time of the event | 389+-----------------------------------+-----------------------------------+ 390 3911. Acquire the active application lock 3922. Create a PortLink instance, target the active ServerApp's sender 393 port, set the opcode to B_UNMAPPED_KEY_DOWN, attach the buffer en masse, 394 and send it to the BApplication. 3953. Release the active application lock 396 397B_UNMAPPED_KEY_UP 398----------------- 399 400Sent when the user presses a key that has not been mapped to a 401character. 402 403Attached Data: 404 405+-----------------------------------+-----------------------------------+ 406| int64 when | event time in seconds since | 407| | 1/1/70 | 408+-----------------------------------+-----------------------------------+ 409| int32 rawcode | code for the physical key pressed | 410+-----------------------------------+-----------------------------------+ 411| int32 modifiers | flags signifying the states of | 412| | the modifier keys | 413+-----------------------------------+-----------------------------------+ 414| int8 state_count | number of bytes to follow | 415| | containing the state of all keys | 416+-----------------------------------+-----------------------------------+ 417| int8 \*states | array of the state of all keys at | 418| | the time of the event | 419+-----------------------------------+-----------------------------------+ 420 4211. Acquire the active application lock 4222. Create a PortLink instance, target the active ServerApp's sender 423 port, set the opcode to B_UNMAPPED_KEY_UP, attach the buffer en masse, 424 and send it to the BApplication. 4253. Release the active application lock 426 427B_MODIFIERS_CHANGED 428------------------- 429 430Sent when the user presses or releases one of the modifier keys 431 432Attached Data: 433 434+-----------------------------------+-----------------------------------+ 435| int64 when | event time in seconds since | 436| | 1/1/70 | 437+-----------------------------------+-----------------------------------+ 438| int32 modifiers | flags signifying the states of | 439| | the modifier keys | 440+-----------------------------------+-----------------------------------+ 441| int32 old_modifiers | former states of the modifier | 442| | keys | 443+-----------------------------------+-----------------------------------+ 444| int8 state_count | number of bytes to follow | 445| | containing the state of all keys | 446+-----------------------------------+-----------------------------------+ 447| int8 \*states | array of the state of all keys at | 448| | the time of the event | 449+-----------------------------------+-----------------------------------+ 450 4511. Acquire the active application lock 4522. Create a PortLink instance, target the active ServerApp's sender 453 port, set the opcode to B_MODIFIERS_CHANGED, attach the buffer en masse, 454 and send it to the BApplication. 4553. Release the active application lock 456 457