display-x - Displays to an X11 server
display-x: [ [-inwin=<winid>|root] | [-screen=<screenidx>] ]
[-fullscreen] [-keepcursor] [-noaccel] [-nobuffer]
[-nocursor] [-nodbe] [-nodga] [-noevi] [-noinput]
[-nomansync] [-noshm] [-novidmode] [-physz=<sizex>,<sizey>[dpi]]
display-x displays a GGI application via an X11 server. The server may
be local or remote, and options are provided to tune performance to
various scenerios. In normal operation, a new X11 window is opened,
solid fill primitives and copybox are accelerated by the server, and a
backbuffer is kept client-side for content fills (e.g. ggiPut*
functions) and to restore data when an application has been exposed
after being concealed by another window.
Ctrl-Alt-m toggles mouse grabbing in the new window. It will try to
emulate a relative mouse device, i.e. one that can be moved arbitrarily
far in any direction without ever leaving the window. This is useful
for game controls, where loosing focus is generally undesireable. Note
that grabbing must be turned off in order to leave the window.
The X display to connect to, otherwise defaults to the display
specified in DISPLAY.
Turns on the fullscreen mode. Default mode is the windowed mode.
In fullscreen mode, the dga helper is tried first if not
disabled by -nodga or failed for some reason. Then the vidmode
helper is tried. When this fails, then the target falls back to
the windowed mode. Note, the -inwin option has no effect with
All rendering is performed in the client-side backbuffer, and
then sent to the server; no server-side accelerated graphics
operations are used. This will signifigantly slow down certain
graphics applications, but for applications that use
directbuffer and asyncronous mode extensively the effect will
not be noticeable. The only real reason to use this option,
however, is to eliminate artifacts caused by incorrectly
implemented X11 hardware drivers.
No client-side backbuffer is kept. This may result in lost data
when the LibGGI application is obscured by other windows. This
data loss can be minimized by enabling backing store in the X11
server. Using this option will cause operations which must read
back framebuffer data to be much slower, but on the other hand
can result in a slight speed gain for certain graphics
primitives. It is best used when resources are severely limited
on the client side, and with applications that do not perform
frequent ggiPut* operations. Note, with this option evExpose
events are passed to the application (Otherwise, they are
internally grabbed to update the backbuffer).
-nodbe Use of the X11 DBE extension to provide buffered frame support
Note: Currently DBE extension support has not been completed.
-nodga Use of the XFree86-DGA extension to provide direct framebuffer
access is disabled. Some implementations of the XFree86-DGA
extension may cause system lockups. Use this option to prevent
-noevi Use of the X11 Extended Visual Information extension to identify
visuals which are exclusively used for overlay/underlay is
X events sent to the window are not captured and merged with any
other LibGII input sources. This allows one to take input from
raw devices without receiving duplicate events should X also be
configured to use the device.
Normal behavior of display-x is to create a small dot mouse
cursor pixmap which is visible when the mouse is positioned over
the window containing the visual. This goes away when using
mouse grabbing as described above, but otherwise can get in the
way of mouse cursors implemented by the application. With the
former option, the X mouse cursor will be invisible when it is
over the visual, with the latter, the cursor from the root
window is used unaltered. If both options are supplied, the
latter takes precedence.
Use of the mansync helper library to periodically flush
backbuffer contents to the X11 server is disabled. This, of
course, will result in incorrect behavior of applications that
use syncronous mode.
-noshm Use of the MIT-SHM extension to speed data transfer between
clients and servers which are running on the same machine is
disabled. Normally it is not necessary to use this option, as
use of the MIT-SHM extension is disabled automatically if it
appears to be nonfunctional.
Run in already-existing window with id winid. This can be used
to embed a LibGGI application into an X11 application. The
value should be an X11 window ID expressed as a "0x" prefixed
hexadecimal number. The special string "root" will cause the
application to run in the root window of the selected screen (or
the default screen if no explicit selection has been made.)
Note that in the root window, you may need to explicitly select
a LibGII input source using the GGI_INPUT environment variable
as the window manager will absorb all events sent to the root
window. Some features (currently frames and virtual areas) may
not work in root windows. On the other hand, when using the
root window other features like direct framebuffer access and
video hardware mode selection may be available which are not
available when the application is running in a normal window.
Use of the X11 Vidmode extension to change video timing in full-
screen modes is disabled. Some implementations of the Vidmode
extension may cause system lockups. Use this option to prevent
This option will override the physical screen size reported by
the X server, which affects applications which wish to remain
resolution independent. sizex,:p:sizey are the x,y size of the
entire screen (not just the X window containing the visual) in
millimeters, unless the optional dpi string is affixed, in which
case, they represent resolution in dots-per-inch. Yes, there are
two equals signs there, for reasons of compatibility with other
The screen to run on. Normally the biggest/deepest screen
compatible with the requested mode will be chosen; with this
option only the screen specified by screenidx will be
CLIFF NOTES ON NEW X TARGET
The old X target rendered all primitives in a RAM backbuffer, and then
copied the entire backbuffer periodically using the mansync helper to
the X screen. This caused a lot of wasted bandwidth. However, since
the bandwidth was being wasted anyway, LibGGIMISC splitline support was
a simple hack that added nearly no complexity.
The old Xlib target had no RAM backbuffer and rendered all primitives
using Xlib calls. This caused very slow performance when a lot of
individual pixels were being drawn one at a time, and slow performance
on operations which got pixel data back from the visual, since it had
to be fetched back over the wire. Also, this precluded the use of the
directbuffer on the xlib target.
The new X target in its default mode maintains both a RAM backbuffer on
the client side, and uses Xlib primitives to draw on the server side.
When a primitive, such as a drawbox, can use an Xlib function, the
command is dispatched to the X server and the data in the RAM buffer is
updated using a software renderer. For operations such as putbox, the
RAM buffer is updated first, and the synced to the X server. Unlike
the old target, the new target keeps track of a "dirty region" and only
syncs the area affected since the last time a syncronization occured.
This dirty-region tracking only keeps track of one rectangular dirty
area. A helper library that keeps track of more than one rectangle
could be implemented to improve performance of display-X and any other
similarly designed display target. To be most flexible such a target
should take weighted parameters representing the cost of transferring
data (per byte) from the backbuffer, and the per-operation cost of
initiating such a transfer, which would alter its strategy as to how
many regions are maintained and how much they overlap.
The old X target’s RAM buffer was implemented using the X target’s
drawops hooks -- that is, the RAM buffer was essentially a re-
implementation of display-memory with the extra facilities to sync to
the X server built in. The new target capitalizes on some improvements
made in display-memory, and instead it opens and loads a child display-
memory visual which takes care of finding software renderers for the
RAM buffer. The main drawops of the new target dispatch the the X
server commands and call the child’s corresponsing software drawops to
ensure consistant state of the RAM buffer vs the X window. This must
be done such that any requests to get data from the RAM backbuffer are
not processed until the RAM backbuffer is up to date, and any flushes
from the backbuffer are not processed until the backbuffer is up to
date. There’s a lot of locking intracacy to ensure this level of
The basic syncronization operation is accomplished by the flush
function, which is the function loaded on the xpriv flush member hook.
The flush hook function is called:
1 When the mansync helper decides it is time to refresh the screen.
2 After a primitive, if the visual is in syncronous rendering mode.
3 When an expose or graphicsexpose event is sent from the server.
This means the server has discarded data that was concealed by
another window or by the edge of the screen, and the data must be
resent from the client.
In the last case the whole area that must be refreshed is sent again by
the client. In the first two cases only the dirty area is sent, except
when the application is holding the directbuffer writing resource, in
which case the whole area must be synced because there is no way for
the target to tell what the user has modified. Holding the
directbuffer write resource open when the display is in syncronous mode
or when also sending primitives will result in bad perfomance. There’s
no reason to do so on any target, so don’t.
Unfortunately some XFree86 drivers are buggy, and when you render an
accelerated primitive which overlaps an area which is not visible to
the user, the driver fails to update the backing store (it only draws
the clipped primitive using accelarated functions and does not complete
the job by calling the software renderer to update the backing store.)
Most people will not be affected by this bug, however.
The new X target implements gammamap (DirectColor), unlike the old
The new X target is best used with backing store turned on in the
server. When backing store is not turned on, primitives which are
clipped to the visual area but still in the virtual area may be slower
then the old target, since data will be sent to the server hoping it
will be stored in the backing store. Likewise when a full-screen flush
occurrs the entire virtual area data is sent. The target could be
optimized not to send this data when it detects that there is no
backing store available in the server.
Either the RAM backbuffer or the X primitives can be disabled via
target options, which will cause emulation of the old X (-noaccel) and
Xlib (-nobuffer) targets, with a couple of notable exceptions:
The old X and Xlib targets opened a window and drew directly
into it. The old Xlib target did not implement support for
ggiSetOrigin. As noted above the old X target used a hack that
didn’t cost much when compared to the cost of syncing the
backbuffer periodically. The new target implements ggiSetOrigin
by creating a parent window, then creating a child window inside
the parent window. Thus the child window can be moved around
inside the parent window, and the parent window will clip the
displayed data to the right size. This is much more efficient
than the old way when the server is keeping a backing store
(which it sometimes does "in secret" even when the backing store
functionality in the server is turned off.)
Unfortunately many window managers seem to be buggy, and do not install
the colormap of a child window when a mouse enters it. This causes
palette and gammamap to be messed up. Since so many windowmanagers
fail to implement the behavior described in the Xlib manpages, a
workaround needs to be added which will not use the child window (this
part is easy enough since the -inwin=root option already implements a
child-less rendering) and either disables ggiSetOrigin support, or uses
a better version of the old display-x target’s creative blitting to
emulate setorigin support.
LibGGIMISC’s splitline support for the original X display was broken by
the new child-window stuff as well. In order to implement splitline
support, libggimisc must implement a new set of primitives for the new
display X that uses two child windows to produce the splitline effect.
This complicates a lot of the primitives, so the code is best isolated
in LibGGIMISC so any bugs or performance issues in it do not affect
vanilla LibGGI users who have no need for splitline. It would probably
be best if the special renderers were only loaded on the first call to
ggiSetSplitline, so that when LibGGIMISC implements support for the
XSync extension, users who are not using splitline do not pay a
performance penalty for using XSync.
The child window may also be to blame for the fact that a window which
is focused, but not moused over, stops receiving keyboard events.
Reworking the X input target to take it’s keyboard events from the
parent window instead of the child window (mouse and
expose/graphicsexpose events must still come from the child window)
would be the needed fix.
The new target tries to remove dl dependencies by creating a separate
module file for any X extensions used. Because of some deficiencies in
the X module system (there is no way to cleanly unload a module) some
kludges have had to be made when a module is loaded but gleaned to be
nonpresent, then unloaded. This won’t effect most people.
However, a more common problem will be seen because X does not give us
any way to determine if the XSHM extension will work -- it tells us
whether the server has XSHM, but it does not tell us whether the client
and server can share memory segments. Thus, when running a remote
client, it may be necessary to manually disable XSHM support with the
-noshm target option.
Anyway, I hope this is helpful to any intrepid soul which decides to
fondle this code :-) (Brian S. Julin)
· DirectBuffer always available.
· Multiple frames except for root window
· Panning except for root window
· Support Gammamap