haiku/docs/develop/servers/app_server/asis.rst

426 lines
15 KiB
ReStructuredText
Raw Normal View History

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.