Is this the proper list to post advanced Xlib questions? If not, any
recommendations? Using Xlib, my hopes are to create two or more hardware
overlay transparencies atop of a main window. I found an example program for
hardware overlays, but, with only one overlay. Ive extended the example (see
below) to several overlays. My problem is the inner overlay graphics do not
show through the top overlay window. Partial code is listed below. Any
oversights i have made, or, is there any tricks to make the inner layer visible
through the top layer? Perhaps an alternative software transparency technique
is recommended? i do have an example using the xshape extension. Also have an
example of the alpha blending technique made possible with the XRender
extension. Neither seem appropriate for my application. Xrender appears way
to complicated to merge with my existing application.
The software application I am working on was written many years back using only
the basic Xlib. The window depth was 8 bits and utilized a shifted color index
methodology to create pseudo window overlays. My task is to revamp the graphics
software to use a 24 bit color depth. In doing so, i now need a new way using
Xlib to make two transparent overlays to go atop my main window, a window that
displays a terrain map. Likewise, three more overlays are required for the
menu. The top layers display vehicle icons, text, and temporary graphics. Ive
explored both hardware overlays and software transparencies. it would so nice
to be able to take advantage of hardware overlays. My graphics card supports up
to 4 overlays. I call an XRaiseWindow to draw on the requested layer. Also
annoying is the Expose event initiated with the call to XRaiseWindow. Am using
an Xlib single overlay example Mark Kilgard posted many years back.
In the following code snippet example, based on a single overlay example
written my Mark Kilgard, I create three overlays. Perhaps there is an option to
add to insure the middle overlays are visible through the top overlay?
my platform is a pc laptop running Red Hat release 4. Video card is NVIDIA
Quadro FX 2700M.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "sovLayerUtil.h"
#define SIZE 400 /* Width and height of window. */
Display *dpy;
Window root, win, overlay1, overlay2, overlay[10];
Colormap cmap[10];
Visual *defaultVisual;
int screen, black, white, red,blue,green,brown,forcolor[10], nVisuals, i,k,
status;
GC normalGC, overlay1GC, overlay2GC, overlayGC[10];
XEvent event;
sovVisualInfo template;
sovVisualInfo *otherLayerInfo, *yetanotherLayerInfo, *defaultLayerInfo;
XSetWindowAttributes winattrs;
XGCValues gcvals;
XColor color, exact;
int x = 0, y = SIZE / 2;
static char*text_color[]={"red","blue","green","yellow"};
main(int argc, char *argv[])
{
// open display, dpy, and retrieve the root window ID and default visual ID
dpy = XOpenDisplay(NULL);
if (dpy == NULL)
fatalError("cannot open display");
screen = DefaultScreen(dpy); // screen
root = RootWindow(dpy, screen); // root window
defaultVisual = DefaultVisual(dpy, screen); // default visual id
/* Find layer info of default visual. */
// Assignment of properties to template is required
// for sovGetVisualInfo to compare and find a Visual
// with similar properties as the template.
template.vinfo.visualid = defaultVisual->visualid;
defaultLayerInfo = sovGetVisualInfo(dpy, VisualIDMask,
&template, &nVisuals); // we now have default layer info
/* Look for visual with transparent pixel in layer "above"
default visual */
template.layer = defaultLayerInfo->layer + 1; //VisualLayerMask
template.vinfo.screen = screen; //VisualScreenMask
template.type = TransparentPixel; //VisualTransparentType
otherLayerInfo = sovGetVisualInfo(dpy,
VisualScreenMask | VisualLayerMask | VisualTransparentType,
&template, &nVisuals);
if (otherLayerInfo == NULL) {
fatalError("unable to find 2nd layer above default visual"); } else {
// layer above default Visual exists!
/* Create *base* window using default visual. */
// the Simple Window inherets its depth, class, and visual
// from its parent. All other attributes have their default
// values. Cursor will be that of the window's parent
// until the cursor attribute is set with XDefineCursor or
// XChangeWindowAttributes. Note no colormap is required
// if visual is same as parent.
black = BlackPixel(dpy, screen);
white = WhitePixel(dpy, screen);
win = XCreateSimpleWindow(dpy, root, 10, 10, SIZE, SIZE, 1,
black, white);
// Sort through next layers
otherLayerInfo = sovGetVisualInfo(dpy,
VisualScreenMask | VisualLayerMask | VisualTransparentType,
&template, &nVisuals);
for( i = 0; i<3; i++){
printf(" i : %d\n", i);
printf(" Visual ID: 0x%x\n", otherLayerInfo[i].vinfo.visualid);
printf(" screen: %d\n", otherLayerInfo[i].vinfo.screen);
printf(" depth: %d\n", otherLayerInfo[i].vinfo.depth);
printf(" value: %d\n", otherLayerInfo[i].value);
// now,create colormap for overlay
cmap[i] = XCreateColormap(dpy, root,
otherLayerInfo[i].vinfo.visual, AllocNone);
// fetch assignment for "red" the first layer, green the second layer, blue
the third.
// status = XAllocNamedColor(dpy, cmap[i], "red", &color, &exact);
status = XAllocNamedColor(dpy, cmap[i], text_color[i], &color, &exact);
if (status == 0)
fatalError("could not allocate red");
forcolor[i] = color.pixel;
printf(" color allocated from cmap: %d\n",i);
// set up window attributes with new colormap, no border
/* Use transparent pixel for background */
winattrs.background_pixel = otherLayerInfo[i].value;
winattrs.border_pixel = 0; /* No border but still
necessary to avoid BadMatch. */
winattrs.colormap = cmap[i];
// create the window overlay
overlay[i] = XCreateWindow(dpy, win, 0, 0, SIZE, SIZE, 0,
otherLayerInfo[i].vinfo.depth,
InputOutput, otherLayerInfo[i].vinfo.visual,
CWBackPixel | CWBorderPixel | CWColormap, &winattrs);
printf(" Finished Overlay: %d\n",i);
}
}
// solicit input for normal window and input for overlay1
XSelectInput(dpy, win, ExposureMask);
for( i = 0; i<3; i++){
XSelectInput(dpy, overlay[i], ExposureMask | ButtonPressMask);
// set the WM_COLORMAP_WINDOWS property on window,win, to the list of
// windows specified in argument 3, ie &overlay1 of qty 1.
// This property tells the window manager that subwindows of this
// application need to have their own colormaps installed.
XSetWMColormapWindows(dpy, win, &overlay[0], 4);
// set graphic content values of normalGC
gcvals.foreground = black;
gcvals.line_width = 8;
gcvals.cap_style = CapRound;
// Create normalGC
normalGC = XCreateGC(dpy, win,
GCForeground | GCLineWidth | GCCapStyle, &gcvals);
// Create overlayGC, each with a new foreground color.
gcvals.foreground = forcolor[i];
overlayGC[i] = XCreateGC(dpy, overlay[i], GCForeground, &gcvals);
}
// map window and its subwindows
XMapSubwindows(dpy, win);
XMapWindow(dpy, win);
....
//in event loop, a call to redrawOverlayPlanesMessage to draw , upon mouse
click, a message on each overlay:
printf(" draw on overlay: %// wait for action d\n", j);// wait for action
i=0;
while (1) {
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
if (event.xexpose.window == win)
redrawNormalPlanes();
else {
// redrawOverlayPlanesMessage(i);
}
break;
case ButtonPress:
x = random() % SIZE / 2;
y = random() % SIZE;
i++;
if( i>2) i=0;
// XClearWindow(dpy, overlay[i]);
redrawOverlayPlanesMessage(i);
break;
}
}
void redrawOverlayPlanesMessage(int j)
{
if( j == 0){
x = random() % SIZE / 2;
y = random() % SIZE;
XRaiseWindow(dpy,overlay[j]);
XDrawString(dpy, overlay[j], overlayGC[j], x, y + 15,
MESSAGE0, sizeof(MESSAGE0) - 1);
printf(" draw on overlay: %d\n", j);
}
if( j == 1 ){
x = random() % SIZE / 2;
y = random() % SIZE;
XRaiseWindow(dpy,overlay[j]);
XDrawString(dpy, overlay[j], overlayGC[j], x, y + 15,
MESSAGE1, sizeof(MESSAGE1) - 1);
printf(" draw on overlay: %d\n", j);
}
}
}
_______________________________________________
[email protected]: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: http://lists.freedesktop.org/mailman/listinfo/xorg
Your subscription address: [email protected]