The Interface Kit: Global Functions

This section describes the global (nonmember) functions defined in the Interface Kit. All these functions deal with aspects of the system-wide environment for the user interface --the keyboard and mouse, the screen, workspaces, installed fonts and symbol sets, the list of possible colors, and various user preferences.

The Application Server maintains this environment (with just a few exceptions). Therefore, for a global Interface Kit function to work, your application must be connected to the Server. The connection these functions depend on is the one that's established when the BApplication object is constructed. Consequently, none of them should be called before a BApplication object is present in your application.


activate_app()

Declared in: <interface/InterfaceDefs.h>

      void activate_app(team_id app)

Activates the app application < by bringing one of its windows to the front and making it the active window >. This function works only if the target application has a window on- screen. The newly activated application is notified with a B_APP_ACTIVATED message.

< This function is an alternative to sending the application a B_ACTIVATE message. It accomplishes the same thing, except that it communicates directly with the Application Server to do its work. >

See also: BApplication::Activate() in the Application Kit


activate_workspace(), current_workspace()

Declared in: <interface/InterfaceDefs.h>

      void activate_workspace(long workspace)
      long current_workspace(void)

These functions set and return the active workspace, the one that's currently displayed on- screen. Each workspace is represented by a bit in a long integer.

See also: BWindow::WorkspaceActivated()


adjust_crt() see get_screen_info()


count_fonts() see get_font_name()


count_screens() see get_screen_info()


count_symbol_sets() see get_symbol_set_name()


count_workspaces() see set_workspace_count()


current_workspace() see activate_workspace()


desktop_color() see set_desktop_color()


get_click_speed() see set_click_speed()


get_dock_width()

Declared in: <interface/InterfaceDefs.h>

      long get_dock_width(float *width)

Writes the current width of the dock into the variable referred to by width. Since the dock floats on top of other windows, this function can help determine how much usable screen space is actually available. It returns B_NO_ERROR if successful and B_ERROR if not.

See also: get_screen_info()


get_font_name(), count_fonts()

Declared in: <interface/InterfaceDefs.h>

      void get_font_name(long index, font_name *name)
      long count_fonts(void)

These two functions are used in combination to get the names of all installed fonts. For example:

   long numFonts = count_fonts();
   font_name buf;
   
   for ( long i = 0; i < numFonts; i++ ) {
       get_font_name(i, &buf);
       . . .
   }

The names of all installed fonts are kept in an alphabetically ordered list. get_font_name() reads one of the names from the list, the name at index, and copies it into the name buffer. Font names can be up to 64 characters long, plus a null terminator. Indices begin at 0.

count_fonts() returns the number of fonts currently installed, the number of names in the list.

See also: BView::GetFontInfo(), BView::SetFontName()


get_key_repeat_delay() see set_key_repeat_rate()


get_key_repeat_rate() see set_key_repeat_rate()


get_keyboard_id()

Declared in: <interface/InterfaceDefs.h>

      long get_keyboard_id(ushort *theId)

Obtains the keyboard identifier from the Application Server and writes it into the variable referred to by theId. This number reveals what kind of keyboard is currently attached to the computer.

The identifier for the standard 101-key keyboard--and for keyboards with a similar set of keys--is 0x83ab. < Currently, this is the only value this function can provide. > See Key Codes for illustrations showing the keys found on a standard keyboard.

If unsuccessful for any reason, get_keyboard_id() returns B_ERROR. If successful, it returns B_NO_ERROR.


get_menu_info() see set_menu_info()


get_mouse_map() see set_mouse_map()


get_mouse_speed() see set_mouse_map()


get_mouse_type() see set_mouse_map()


get_screen_info(), count_screens()

Declared in: <interface/InterfaceDefs.h>

      void get_screen_info(screen_info *theInfo)
      void get_screen_info(long index, screen_info *theInfo)

      long count_screens(void)
      long set_screen_space(long index, ulong space, bool makeDefault = TRUE)
      long set_screen_refresh_rate(long index, float rate, bool makeDefault = TRUE)
      long adjust_crt(long index, uchar hPosition, uchar vPosition, 
         uchar hSize, uchar vSize, bool makeDefault = TRUE)

These functions provide information about the screens (monitors) that are currently hooked up to the BeBox, and alter screen parameters.

Each screen that's attached to the machine is identified by an index into a system-wide screen list. The screen at index 0 is the one that has the origin of the screen coordinate system at its left top corner. Other screens in the list are unordered; they're located elsewhere in the coordinate system that the first screen defines. < Currently, multiple screens are not supported, so the screen at index 0 is the only one in the list. Therefore, the index passed to these functions should always be 0. >

count_screens() returns the number of screens (monitors) that are attached to the computer. < Since no more than one screen can be attached, this function currently always returns 1. >

get_screen_info() writes information about the screen at index into the screen_info structure referred to by theInfo. If no index is mentioned, it assumes the screen at index 0. The screen_info structure contains the following fields:

color_space mode The depth and color interpretation of pixel data in the screen's frame buffer; currently, the mode will be either B_COLOR_8_BIT or B_RGB_32_BIT. (See Colors of the chapter introduction for an explanation of the various color_space modes.)
BRect frame The frame rectangle of the screen--the rectangle that defines the size and location of the screen in the screen coordinate system.
ulong spaces A mask that enumerates all the possible configurations of the screen space. The consonant values that can contribute to the mask are listed below.
float min_refresh_rate The maximum possible refresh rate in cycles per second.
float max_refresh_rate The minimum possible refresh rate (which may be the same as the maximum).
float refresh_rate The current refresh rate.
uchar h_position The current horizontal position of the CRT display on the monitor, a value between 0 (as far to the left as possible) and 100 (as far to the right as possible) with 50 as the default.
uchar v_position The current vertical position of the CRT display on the monitor, a value between 0 (as close to the top as possible) and 100 (as close to the bottom as possible) with 50 as the default.
uchar h_size The current horizontal size of the CRT display on the monitor, a value between 0 (as narrow as possible) and 100 (as wide as possible) with 50 as the default.
uchar v_size The current vertical size of the CRT display on the monitor, a value between 0 (as short as possible) and 100 (as tall as possible) with 50 as the default.

If the color space mode is B_COLOR_8_BIT, each pixel value in the frame buffer for the screen is an 8-bit color index. In B_RGB_32_BIT mode, each value is a set of four 8-bit color components (red, green, blue, and alpha). The components will be arranged in the most natural order for the display device--typically blue, green, red, and alpha. You can access the frame buffer only through the BWindowScreen class in the Game Kit.

The spaces field is a mask that enumerates all the possible configurations of the screen space (its depth and dimensions). It's formed from the following constants:

B_8_BIT_640x400
B_8_BIT_640x480 B_16_BIT_640x480 B_32_BIT_640x480
B_8_BIT_800x600 B_16_BIT_800x600 B_32_BIT_800x600
B_8_BIT_1024x768 B_16_BIT_1024x768 B_32_BIT_1024x768
B_8_BIT_1152x900 B_16_BIT_1152x900 B_32_BIT_1152x900
B_8_BIT_1280x1024 B_16_BIT_1280x1024 B_32_BIT_1280x1024
B_8_BIT_1600x1200 B_16_BIT_1600x1200 B_32_BIT_1600x1200

For example, if the mask includes B_32_BIT_1280x1024, the frame buffer can be 32 bits deep (the B_RGB_32_BIT color space) while the screen grid is 1,280 pixels wide and 1,024 pixels high. Not all configurations are possible for all graphics cards. < The operating system currently doesn't support depths of 16 bits. >

The current screen configuration can be read from the mode and frame fields. To change the configuration, you can pass one of the spaces constants to set_screen_space(). When the configuration of the screen changes, every affected BWindow object is notified with a ScreenChanged() function call. < Since there's currently only one screen, all windows are affected and all, whether on-screen or hidden, receive ScreenChanged() notifications. >

The refresh rate for the screen can be changed by passing a new rate to set_screen_refresh_rate(). The rate should lie between the minimum and maximum reported by get_screen_info(). The requested change is made to the best of the ability of the graphics card driver; exact compliance is not promised.

The h_position, v_position, h_size, and v_size fields of the screen_info structure record the placement of the CRT display on the physical monitor, as set by software controls --not the hardware controls on the monitor itself. If the monitor and the driver for the graphics card permit CRT adjustments through software, adjust_crt() can be called to change any setting. Its hPosition, vPosition, hSize, and vSize arguments have the same meaning as the corresponding fields of screen_info.

The three functions that alter screen parameters--adjust_crt() , set_screen_space(), and set_screen_refresh_rate() --all make changes that take effect immediately. If the makeDefault flag is TRUE, the new setting also becomes the default and will be used the next time the machine is turned on. If makeDefault is FALSE , the setting is in effect for the current session only. Each function returns B_NO_ERROR if successful, and B_ERROR if not.

These three functions are designed for preferences applications--like the Screen application--that permit users to make system-wide choices. Other applications should respect those choices and refrain from modifying them.

get_screen_info() reports on the screen as it is known to the Application Server. If you bypass the Server with the Game Kit, it may not provide accurate information.

See also: BWindow::ScreenChanged(), The Game Kit chapter


get_scroll_bar_info() see set_scroll_bar_info()


get_symbol_set_name(), count_symbol_sets()

Declared in: <interface/InterfaceDefs.h>

      void get_symbol_set_name(long index, symbol_set_name *name)
      long count_symbol_sets(void)

These functions are used to get the names of all available symbol sets. They work much like the parallel font functions get_font_name() and count_fonts().

A symbol set associates character symbols (glyphs) with character codes (ASCII values). They differ mainly in how they extend the standard ASCII set--how they assign characters to codes above 0x7f.

get_symbol_set_name() gets one name from the list of symbol sets, the name at index, and copies it into the name buffer. count_symbol_sets() returns the total number of symbol sets (the number of names in the list).

Unlike font names, the names of symbol sets are not arranged alphabetically.

Every font implements every symbol set. However, some fonts implement particular sets more fully than others--that is, some characters in a symbol set may not be available in some fonts. But the position of each character in the set (its character code) remains the same across all fonts.

See also: BView::SetSymbolSet(), get_font_name()


idle_time()

      double idle_time(void) const

Returns the number of microseconds since the user last manipulated the mouse or keyboard. This information isn't specific to a particular application; idle_time() tells you when the user last directed an action at any application, not just yours.


index_for_color()

Declared in: <interface/InterfaceDefs.h>

      uchar index_for_color(rgb_color aColor)
      uchar index_for_color(uchar red, uchar green, uchar blue, uchar alpha = 0)

Returns an index into the list of 256 colors that comprise the B_COLOR_8_BIT color space. The value returned picks out the listed color that most closely matches a full 32-bit color--specified either as an rgb_color value, aColor, or by its red, green , and blue components. < (The alpha component is currently ignored.) >

The returned index identifies a color in the B_COLOR_8_BIT color space. It can, for example, be passed to BBitmap's SetBits() function.

To find the fully specified color that an index picks out, you have to get the color list from the system color map. For example, if you first obtain the index for the "best fit" color that most closely matches an arbitrary color,

   uchar index = index_for_color(134, 210, 6);

you can then use the index to locate that color in the color list:

   rgb_color bestFit = system_colors()->color_list[index];

See also: system_colors() , the BBitmap class


modifiers()

Declared in: <interface/InterfaceDefs.h>

      ulong modifiers(void)

Returns a mask that has a bit set for each modifier key the user is holding down and for each keyboard lock that's set. The mask can be tested against these constants:

B_SHIFT_KEY B_COMMAND_KEY B_CAPS_LOCK
B_CONTROL_KEY B_MENU_KEY B_SCROLL_LOCK
B_OPTION_KEY B_NUM_LOCK

No bits are set (the mask is 0) if no locks are on and none of the modifiers keys are down.

If it's important to know which physical key the user is holding down, the one on the right or the one on the left, the mask can be further tested against these constants:

B_LEFT_SHIFT_KEY B_RIGHT_SHIFT_KEY
B_LEFT_CONTROL_KEY B_RIGHT_CONTROL_KEY
B_LEFT_OPTION_KEY B_RIGHT_OPTION_KEY
B_LEFT_COMMAND_KEY B_RIGHT_COMMAND_KEY

By default, on a 101-key keyboard, the keys labeled "Alt(ernate)" function as the Command modifiers, the key on the right labeled "Control" functions as the right Option key, and only the left "Control" key is available to function as a Control modifier. However, users can change this configuration with the Keymap application.

See also: Modifier Keys of the introduction to the chapter, system_key_map(), BView::GetKeys()


restore_key_map() see system_key_map()


set_click_speed(), get_click_speed()

Declared in: <interface/InterfaceDefs.h>

      long set_click_speed(double interval)
      long get_click_speed(double *interval)

These functions set and report the timing for multiple-clicks. For successive mouse-down events to count as a multiple-click, they must occur within the interval set by set_click_speed() and provided by get_click_speed() . The interval is measured in microseconds; it's usually set by the user in the Mouse preferences application. The smallest possible interval is 100,000 microseconds (0.1 second).

If successful, these functions return B_NO_ERROR; if unsuccessful, they return an error code, which may be just B_ERROR.

See also: set_mouse_map()


set_desktop_color(), desktop_color()

Declared in: <interface/InterfaceDefs.h>

      void set_desktop_color(rgb_color color, bool makeDefault = TRUE)
      rgb_color desktop_color(void) 

These functions set and return the color of the so-called "desktop" --the bare backdrop against which windows are displayed. The color is the same for all screens attached to the same machine (however, the Workspaces application can arrange for each workspace to have a different background color). set_desktop_color() makes an immediate change in the desktop color displayed on-screen; desktop_color() returns the color currently displayed.

If the makeDefault flag is TRUE, the color that's set becomes the default color for the desktop; it's the color that will be shown the next time the machine is booted. If the flag is FALSE, the color is set only for the current session.

Users can change the default color with the Screen application found in /preferences.


set_key_repeat_rate(), get_key_repeat_rate(), set_key_repeat_delay() , get_key_repeat_delay()

Declared in: <interface/InterfaceDefs.h>

      long set_key_repeat_rate(int rate)
      long get_key_repeat_rate(int *rate)
      long set_key_repeat_delay(double delay)
      long get_key_repeat_delay(double *delay)

These functions set and report the timing of repeating keys. When the user presses a character key on the keyboard, it produces an immediate B_KEY_DOWN message. If the user continues to hold the key down, it will, after an initial delay, continue to produce messages at regularly spaced intervals--until the user releases the key or presses another key. The delay and the spacing between messages are both preferences the user can set with the Keyboard application.

set_key_repeat_rate() sets the number of messages repeating keys produce per second. For a standard PC keyboard, the rate can be as low as 2 and as high as 30; get_key_repeat_rate() writes the current setting into the integer that rate refers to.

set_key_repeat_delay() sets the length of the initial delay before the key begins repeating. Acceptable values are 250,000.0, 500,000.0, 750,000.0 and 1,000,000.0 microseconds (.25, .5, .75, and 1.0 second); get_key_repeat_delay() writes the current setting into the variable that delay points to.

All four functions return B_NO_ERROR if they successfully communicate with the Application Server, and B_ERROR if not. It's possible for the set...() functions to communicate with the Server but not succeed in setting the rate or delay (for example, if the delay isn't one of the listed four values).


set_keyboard_locks()

Declared in: <interface/InterfaceDefs.h>

      void set_keyboard_locks(ulong modifiers)

Turns the keyboard locks--Caps Lock, Num Lock, and Scroll Lock--on and off. The keyboard locks that are listed in the modifiers mask passed as an argument are turned on; those not listed are turned off. The mask can be 0 (to turn off all locks) or it can contain any combination of the following constants:

B_CAPS_LOCK
B_NUM_LOCK
B_SCROLL_LOCK

See also: system_key_map() , modifiers()


set_menu_info(), get_menu_info()

Declared in: <interface/Menu.h>

      void set_menu_info(menu_info *info)
      void get_menu_info(menu_info *info)

These functions set and get the user's preferences for how menus should look and work. User's express their preferences with the Menu application, which calls set_menu_info() . get_menu_info() writes the current preferences into the menu_info structure that into refers to. This structure contains the following fields:

float font_size The size of the font that will be used to display menu items.
font_name font The name of the font that's used to display menu items.
rgb_color background_color The background color of the menu.
long separator The style of horizontal line that separates groups of items in a menu. The value is an index ranging from 0 through 2; there are three possible separators.
bool click_to_open Whether it's possible to open a menu by clicking in the item that controls it. The default value is TRUE.
bool triggers_always_shown Whether trigger characters are always marked in menus and menu bars, regardless of whether the menu hierarchy is the target for keyboard actions. The default value is FALSE.

< At present, both functions always return B_NO_ERROR . >

See also: the BMenu class


set_modifier_key()

Declared in: <interface/InterfaceDefs.h>

      void set_modifier_key(ulong modifier, ulong key)

Maps a modifier role to a particular key on the keyboard, where key is a key identifier and modifier is one of the these constants:

B_CAPS_LOCK B_LEFT_SHIFT_KEY B_RIGHT_SHIFT_KEY
B_NUM_LOCK B_LEFT_CONTROL_KEY B_RIGHT_CONTROL_KEY
B_SCROLL_LOCK B_LEFT_OPTION_KEY B_RIGHT_OPTION_KEY
B_MENU_KEY B_LEFT_COMMAND_KEY B_RIGHT_COMMAND_KEY

The key in question serves as the named modifier key, unmapping any key that previously played that role. The change remains in effect until the default key map is restored. In general, the user's preferences for modifier keys--expressed in the Keymap application --should be respected.

Modifier keys can also be mapped by calling system_key_map() and altering the key_map structure directly. This function is merely a convenient alternative for accomplishing the same thing.

See also: system_key_map()


set_mouse_map(), get_mouse_map() , set_mouse_type(), get_mouse_type(), set_mouse_speed(), get_mouse_speed()

Declared in: <interface/InterfaceDefs.h>

      long set_mouse_map(mouse_map *map)
      long get_mouse_map(mouse_map *map)
      long set_mouse_type(long numButtons)
      long get_mouse_type(long *numButtons)
      long set_mouse_speed(long acceleration)
      long get_mouse_speed(long *acceleration)

These functions configure the mouse and supply information about the current configuration. The configuration should usually be left to the user and the Mouse preferences application.

set_mouse_map() maps the buttons of the mouse to their roles in the user interface, and get_mouse_map() writes the current map into the variable referred to by map. The mouse_map structure has a field for each button on a three-button mouse:

ulong left The button on the left of the mouse
ulong right The button on the right of the mouse
ulong middle The button in the middle, between the other two buttons

Each field is set to one of the following constants:

B_PRIMARY_MOUSE_BUTTON
B_SECONDARY_MOUSE_BUTTON
B_TERTIARY_MOUSE_BUTTON

The same role can be assigned to more than one physical button. If all three buttons are set to B_PRIMARY_MOUSE_BUTTON , they all function as the primary button; if two of them are set to B_SECONDARY_MOUSE_BUTTON , they both function as the secondary button; and so on.

set_mouse_type() informs the system of how many buttons the mouse actually has. If it has two buttons, only the left and right fields of the mouse_map are operative. If it has just one button, only the left field is operative. set_mouse_type() writes the current number of buttons into the variable referred to by numButtons.

set_mouse_speed() sets the speed of the mouse--the acceleration of the cursor image on- screen relative to the actual speed at which the user moves the mouse on its pad. An acceleration value of 0 means no acceleration. The maximum acceleration is 20, though even 10 is too fast for most users. set_mouse_speed() writes the current acceleration into the variable referred to by acceleration.

All six functions return B_NO_ERROR if successful, and an error code, typically B_ERROR, if not.


set_screen_refresh_rate() see get_screen_info()


set_screen_space() see get_screen_info()


set_scroll_bar_info(), get_scroll_bar_info()

      long set_scroll_bar_info(scroll_bar_info *info)
      long get_scroll_bar_info(scroll_bar_info *info)

These functions set and report preferences that the BScrollBar class uses when it creates a new scroll bar. set_scroll_bar_info() reads the values contained in the scroll_bar_info structure that info refers to and sets the system-wide preferences accordingly; get_scroll_bar_info() writes the current preferences into the structure provided.

The scroll_bar_info structure contains the following fields:

bool proportional TRUE if scroll bars should have a knob that grows and shrinks to show what proportion of the document is currently visible on-screen, and FALSE if not. Scroll knobs are proportional by default.
bool double_arrows TRUE if a set of double arrows (for scrolling in both directions) should appear at each end of the scroll bar, or FALSE if only single arrows (for scrolling in one direction only) should be used. Double arrows are the default.
long knob An index that picks the pattern for the knob. Only values of 0, 1, and 2 are currently valid. The patterns can be seen in the ScrollBar preferences application. The pattern at index 1 is the default.
long min_knob_size The length of the scroll knob, in pixels. This is the minimum size for a proportional knob and the fixed size for one that's not proportional. The default is 15.

The user can set these preferences with the ScrollBar application. Applications can call get_scroll_bar_info() to find out what choices the user made, but should refrain from calling set_scroll_bar_info(). That function is desigined for utilities, like the ScrollBar application, that enable users to set preferences that are respected system-wide.

If successful, these functions return B_NO_ERROR; if not, they return B_ERROR.

See also: the BScrollBar class


set_workspace_count(), count_workspaces()

Declared in: <interface/InterfaceDefs.h>

      void set_workspace_count(long numWorkspaces)
      long count_workspaces(void)

These functions set and return the number of workspaces the user has available. There can be as many as 32 workspaces and as few as 1. The choice of how many there should be is usually left to the user and the Workspaces application.

See also: activate_workspace()


system_colors()

Declared in: <interface/InterfaceDefs.h>

      color_map *system_colors(void)

Returns a pointer to the system's color map. The color map defines the set of 256 colors that can be displayed in the B_COLOR_8_BIT color space. A single set of colors is shared by all applications connected to the Application Server.

The color_map structure is defined in interface/InterfaceDefs.h and contains the following fields:

long id An identifier that the Server uses to distinguish one color map from another.
rgb_color color_list[256] A list of the 256 colors, expressed as rgb_color structures. Indices into the list can be used to specify colors in the B_COLOR_8_BIT color space. See the index_for_color() function above.
uchar inversion_map[256] A mapping of each color in the color_list to its opposite color. Indices are mapped to indices. An example of how this map might be used is given below.
uchar index_map[32768] An array that maps RGB colors--specified using five bits per component--to their nearest counterparts in the color list. An example of how to use this map is also given below.

The inversion_map is a list of indices into the color_list where each index locates the "inversion" of the original color. The inversion of the n'th color in color_list would be found as follows:

   uchar inversionIndex = system_colors()->inversion_map[n];
   rgb_color inversionColor =
                   system_colors()->color_list[inversionIndex];

Inverting an inverted index returns the original index, so this code

   uchar color = system_colors()->inversion_map[inversionIndex];

would return n. < Inverted colors are used, primarily, for highlighting. Given a color, its highlight complement is its inversion. >

The index_map maps every RGB combination that can be expressed in 15 bits (five bits per component) to a single color_list index that best approximates the original RGB data. The following example demonstrates how to squeeze 24-bit RGB data into a 15-bit number that can be used as an index into the index_map:

   long rgb15 = ( ((red & 0xf8) << 7) |
                  ((green & 0xf8) << 2) |
                  ((blue & 0xf8) >> 3) );

Most applications won't need to use the index map directly; the index_for_color() function performs the same conversion with less fuss (no masking and shifting required). However, applications that implement repetitive graphic operations, such as dithering, may want to access the index map themselves, and thus avoid the overhead of an additional function call.

You should never modify or free the color_map structure returned by this function.

See also: index_for_color()


system_key_map(), restore_key_map()

Declared in: <interface/InterfaceDefs.h>

      key_map *system_key_map(void)
      void restore_key_map(void)

The first of these functions returns a pointer to the system key map --the structure that describes the role of each key on the keyboard. The second function restores the default map, in case any of its fields have been changed.

The system key map is shared by all applications. An application can alter values in the structure that system_key_map() returns--and thus alter the roles that the keys play --but it should make sure that those changes are local to itself and don't affect other, unsuspecting applications. In particular, it should:

Through the Keymap preferences application, users can configure the keyboard to their liking. The user's preferences affect all applications; they're captured in the default key map and stored in a file (/system/settings/Key_map).

When the machine reboots or when restore_key_map() is called, the key map is read from this file. If the file doesn't exist, the original map encoded in the Application Server is used.

The key_map structure contains a large number of fields, but it can be broken down into these six parts:

The following sections describe each part of the key_map structure in turn.

Version

The first field of the key map is a version number:

ulong version An internal identifier for the key map.

The version number doesn't change when the user configures the keyboard, and shouldn't be changed programmatically either. You can ignore it.

Modifiers

Modifier keys set states that affect other user actions on the keyboard and mouse. Eight modifier states are defined--Shift, Control, Option, Command, Menu, Caps Lock, Num Lock, and Scroll Lock. These states are discussed under Modifier Keys of the introduction. They overlap, but don't exactly match the key caps found on a standard keyboard--which generally has a set of Alt(ernate) keys, rarely Option keys, and only sometimes Command and Menu keys. Because of these differences, the mapping of keys to modifiers is the area of the key map most open to the user's personal judgement and taste, and consequently to changes in the default configuration. Applications are urged to respect the user's preferences.

Since two keys, one on the left and one on the right, can be mapped to the Shift, Control, Option, and Command modifiers, the keyboard can have as many as twelve modifier keys. The key_map structure has one field for each key:

ulong caps_key The key that functions as the Caps Lock key--by default, this is the key labeled "Caps Lock," key 0x3b.
ulong scroll_key The key that functions as the Scroll Lock key--by default, this is the key labeled "Scroll Lock," key 0x0f.
ulong num_key The key that functions as the Num Lock key--by default, this is the key labeled "Num Lock," key 0x22.
ulong left_shift_key A key that functions as a Shift key--by default, this is the key on the left labeled "Shift," key 0x4b.
ulong right_shift_key Another key that functions as a Shift key--by default, this is the key on the right labeled "Shift," key 0x56.
ulong left_command_key A key that functions as a Command key--by default, this is the left "Alt" key, key 0x5d.
ulong right_command_key Another key that functions as a Command key--by default, this is the right "Alt" key, key 0x5f.
ulong left_control_key A key that functions as a Control key--by default, this is the key labeled "Control" on the left, key 0x5c.
ulong right_control_key Another key that functions as a Control key--by default, this key is not mapped. (The value of the field is set to 0.)
ulong left_option_key A key that functions as an Option key--by default, this is the key that's labeled "Command" (or that has a command symbol) on the left of some keyboards, key 0x66. This key doesn't exist on, and therefore isn't mapped for, a standard 101-key keyboard.
ulong right_option_key A key that functions as an Option key--by default, this is the key labeled "Control" on the right, key 0x60.
ulong menu_key A key that initiates keyboard navigation of the menu hierarchy--by default, this is the key labeled "Menu," key 0x68. This key doesn't exist on, and therefore isn't mapped for, a standard 101-key keyboard.

Each field names the key that functions as that modifier. For example, when the user holds down the key whose code is set in the right_option_key field, the B_OPTION_KEY and B_RIGHT_OPTION_KEY bits are turned on in the modifiers mask that the modifiers() function returns. When the user then strikes a character key, the B_OPTION_KEY state influences the character that's generated.

If a modifier field is set to a value that doesn't correspond to an actual key on the keyboard (including 0), that field is not mapped. No key fills that particular modifier role.

Keyboard locks

One field of the key map sets initial modifier states:

ulong lock_settings A mask that determines which keyboard locks are turned on when the machine reboots or when the default key map is restored.

The mask can be 0 or may contain any combination of these three constants:

B_CAPS_LOCK
B_SCROLL_LOCK
B_NUM_LOCK

It's 0 by default; there are no initial locks.

Altering the lock_settings field has no effect unless the altered key map is made the default (by writing it to a file that replaces /system/settings/Key_map).

Character maps

The principal job of the key map is to assign character values to keys. This is done in a series of nine tables:

ulong control_map[128] The characters that are produced when a Control key is down but both Command keys are up.
ulong option_caps_shift_map[128] The characters that are produced when Caps Lock is on and both a Shift key and an Option key are down.
ulong option_caps_map[128] The characters that are produced when Caps Lock is on and an Option key is down.
ulong option_shift_map[128] The characters that are produced when both a Shift key and an Option key are down.
ulong option_map[128] The characters that are produced when an Option key is down.
ulong caps_shift_map[128] The characters that are produced when Caps Lock is on and a Shift key is down.
ulong caps_map[128] The characters that are produced when Caps Lock is on.
ulong shift_map[128] The characters that are produced when a Shift key is down.
ulong normal_map[128] The characters that are produced when none of the other tables apply.

Each of these tables is an array of 128 characters (declared as ulongs). Key codes are used as indices into the arrays. The value stored at any particular index is the character associated with that key. For example, the code assigned to the M key is 0x52; the characters to which the M key is mapped are recorded at index 0x52 in the various arrays.

The tables are ordered. Character values from the first applicable array are used, even if another array might also seem to apply. For example, if Caps Lock is on and a Control key is down (and both Command keys are up), the control_map array is used, not caps_map. If a Shift key is down and Caps Lock is on, the caps_shift_map is used, not shift_map or caps_map .

Notice that the last eight tables (all except control_map ) are paired, with a table that names the Shift key (..._shift_map ) preceding an equivalent table without Shift:

  • option_caps_shift_map is paired with option_caps_map ,

  • option_shift_map with option_map ,

  • caps_shift_map with caps_map, and

  • shift_map with normal_map.
  • These pairings are important for a special rule that applies to keys on the numerical keypad when Num Lock is on:

  • If the Shift key is down, the non-Shift table is used.

  • However, if the Shift key is not down, the Shift table is used.
  • In other words, Num Lock inverts the Shift and non-Shift tables for keys on the numerical keypad.

    Not every key needs to be mapped to a character. If the value recorded in a table is -1, the key corresponding to that index is not mapped to a character given the particular modifier states the table represents. Generally, modifier keys are not mapped to characters, but all other keys are, at least for some tables. Key-down events are not generated for -1 character values.

    Dead keys

    Next are the tables that map combinations of keys to single characters. The first key in the combination is "dead"--it doesn't produce a key-down event until the user strikes another character key. When the user hits the second key, one of two things will happen: If the second key is one that can be used in combination with the dead key, a single key-down event reports the combination character. If the second key doesn't combine with the dead key, two key-down events occur, one reporting the dead-key character and one reporting the second character.

    There are five dead-key tables:

    ulong acute_dead_key[32] The table for combining an acute accent with other characters.
    ulong grave_dead_key[32] The table for combining a grave accent with other characters.
    ulong circumflex_dead_key[32] The table for combining a circumflex with other characters.
    ulong dieresis_dead_key[32] The table for combining a dieresis with other characters.
    ulong tilde_dead_key[32] The table for combining a tilde with other characters

    The tables are named after diacritical marks that can be placed on more than one character. However, the name is just a mnemonic; it means nothing. The contents of the table determine what the dead key is and how it combines with other characters. It would be possible, for example, to remap the tilde_dead_key table so that it had nothing to do with a tilde.

    Each table consists of a series of up to 16 character pairs, where each character is declared as a ulong. The first character in the pair is the one that must be typed immediately after the dead key. The second character is the resulting character, the character that's produced by the combination of the dead key plus the first character in the pair. For example, if the first character is 'o', the second might be 'ô'--meaning that the combination of a dead key plus the character 'o' produces a circumflexed 'ô'.

    The character pairs in the default grave_dead_key array look something like this:

       ' ', '`',
       'A', 'À',
       'E', 'È',
       'I', 'Ì',
       'O', 'Ò',
       'U', 'Ù',
       'a', 'à',
       'e', 'è',
       'i', 'ì',
       'o', 'ò',
       'u', 'ù',
       . . .

    By convention, the first pair in each array is a space followed by the dead-key character itself. This pair does double duty: It states that the dead key plus a space yields the dead- key character, and it also names the dead key. The system understands what the dead key is from the second character in the array.

    Character tables for dead keys

    As mentioned above, for a key to be dead, it must be mapped to the second character in a dead-key array. However, it's not typical for every key that's mapped to the character to be dead. Usually, there's a requirement that the user must hold down certain modifier keys (often the Option key). In other words, a key is dead only if selected character-map tables map it to the requisite character.

    Five additional fields of the key_map structure specify what those character-map tables are--which modifiers are required for each of the dead keys:

    ulong acute_tables The character tables that cause a key to be dead when they map it to the second character in the acute_dead_key array.
    ulong grave_tables The character tables that cause a key to be dead when they map it to the second character in the grave_dead_key array.
    ulong circumflex_tables The character tables that cause a key to be dead when they map it to the second character in the circumflex_dead_key array.
    ulong dieresis_tables The character tables that cause a key to be dead when they map it to the second character in the dieresis_dead_key array.
    ulong tilde_tables The character tables that cause a key to be dead when they map it to the second character in the tilde_dead_key array.

    Each of these fields contains a mask formed from the following constants:

    B_CONTROL_TABLE
    B_OPTION_CAPS_SHIFT_TABLE
    B_OPTION_CAPS_TABLE
    B_OPTION_SHIFT_TABLE
    B_OPTION_TABLE
    B_CAPS_SHIFT_TABLE
    B_CAPS_TABLE
    B_SHIFT_TABLE
    B_NORMAL_TABLE

    The mask designates the character-map tables that permit a key to be dead. For example, if the mask for the grave_tables field is,

       B_OPTION_TABLE | B_OPTION_CAPS_SHIFT_TABLE

    a key would be dead whenever either of those tables mapped the key to the second character in the grave_dead_key array ('`' in the example above). A key mapped to the same character by another table would not be dead.

    See also: BView::GetKeys() , modifiers(), Keyboard Information in the chapter introduction, set_modifier_key()






    The Be Book, HTML Edition, for Developer Release 8 of the Be Operating System.

    Copyright © 1996 Be, Inc. All rights reserved.

    Be, the Be logo, BeBox, BeOS, BeWare, and GeekPort are trademarks of Be, Inc.

    Last modified September 6, 1996.