The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Prima::X11 - usage guide for the X11 environment

DESCRIPTION

This document describes subtle topics one must be aware of when programming or using Prima programs under X11. The document covers various aspects of the toolkit and its implementation details with the guidelines of the expected use. Also, some of the X11 programming techniques are visited.

Basic command-line switches

--help

Prints the available command-line arguments and exits

--display

Sets the X display address in the Xlib notation. If not set, the standard Xlib ( XOpenDisplay(null) ) behavior applies.

Example:

   --display=:0.1
--visual

Sets the X visual to be used by default. Example:

   --visual=0x23
--sync

Turn on the X synchronization

--bg, --fg

Set the default background and foreground colors. Example:

  --bg=BlanchedAlmond
--font

Sets the default font in either XLFD or Fontconfig format. Examples:

   --font=serif
   --font=Arial-16:bold
   --font='adobe-helvetica-medium-r-*-*--*-120-*-*-*-*-*-*'
--no-x11

Runs Prima without the X11 display initialized. This switch can be used for programs that use only the OS-independent parts of Prima, such as the image subsystem or the PDF generator, in environments where X is not present, for example, from a CGI script. Any attempt to create an instance of the Prima::Application class or otherwise access the X-depended code under such conditions causes the program to abort.

There are alternatives to the command switch. First, there is module Prima::noX11 for the same purpose but that is more convenient to use as the

   perl -MPrima::noX11

construct. Second, there is the technique to continue execution even if the connection to the X server fails:

   use Prima::noX11;
   use Prima;

   my $error = Prima::XOpenDisplay();
   if ( defined $error) {
        print "not connected to display: $error\n";
   } else {
        print "connected to the X display\n";
   }

The Prima::noX11 module exports the single function XOpenDisplay into the Prima namespace, to connect to the X display explicitly. The display to be connected to is the $ENV{DISPLAY} unless stated otherwise on the command line ( with the --display option) or with a parameter to the XOpenDisplay function.

This technique may be useful to programs that use Prima imaging functionality and may or may not use the windowing capabilities.

The X11 resources database

X11 provides XRDB, the X resource database, a named list of arbitrary string values stored on the X server. Each key is a combination of names and classes of widgets in the text format. The key is constructed so that the leftmost substring ( the name or the class ) corresponds to the top-level item in the hierarchy, usually the application name or class. Although the XRDB can be also written via the native X API, it is rarely done by applications. Instead, the user creates a file usually named .Xdefaults which contains the database in the text form.

The format of the .Xdefaults file directly reflects the XRDB capabilities, one of the most important of which is globbing, manifested via the * ( star ) character. With the use of the globbing, the user can set up a property value that corresponds to multiple targets:

   *.ListBox.backColor: yellow

The string above means that all widgets of the ListBox class must have a yellow background.

The application itself is responsible for parsing the strings and querying the XRDB. Also, both class and widget names, as well as the database values are fully defined in terms of the application. There are some guidelines though, for example, the colors and fonts are best described in the terms native to the X server. Also, classes and names are distinguished by the case: classes must begin with the uppercase letter. Finally, not every character can be stored in the XRDB database (space, for example, cannot be) and therefore the XRDB API automatically converts these to the _ ( underscore ) characters.

Prima defines its own set of resources, divided into two parts: general toolkit settings and per-widget settings. The general settings functionality is partially overlapping with the command-line arguments. The per-widget settings are the fonts and colors that can be defined for each Prima widget.

All of the general settings apply to the top-level item of the widget hierarchy, named after the application, and the Prima class. Some of these though needed to be initialized before the application instance itself is created, so these can be accessed via the Prima class only, for example, Prima.Visual. Some, on the contrary, may occasionally overlap with the per-widget syntax. In particular, one must be wary not to write

   Prima*font: myfont

instead of

   Prima.font: myfont

The latter syntax is a general setting and changes the default Prima font only. The former is a per-widget assignment, and explicitly sets the font to all Prima widgets, effectively ruining the toolkit font inheritance scheme. The same is valid for an even more powerful

   *font: myfont

record.

The allowed per-widget settings are the color and font settings only ( see the corresponding sections ). It is an arguably useful feature to map all the widget properties onto XRDB, but Prima does not implement this, primarily because no one asked for it, and also because this creates unnecessary latency when the enumeration of all possible widget properties takes place for every widget.

All of the global settings' classes and names are identical except for their first letter. For example, to set the Submenudelay value, one can do it either by the

   Prima.Submenudelay: 10

or by the

   Prima.submenudelay: 10

syntax. Despite that, these calls are different, in a way that one reaches for the whole class and another for the name, for the majority of these properties it does not matter. To avoid confusion all class names are camelcase while the property names are lowercase.

Fonts

Default fonts

Prima::Application defines the set of get_default_XXX_font functions, where each returns the font that is predefined by the system or by the user through the system settings, to be displayed correspondingly in menus, messages, window captions, and all other widgets. While in f ex Win32 these are indeed the configurable user options, the raw X11 protocol doesn't define any. If the toolkit is compiled with the GTK, then the default fonts can be read from the GTK settings. Nevertheless, as the high-level code relies on these, the corresponding resources are defined. These are:

  • font - Application::get_default_font

  • caption_font - Application::get_caption_font. Used in Prima::MDI.

  • menu_font - Widget::get_default_menu_font. The default font for the pull-down and pop-up menus.

  • msg_font - Application::get_message_font. Used in Prima::MsgBox.

  • widget_font - Widget::get_default_font.

All of the global font properties can only be set via the Prima class, no application name is recognized. Also, these properties are identical to --font, --menu-font, --caption-font, --msg-font, and --widget-font command-line arguments. The per-widget properties are font and popupFont, of class Font, settable via XRDB only:

   Prima*Dialog.font: my-fancy-dialog-font
   Prima.FontDialog.font: some-conservative-font

By default, Prima font is 12.helvetica .

X core fonts

The values of the font entries are standard XLFD strings, formatted with the default *-*-*-*-*-*-*-*-*-*-*-*-*-*-* pattern, where each star character can be replaced by a particular font property, such as name, size, charset, and so on. To interactively select an appropriate font, use the standard xfontsel program from the Xorg distribution.

Note, that the encoding part of the font is recommended to be left unspecified, otherwise it may clash with the LANG environment variable that is used by the Prima font subsystem to determine which font to select when no encoding is given. This advice, though, is correct only when both the LANG and encoding part of the desired font match. To force a particular font encoding, the property Prima.font must contain one.

Alternatively, and/or to reduce X font traffic, one may set the IgnoreEncodings.ignoreEncodings property, which is a semicolon-separated list of encodings Prima must not use. This feature has limited usability when for example fonts in the Asian encodings result in large font requests. Another drastic measure to decrease font traffic is the boolean property Noscaledfonts.noscaledfonts, which, if set to 1, restricts the choice of fonts to the non-scalable fonts only.

Xft fonts

Prima can compile with the Xft library, which contrary to core X font API, can make use of the client-side fonts. Plus, the Xft library offers appealing features such as font antialiasing, unicode, and arguably a better font syntax. The Xft font syntax is inherited from the fontconfig library and is to be consulted from man fonts-conf. For example:

   Palatino-12

A font with the name Palatino and a size of 12 points.

   Arial-10:BI

A font with the name Arial, size of 10 points, bold, and italic. The fontconfig syntax allows more than that, for example, arbitrary matrix transformations, but Prima can make use only of the font name, size, and style flags.

--no-xft

The --no-xft command-line argument, and the corresponding boolean UseXFT.usexft XRDB property can be used to disable the use of the Xft library.

--no-core-fonts

Disables all X11 core fonts, except the fixed font. The fixed font is selected for the same reasons that the X server is designed to provide at least one font, which usually is fixed.

It is valid to combine --no-core-fonts and --no-xft. Moreover, adding --noscaled to these gives Prima programs the very classic X look.

--font-priority

Can be set to either xft or core, to select the font provider mechanism to match unknown or incompletely specified fonts against.

Default value: xft ( if compiled in ), core otherwise.

--no-aa

If set, turns off the Xft font antialiasing.

Colors

XRDB conventions

The X11 is traditionally shipped with the color names database, usually a text file named rgb.txt. Check your X manual where exactly this file resides and what is its format. The idea behind it is that users can benefit from portable literal color names, with color values transparently adjustable to display capabilities. Thus, it is customary to write

   color: green

for many applications, and these in turn call the XParseColor function to convert strings into RGB values.

Prima can also support this functionality. Each widget can assign eight color properties: color, hiliteBackColor, disabledColor, dark3DColor backColor, hiliteColor, disabledBackColor, light3DColor by their name:

   Prima.backColor: #cccccc

Additionally, the following command-line arguments allow overriding the default values for these properties:

  • --fg - color

  • --bg - backColor

  • --hilite-fg - hiliteColor

  • --hilite-bg - hiliteBackColor

  • --disabled-fg - disabledColor

  • --disabled-bg - disabledBackColor

  • --light - light3DColor

  • --dark - dark3DColor

Visuals

The colors in the X11 protocol require the pixel values to be explicitly defined. A pixel value is a 32-bit unsigned integer that encodes color in the display format. There are two different color coding schemes - the direct color and the indexed color. The direct color-coded pixel value can unambiguously be converted into an RGB value without any additional information. The indexed-color scheme represents the pixel value as an index in a palette that resides on the X server. The X11 display can contain more than one palette, and allow ( or disallow ) modification of the palette color cells depending on the visual the palette is attached to.

A visual is an X server resource with a specific representation of the color coding scheme, color bit depth, and modifiability of the palette. The X server can ( and usually does ) provide more than one visual, as well as different pixel bit depths. There are six classes of visuals in the X11 paradigm. In each, Prima behaves differently, also depending on the display bit depth available. In particular, the color dithering can be used on the displays with less than 12-bit color depth. On the displays with the modifiable color palette Prima can install its own values in palettes, which may result in an effect known as palette flashing.

To switch to a non-default visual, use the Prima.Visual XRDB property or the --visual command-line argument. The list of visuals can be produced by the standard xdpyinfo command from the Xorg distribution, where each class of the visual corresponds to one of the six following classes:

StaticGray

All color cells are read-only and contain monochrome values only. A typical example is a two-color, black-and-white monochrome display. This visual is extremely rare.

GrayScale

Contains a modifiable color palette, and is capable of displaying monochrome values only. Theoretically, any paletted display on a monochrome monitor can be treated as a GrayScale visual. For both GrayScale and StaticGray visuals Prima resorts to dithering if it cannot get at least 32 evenly spaced gray values from black to white.

StaticColor

All color cells are read-only. A typical example is a PC display in the 16-color EGA mode. This visual is extremely rare.

PseudoColor

All color cells are modifiable. Typically, the 8-bit displays define this class as the default visual. For both StaticColor and PseudoColor visuals dithering is always used, although on the PseudoColor visuals Prima resorts to that only if the X server cannot allocate a required color.

On the PseudoColor and GrayScale visuals Prima allocates a small fixed set of colors, not used for palette modifications. When a pixmap is to be exported via clipboard, displayed in the menu, or sent to the window manager as an icon to be attached to a window, it is resampled so that it uses these colors only, which are guaranteed to stay immutable through the life of the application.

TrueColor

Each pixel value is explicitly coded as RGB. Typical examples are 16, 24, or 32-bit display modes. This visual class is the best in terms of visual quality.

DirectColor

Same as TrueColor, but additionally each pixel value can be reprogrammed. Not all hardware supports this visual, and usually this visual is not set as the default one. Prima supports this mode in the same way as it does the TrueColor visual without any additional features.

Images

The X11 protocol does not standardize the pixel memory format for the TrueColor and DirectColor visuals, so there is a chance that Prima won't work on some bizarre hardware. Currently, Prima knows how to compose pixels of 15, 16, 24, and 32 bit depth, of contiguous ( not interspersed ) red-green-blue memory layout. Any other pixel memory layout causes Prima to fail.

Prima supports the shared memory image X extension that greatly speeds up displaying images on the X servers running on the same machine as the X client. The price for this is that if the Prima program aborts, the shared memory will never be returned to the OS. To remove the leftover segments, use your OS facilities, for example, ipcrm on Linux and BSD.

To disable the user of the shared memory with images use the --no-shmem switch in the command-line arguments.

The clipboard exchange of images is incompletely implemented, since Prima does not accompany ( and neither reads ) COLORMAP, FOREGROUND, and BACKGROUND clipboard data, which contains the RGB values for the paletted image. As a palliative, the clipboard-bound images are downgraded to the safe immutable set of colors.

A note on the images in the clipboard: contrary to the text in the clipboard, which can be used several times, images seemingly cannot. The Bitmap or Pixmap descriptor, stored in the clipboard, is rendered invalid after it has been read once. This does not apply to the more modern clipboard exchange protocol based on images being encoded as binary data, f ex in PNG format. Prima prefers this exchange protocol whenever possible.

Window managers

The original design of the X protocol did not include the notion of a window manager, and the latter was implemented as an ad-hoc patch, which results in possible race conditions when configuring widgets.

Prima was tested with alternating success under the following window managers: mutter, marco, mwm, kwin, wmaker, fvwm, fvwm2, enlightenment, sawfish, blackbox, 9wm, olvm, twm, and in no-WM environment.

Protocols

Prima makes use of the WM_DELETE_WINDOW and WM_TAKE_FOCUS protocols. While the WM_DELETE_WINDOW protocol usage is straightforward and needs no further attention, the WM_TAKE_FOCUS protocol can be tricky, since X11 defines several of the input modes for a widget, which behave differently for each WM. In particular, the 'focus follows pointer' policy gives problems under twm and mwm when the navigation of drop-down combo boxes is greatly hindered by the window manager. The drop-down list is programmed so it is dismissed as soon its focus is gone; these window managers withdraw focus even if the pointer is over the focused widget's border.

Hints

Size, position, icons, and other standard X hints are passed to WM in a standard way, and, as the inter-client communication manual ( ICCCM ) allows, are ften misinterpreted by window managers. Many ( wmaker, for example ) apply the coordinates given by the program not to the top-level widget itself, but to its decoration. mwm defines a list of the accepted icon sizes so these can be absurdly large, which adds to the confusion for an X client that can create an icon of any size but is unable to determine the best one.

Non-standard properties

Prima tries to use the WM-specific hints for two window managers it knows about: mwm and kwin. For mwm ( Motif window manager ) Prima sets hints for the decoration border width and icons. For kwin ( and probably to others that conform to the specifications of http://www.freedesktop.org/ ) Prima uses the NET_WM_STATE property, in particular for the implementation of the window maximization and the visibility of windows in the taskbar.

Use of these properties explicitly contradicts ICCCM and definitely might lead to bugs in the future ( at least with NET_WM_STATE, since the Motif interface can hardly expected to be changed ). To disable the use of the non-standard WM properties, the --icccm command-line argument can be set.

Unicode

The core X11 protocol does not support unicode, and a number of patches were applied to X servers and clients to make the situation change. Prima can only effectively support unicode text shaping and rendering if compiled with the Xft, fontconfig, harfbuzz, and the fribidi libraries.

The core X11 protocol supports text rendering when the text is sent as either 8-bit or 16-bit integers, but neither can be used to display unicode strings properly. Also, the core font transfer protocol suffers from ineffective memory representation, which creates latency when fonts with a large span of glyphs are loaded. Such fonts, in the still uncommon but standard iso10646 encoding, are the only media to display multi-encoding text if the Xft services are unavailable.

These and some other problems are efficiently solved by the Xft library, a superset of X core font functionality. Xft features Level 1 ( November 2003 ) unicode display and supports 32-bit text strings as well as UTF8-coded strings. Xft does not operate with charset encodings, and these are implemented in Prima using the iconv charset converter library.

Clipboard

Prima supports the UTF8 text in the clipboard via the UTF8_STRING format.

Because any application can take ownership of the clipboard at any time, open/close brackets are not strictly respected in the X11 implementation. Practically, this means that when modern X11 clipboard daemons ( KDE klipper, for example ) interfere with the Prima clipboard, the results may not be consistent from the programmer's view, for example, the clipboard contains data after a clear call. It must be noted though that this behavior is expected by the users.

Other XRDB resources

Timeouts

The X11 protocol provides no such GUI helpers as the double-click event, cursor, or menu. Neither does it provide the related time how often, for example, a cursor should blink. Therefore Prima emulates these but allows the user to reprogram the corresponding timeouts. Prima recognizes the following properties, accessible either via the application name or the Prima class key. All timeouts are integer values, the number of milliseconds for the corresponding timeout property.

Blinkinvisibletime.blinkinvisibletime: MSEC

The cursor stays invisible in MSEC milliseconds.

Default value: 500

Blinkvisibletime.blinkvisibletime: MSEC

The cursor stays visible in MSEC milliseconds.

Default value: 500

Clicktimeframe.clicktimeframe MSEC

If the 'mouse down' and 'mouse up' events follow each other within MSEC milliseconds, the 'mouse click' event is synthesized.

Default value: 200

Doubleclicktimeframe.doubleclicktimeframe MSEC

If the 'mouse click' and 'mouse down' events follow each other within MSEC milliseconds, the 'mouse double click' event is synthesized.

Default value: 200

When the user clicks on a menu item that points to a lower-level menu window, the latter is displayed after MSEC milliseconds.

Default value: 200

Scrollfirst.scrollfirst MSEC

When an auto-repetitive action, similar to keystroke events resulting from a long key press on the keyboard, is to be simulated, two timeout values are used, the 'first' and the 'next' delay. These actions are not simulated within Prima core, and the corresponding timeouts are advisory for the programmer. Prima widgets use it for automatic scrolling, either by a scrollbar or by any other means. Also, the Prima::Button widgets can use these timeouts for the emulation of a key press in the autoRepeat mode.

Scrollfirst is a 'first' timeout.

Default value: 200

Scrollnext.scrollnext MSEC

Same as Scrollfirst but for the 'next' delay event.

Default value: 50

Miscellaneous

Visual.visual: VISUAL_ID

Selects the display visual VISUAL_ID which usually has a form of 0x?? hexadecimal number. Different visuals provide different color depth and pixel encoding schemes. Some X servers have badly chosen default visuals (for example, the default IRIX workstation setup has an 8-bit default visual selected), so this property can be used to fix things. A list of the visuals supported by the X display can be produced interactively by the standard xdpyinfo command from Xorg distribution.

Identical to the --visual command-line argument.

See Color for more information.

Wheeldown.wheeldown BUTTON

BUTTON is the numeric ID of the X mouse button, which corresponds to the mouse wheel 'down' event.

Default value: 5 ( default values for wheeldown and wheelup are current de-facto most popular settings ).

Wheelup.wheelup BUTTON

BUTTON is the numeric ID of the X mouse button, which that is corresponds to the mouse wheel 'up' event.

Default value: 4

Debugging

The famous 'use the source' call is highly actual with Prima. However, some debug information comes already compiled in, and can be activated by the --debug command-line key. Its parameter is a combination of letters where each activates the debugging of different subsystems:

  • C - clipboard

  • E - events subsystem

  • F - fonts

  • M - miscellaneous debug info

  • P - palettes and colors

  • X - XRDB

  • A - all of the above

Example:

   --debug=xf

Also, the built-in X API XSynchronize call, which enables the X protocol synchronization ( at the expense of operation slowdown though ) is activated with the --sync command-line argument, and can be used to ease the debugging.

GTK

Prima can be compiled with GTK and can use its colors and font schemes, and also the standard GTK file dialogs. This can be disabled with the --no-gtk command line switch.

On MacOSX, GTK usually comes compiled with the Quartz backend, which means that Prima will get into problems with the remote X11 connections. Prima tries to detect this condition, but if the trouble persists, please use the --no-gtk switch (and please file a bug report so this can be fixed, too).

Quartz

Prima can be compiled with the Cocoa library on MacOSX that gives access to the screen scraping functionality that is used by the Application.get_image method and which otherwise is non-functional with XQuartz. To disable this feature use the --no-quartz command-line switch.

AUTHOR

Dmitry Karasik, <dmitry@karasik.eu.org>.

SEE ALSO

Prima, Prima::gp-problems, Prima::Widget, Nye A, Xlib programming manual. O'Reilly & Associates, 1995.