Xlib hardware multi overlay transparency question

Diaz, James M James.Diaz at gdit.com
Thu Jul 14 14:46:20 PDT 2011



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);
  }
}
}




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.x.org/archives/xorg/attachments/20110714/9e5fb61c/attachment.html>


More information about the xorg mailing list