426 lines
15 KiB
ReStructuredText
426 lines
15 KiB
ReStructuredText
|
App Server Interface Specification v0.3
|
||
|
#######################################
|
||
|
|
||
|
Purpose:
|
||
|
========
|
||
|
|
||
|
The app_server provides services to the OpenBeOS by managing processes,
|
||
|
filtering and dispatching input from the Input Server to the appropriate
|
||
|
applications, and managing all graphics-related tasks.
|
||
|
|
||
|
Tasks:
|
||
|
======
|
||
|
|
||
|
The tasks performed by the app_server are grouped in relation to its
|
||
|
purpose.
|
||
|
|
||
|
- Receives and redirects (dispatches) messages from the input server
|
||
|
- Responds to messages from apps
|
||
|
- Receives and consolidates requests from BView, BWindow, BBitmap, and others to draw stuff (draw bitmap, etc)
|
||
|
- Utilizes ports to communicate with child processes
|
||
|
- Handles drag & drop messaging
|
||
|
- Manages the system clipboard
|
||
|
- Loads and Kills processes
|
||
|
- Detects absence of Input Server and restarts when not running
|
||
|
- Aids in system shutdown
|
||
|
- Dynamically loads accelerant portion of graphics driver
|
||
|
- Creates a connection with BBitmaps requiring a child view
|
||
|
- Draws the blue desktop screen
|
||
|
- Provides workspace support
|
||
|
- Provides functionality to the BeAPI for drawing primitives, such as rectangles, ellipses, and beziers
|
||
|
- Provides a means for BViews to draw on BBitmaps
|
||
|
- Manages window behavior with respect to redraw (move to front, minimize, etc)
|
||
|
- Returns a frame buffer to direct-access classes
|
||
|
- Caches fonts for screen and printer use
|
||
|
- Draws text and provides other font API support for the BeAPI classes
|
||
|
|
||
|
Graphics:
|
||
|
=========
|
||
|
|
||
|
Desktop Initialization
|
||
|
-----------------------
|
||
|
|
||
|
The graphics hardware is abstracted from the rest of the app_server.
|
||
|
When started, the server creates the desktop, which is little more than
|
||
|
a collection of workspaces. The desktop actually creates a DisplayDriver
|
||
|
and then calls the driver's method Inititialize() before calling a few
|
||
|
high-level routines for setup. Below is the process by which the
|
||
|
HWDriver class, which is used to access the primary graphics card in the
|
||
|
system, followed by the steps taken to set up the desktop.
|
||
|
|
||
|
Load Accelerant
|
||
|
...............
|
||
|
|
||
|
The app_server looks in three paths when scanning for an accelerant:
|
||
|
|
||
|
- /fd/beos/system/add-ons/app_server
|
||
|
- /boot/home/config/add-ons/app_server
|
||
|
- /boot/beos/system/add-ons/app_server
|
||
|
|
||
|
When the app_server searches a path, it simply prints to the debug
|
||
|
stream on the serial port a message akin "Attempting to load accelerant
|
||
|
so-and-so" when loading the accelerant. Following this, it is loads the
|
||
|
accelerant via load_add_on(), obtains the hook function
|
||
|
control_graphics_card is via get_image_symbol, and
|
||
|
control_graphics_card(OPEN_GRAPHICS_CARD) is called. If this returns an
|
||
|
error, the image is unloaded after a
|
||
|
control_graphics_card(CLOSE_GRAPHICS_CARD) is called and the server
|
||
|
spits out a message like "So-and-so is not an acceptable driver" to the
|
||
|
serial port. Assuming that the OPEN call succeeds, the app_server serial
|
||
|
prints "Using so-and-so as accelerant." Hook functions are then acquired
|
||
|
through control_graphics_card(B_GET_GRAPHICS_CARD_HOOKS). At this point,
|
||
|
it is a good idea to have a palette generated for 8-bit mode (just in
|
||
|
case we're going to use it), so the server generates the system palette.
|
||
|
The palette on the graphics card is then set through many calls to
|
||
|
control_graphics_card(B_SET_INDEXED_COLOR).
|
||
|
|
||
|
Set up workspaces
|
||
|
.................
|
||
|
|
||
|
Workspace preferences are read in from disk. If they exist, they are
|
||
|
used; otherwise the default of 3 workspace, each with the settings
|
||
|
640x480x256@59.9Hz, is used. Each workspace is initialized to the proper
|
||
|
information (preferences or default). Additionally, all settings are
|
||
|
checked and possibly "clipped" by information gained through the driver
|
||
|
class. With the desktop having been given the proper settings, the
|
||
|
default workspace, 0, is activated.
|
||
|
|
||
|
Display
|
||
|
.......
|
||
|
|
||
|
Provided that everything has gone well so far, the screen is filled to
|
||
|
the user-set workspace color or RGB(51,102,160) Also, the global
|
||
|
clipboard is created, which is nothing more than a BClipboard object.
|
||
|
The Input Server will notify the app_server of its existence, at which
|
||
|
point the cursor will be set to B_HAND_CURSOR and shown on the screen.
|
||
|
|
||
|
Window management
|
||
|
-----------------
|
||
|
|
||
|
Window management is a complicated issue, requiring the cooperation of a
|
||
|
number of different types of elements. Each BApplication, BWindow, and
|
||
|
BView has a counterpart in the app_server which has a role to play.
|
||
|
These objects are Decorators, ServerApps, ServerWindows, Layers, and
|
||
|
WindowBorders.
|
||
|
|
||
|
ServerApps
|
||
|
..........
|
||
|
|
||
|
ServerApp objects are created when a BApplication notifies the
|
||
|
app_server of its presence. In acknowledging the BApplication's
|
||
|
existence, the server creates a ServerApp which will handle future
|
||
|
server-app communications and notifies the BApplication of the port to
|
||
|
which it must send future messages.
|
||
|
|
||
|
ServerApps are each an independent thread which has a function similar
|
||
|
to that of a BLooper, but with additional tasks. When a BWindow is
|
||
|
created, it spawns a ServerWindow object to handle the new window. The
|
||
|
same applies to when a window is destroyed. Cursor commands and all
|
||
|
other BApplication functions which require server interaction are also
|
||
|
handled. B_QUIT_REQUESTED messages are received and passed along to the
|
||
|
main thread in order for the ServerApp object to be destroyed. The
|
||
|
server's Picasso thread also utilizes ServerApp::PingTarget in order to
|
||
|
determine whether the counterpart BApplication is still alive and
|
||
|
running.
|
||
|
|
||
|
ServerWindows
|
||
|
.............
|
||
|
|
||
|
ServerWindow objects' purpose is to take care of the needs of BWindows.
|
||
|
This includes all calls which require a trip to the server, such as
|
||
|
BView graphics calls and sending messages to invoke hook functions
|
||
|
within a window.
|
||
|
|
||
|
Layers
|
||
|
......
|
||
|
|
||
|
Layers are shadowed BViews and are used to handle much BView
|
||
|
functionality and also determine invalid screen regions. Hierarchal
|
||
|
functions, such as AddChild, are mirrored. Invalid regions are tracked
|
||
|
and generate Draw requests which are sent to the application for a
|
||
|
specific BView to update its part of the screen.
|
||
|
|
||
|
WindowBorders
|
||
|
.............
|
||
|
|
||
|
WindowBorders are a special kind of Layer with no BView counterpart,
|
||
|
designed to handle window management issues, such as click tests, resize
|
||
|
and move events, and ensuring that its decorator updates the screen
|
||
|
appropriately.
|
||
|
|
||
|
Decorators
|
||
|
..........
|
||
|
|
||
|
Decorators are addons which are intended to do one thing: draw the
|
||
|
window frame. The Decorator API and development information is described
|
||
|
in the Decorator Development Reference. They are essentially the means
|
||
|
by which WindowBorders draw to the screen.
|
||
|
|
||
|
How It All Works
|
||
|
................
|
||
|
|
||
|
The app_server is one large, complex beast because of all the tasks it
|
||
|
performs. It also utilizes the various objects to accomplish them. Input
|
||
|
messages are received from the Input Server and all messages not
|
||
|
specific to the server (such as Ctrl-Alt-Shift-Backspace) are passed to
|
||
|
the active application, if any. Mouse clicks are passed to the
|
||
|
ServerWindow class for hit testing. These hit tests can result in window
|
||
|
tabs and buttons being clicked, or mouse click messages being passed to
|
||
|
a specific view in a window.
|
||
|
|
||
|
These input messages which are passed to a running application will
|
||
|
sometimes cause things to happen inside it, such as button presses,
|
||
|
window closings/openings, etc. which will cause messages to be sent to
|
||
|
the server. These messages are sent either from a BWindow to a
|
||
|
ServerWindow or a BApplication to a ServerApp. When such messages are
|
||
|
sent, then the corresponding app_server object performs an appropriate
|
||
|
action.
|
||
|
|
||
|
Screen Updates
|
||
|
--------------
|
||
|
|
||
|
Screen updates are done entirely through the BView class or some
|
||
|
subclass thereof, hereafter referred to as a view. A view's drawing
|
||
|
commands will cause its window to store draw command messages in a
|
||
|
message packet. At some point Flush() will be called and the command
|
||
|
packet will be sent to the window's ServerWindow object inside the
|
||
|
server.
|
||
|
|
||
|
The ServerWindow will receive the packet, check to ensure that its size
|
||
|
is correct, and begin retrieving each command from the packet and
|
||
|
dispatching it, taking the appropriate actions. Actual drawing commands,
|
||
|
such as StrokeRect, will involve the ServerWindow object calling the
|
||
|
appropriate command in the graphics module for the Layer corresponding
|
||
|
to the view which sent the command.
|
||
|
|
||
|
Cursor Management
|
||
|
-----------------
|
||
|
|
||
|
The app_server handles all messiness to do with the cursor. The cursor
|
||
|
commands which are members of the BApplication class will send a message
|
||
|
to its ServerApp, which will then call the DisplayDriver's appropriate
|
||
|
function. The DisplayDriver used will actually handle the drawing of the
|
||
|
cursor and whether or not to do so at any given time.
|
||
|
|
||
|
OpenBeOS R1 will also include the advent of an extension of the API:
|
||
|
SetCursor(BBitmap \*), which will accept a BBitmap of color space
|
||
|
RGB(A)32, RGBA16, CMAP8, GRAY8, or GRAY1. Thus, color cursors and
|
||
|
cursors which are not 16x16 are now supported.
|
||
|
|
||
|
Display Drivers
|
||
|
---------------
|
||
|
|
||
|
Unlike the BeOS R5 app_server, OpenBeOS' server will have a special
|
||
|
feature: a modular graphics driver access class. The class is not
|
||
|
actually the graphics driver, but, rather, a generalized interface which
|
||
|
is implemented to interact with various destinations for graphics
|
||
|
output. This allows the server to draw to a BWindow/BView combination, a
|
||
|
BDirectWindow, or the actual frame buffer of a particular graphics card.
|
||
|
All that the rest of the server needs to do is call whichever graphics
|
||
|
function that is needed.
|
||
|
|
||
|
Process Management
|
||
|
==================
|
||
|
|
||
|
BApplication execution
|
||
|
-----------------------
|
||
|
|
||
|
Applications will come in two types: those which communicate with the
|
||
|
app_server and take advantage of its services, and those which do not.
|
||
|
To access the app_server, an application must be derived from
|
||
|
BApplication.
|
||
|
|
||
|
When a BApplication (referred to hereafter as a BApp) is executed, the
|
||
|
app constructor creates its BLooper message port with the name
|
||
|
AppLooperPort. This port's id, by means of BLooper, registers its
|
||
|
port_id with the app_server so that the two can communicate with each
|
||
|
other most easily.
|
||
|
|
||
|
When the app_server receives notification that an app has been created,
|
||
|
the server creates an AppMonitor (with accompanying thread) in its own
|
||
|
team to handle messages sent to it and sends a reply with the port_id of
|
||
|
the AppMonitor, to which all future messages are sent. These AppMonitor
|
||
|
objects are stored in a global BList created for the storage of such
|
||
|
things.
|
||
|
|
||
|
non-BApplication execution
|
||
|
--------------------------
|
||
|
|
||
|
Other applications do not communicate with the app_server. These
|
||
|
applications have no access to app services and do not generally pass
|
||
|
BMessages. This includes, but is not limited to, UNIX apps. The
|
||
|
app_server ignores such applications except when asked to kill them.
|
||
|
|
||
|
While, technically, these are not limited to being non-GUI applications,
|
||
|
in practice these applications are command-line-only, for the
|
||
|
application would be required to (1) render the app_server unable to
|
||
|
access video hardware and (2) reinvent existing graphics code to load
|
||
|
and use accelerants and draw onto the video buffer. This is extremely
|
||
|
bad style and programming practice, not to mention more work than it is
|
||
|
worth except in one case: the OpenBeOS app_server can coexist with the
|
||
|
BeOS R5 app_server with some degree of peace because it can utilize
|
||
|
extra video cards which the BeOS app_server does not use.
|
||
|
|
||
|
Killing/Exiting Applications
|
||
|
----------------------------
|
||
|
|
||
|
While the input server handles the Team Monitor window, the app_server
|
||
|
actually takes care of shutting down teams, peacefully or not. Exiting
|
||
|
an app is done simply by sending a B_QUIT_REQUESTED message to
|
||
|
particular app. Killing an app is done via kill_team, but all the messy
|
||
|
details are handled by the kernel itself through this call. When the
|
||
|
user requests a team die via the Team Monitor, the Input Server sends a
|
||
|
message to the app_server to kill the team, attaching the team_id. The
|
||
|
app_server responds by happily nuking the respective team and notifies
|
||
|
the registrar of its forcible removal from the roster.
|
||
|
|
||
|
System Shutdown
|
||
|
---------------
|
||
|
|
||
|
Although the server maintains an internal list of running GUI
|
||
|
applications, when a request to shut down the system is received by the
|
||
|
app_server, it will pass the request on to the registrar, which will, in
|
||
|
turn, increment its way through the app roster and request each app
|
||
|
quit. When each quit request is sent, a timer is started and after
|
||
|
timeout, the registrar will ask the server to kill the particular team
|
||
|
and continue iterating through the application list.
|
||
|
|
||
|
Input Processing
|
||
|
================
|
||
|
|
||
|
Input Server messages
|
||
|
---------------------
|
||
|
|
||
|
The Input Server collects information about keyboard and mouse events
|
||
|
and forwards them to the app_server via messages. They are sent to port
|
||
|
specifically for such messages, and the port is monitored by a thread
|
||
|
whose task is to monitor, process, and dispatch them to the appropriate
|
||
|
recipients. The Input Server is a regular BApplication, and unlike other
|
||
|
applications, it requests a port to which it can send input messages.
|
||
|
|
||
|
Mouse
|
||
|
-----
|
||
|
|
||
|
Mouse events consist of button changes, mouse movements, and the mouse
|
||
|
wheel. The message will consist of the time of the event and attachments
|
||
|
appropriate for each message listed below:
|
||
|
|
||
|
B_MOUSE_DOWN
|
||
|
............
|
||
|
|
||
|
- when
|
||
|
- location of the cursor
|
||
|
- button number
|
||
|
- modifiers
|
||
|
- clicks
|
||
|
|
||
|
B_MOUSE_UP
|
||
|
..........
|
||
|
|
||
|
- time
|
||
|
- buttons' status // not implemented for R5 but included for future expansion
|
||
|
- location of the cursor
|
||
|
- modifiers
|
||
|
|
||
|
B_MOUSE_MOVED
|
||
|
.............
|
||
|
|
||
|
- time
|
||
|
- location of the cursor
|
||
|
- buttons' status
|
||
|
|
||
|
B_MOUSE_WHEEL_CHANGED
|
||
|
.....................
|
||
|
|
||
|
- time
|
||
|
- location of the cursor
|
||
|
- transit - in or out
|
||
|
- x delta
|
||
|
- y delta
|
||
|
|
||
|
Keyboard
|
||
|
--------
|
||
|
|
||
|
Keyboard events consist of notification when a key is pressed or
|
||
|
released. Any keypress or release will evoke a message, regardless of
|
||
|
whether or not the key is mapped. The message will consist of the
|
||
|
appropriate code and attachments listed below:
|
||
|
|
||
|
B_KEY_DOWN
|
||
|
..........
|
||
|
|
||
|
- time
|
||
|
- key code
|
||
|
- repeat count
|
||
|
- modifiers
|
||
|
- states
|
||
|
- UTF-8 code
|
||
|
- string generated
|
||
|
- modifier-independent ASCII code
|
||
|
|
||
|
B_KEY_UP
|
||
|
........
|
||
|
|
||
|
- time
|
||
|
- key code
|
||
|
- modifiers
|
||
|
- states
|
||
|
- UTF-8 code
|
||
|
- string generated
|
||
|
- modifier-independent ASCII code
|
||
|
|
||
|
B_UNMAPPED_KEY_DOWN
|
||
|
...................
|
||
|
|
||
|
- time
|
||
|
- key code
|
||
|
- modifiers
|
||
|
- states
|
||
|
|
||
|
B_UNMAPPED_KEY_UP
|
||
|
.................
|
||
|
|
||
|
- time
|
||
|
- key code
|
||
|
- modifiers
|
||
|
- states
|
||
|
|
||
|
B_MODIFIERS_CHANGED
|
||
|
...................
|
||
|
|
||
|
sent when a modifier key changes
|
||
|
|
||
|
- time
|
||
|
- modifier states
|
||
|
- previous modifier states
|
||
|
- states
|
||
|
|
||
|
Nearly all keypresses received by the app_server are passed onto the
|
||
|
appropriate application. Control-Tab, when held, is sent to the Deskbar
|
||
|
for app switching. Command+F?? is intercepted and a workspace is
|
||
|
switched. Left Control + Alt + Delete is not even intercepted by the
|
||
|
app_server. The Input Server receives it and shows the Team Monitor
|
||
|
window.
|
||
|
|
||
|
Messaging
|
||
|
=========
|
||
|
|
||
|
Inter-Application Messaging
|
||
|
---------------------------
|
||
|
|
||
|
The details of messaging are depicted under Process
|
||
|
Management::BApplication.
|
||
|
|
||
|
Drag-and-drop
|
||
|
-------------
|
||
|
|
||
|
Methods
|
||
|
-------
|
||
|
|
||
|
Messaging with the app_server is not done using BMessages because of the
|
||
|
overhead required to send them costs time and speed. Instead, ports are
|
||
|
utilized indirectly by means of the PortLink class, which simply makes
|
||
|
attaching data to a port message easier, but requires very little
|
||
|
overhead.
|
||
|
|