Linearity of a visual can be determined in Solaris by querying the visual's gamma. This is done by calling XSolarisGetVisualGamma(3). If the gamma value is equal to (or close to) 1.0, the visual is linear. Otherwise, it is nonlinear. A good rule-of-thumb for the closeness tolerance is 10%. To use the XSolarisGetVisualGamma API, the application must be linked with the Solaris libXmu.
Example 3-1 is an example of selecting the best visual for a typical XGLTM 3D linear application. In this example, the application uses a nonlinear visual if a linear one cannot be found. This is only one possible visual selection policy.
If the gamma of any visual on the device is changed, either through reconfiguration or calibration, the window system should be restarted. Otherwise, applications using XSolarisGetVisualGamma that are already running will not detect the change and may use the wrong visual.
/* ** Returns the visual of the given depth, class and linearity, ** or NULL if not found. */ Visual * match_visual (Display *dpy, int screen, int depth, int class, Bool wantLinear) { XVisualInfo template; XVisualInfo *vinfo, *vi; int nitems, isLinear, i; double gamma; template.screen = screen; template.depth = depth; template.class = class; if (!(vinfo = XGetVisualInfo(dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &template, &nitems)) || nitems <= 0) { return (NULL); } for (i = 0, vi = vinfo; i < nitems; i++, vi++) { if (XSolarisGetVisualGamma(dpy, screen, vi->visual, &gamma) == Success) { /* ** A good rule of thumb for linearity of a visual is ** whether the gamma is within 10% of 1.0. */ isLinear = (gamma >= 0.9 && gamma <= 1.1); if ((wantLinear && isLinear) || (!wantLinear && !isLinear)) { Visual *visual = vi->visual; XFree(vinfo); return (visual); } } } XFree(vinfo); return (NULL); }
Here is the main routine of the example:
main () { Visual vis; ... if ((vis = match_visual(display, screen, 24, TrueColor, True))) { fprintf(stderr, "Found a linear 24-bit TrueColor visual\n"); visualClass = TrueColor; depth = 24; } else if ((vis = match_visual(display, screen, 24, TrueColor,False))){ fprintf(stderr, "Found a nonlinear 24-bit TrueColor visual\n"); visualClass = TrueColor; depth = 24; } else if ((vis = match_visual(display, screen, 8, PseudoColor,False))){ fprintf(stderr, "Found a nonlinear 8-bit PseudoColor visual\n"); visualClass = PseudoColor; depth = 8; } else { fprintf(stderr, "Cannot match 24 or 8 bit visual\n"); exit(1); } ... }