mtoy@xman.sgi.COM (Michael Toy -- The S.G.I. XMAN) (11/04/87)
I'm close to the light at the end of the tunnel on this one. Mission: Create a colormap filled in with the correct hardware values on a StaticColor display. (I actually have a PsedoColor display, but I want X to use a particluar already set up colormap with nice ramps in it) PortingLayer doc suggests checking the BeingCreated bit in the ddx CreateColormap routine and if it is set, calling AllocColor for each pixel. This doesn't work. AllocColors calss Find<mumble> which just returns if your visualtype is StaticColor. What mostly works for ms is filling a xColorItem structure and calling StoreColors in a loop. Most things work ok unless I ask for colors up in the high parts of the colormap, then I get core dumps. So how about it Xperts? Am I on the right track? Anybody else out there been down this road? Don't tell me about cfb/sun supprt through the STATIC_COLOR #define, that stuff seems to be a dinosaurish implementation of a TrueColor visual. -- Michael Toy, secret identity: the XMAN at Silicon Graphics Someday: mtoy@xman.sgi.com For now: {ames,decwrl,sun}!sgi!mtoy
carver@3d.DEC.COM (The danger on the rocks has surely passed, still I remain tied to the mast) (11/04/87)
We needed to do the same thing in our server---in fact we needed to construct several static colormaps with device dependent color values--- and the method we use (as your mail discussed) is as follows: mid = FakeClientID(0); CreateColormap(mid,pScr,pVisTrue24,&pCmap,AllocAll,0); * StoreColors(pCmap,256,defs) * The last argument to CreateColormap is the client index, we use 0 to indicate that the server is the creator. So far as we know this works properly in our environments: VAX/ULTRIX and VAX/VMS. You may be having some sort of portability problem in dix/colormap.c. --david carver
todd@GRANITE.DEC.COM (Todd Newman) (11/05/87)
This is in reply to Michael Toy's mail. (It would be nice if the return address given is one I can actually use instead of one that will work "Someday.") I'm having trouble believing what you've said. You said: PortingLayer doc suggests checking the BeingCreated bit in the ddx CreateColormap routine and if it is set, calling AllocColor for each pixel. This doesn't work. AllocColors calss Find<mumble> which just returns if your visualtype is StaticColor. It's hard for me to believe that FindColor just returns. You've actually run this and had it fail? I'm puzzled because I double-checked the source code and can't see why it should. AllocColor will diddle with its concept of the class so that if the server is creating the colormap, and the BeingCreated flag is set, the class becomes Dynamic. That means that it will ALWAYS call FindColor when you're creating a colormap. Three points about FindColor: Firstly, FindColor never checks whether the colormap is static or not. There simply isn't such a test. Secondly, all you have to do is AllocColor with *pPix (the 5th argument) set to 0. When it calls FindColor, FindColor will start looking at the 0th map entry and keep searching till it finds an empty one. That is going to be the next free one. Just keep making the same call to AllocColor and it should return successive pixels into which you load your ramping color values. Finally, if you think about it right, you'll see that that's how the qvCreateColormap code works. The monochrome colormap is static. And I call it twice and get back two different pixels. I know it seems a lot to ask, but please trace through the FindColor and see why it's giving up. I just can't believe it's because the class is static. /tdn
paulsh@shark.tek.COM (11/10/87)
> I'm close to the light at the end of the tunnel on this one. > > Mission: Create a colormap filled in with the correct hardware values > on a StaticColor display. (I actually have a PsedoColor display, but I want > X to use a particluar already set up colormap with nice ramps in it) > > PortingLayer doc suggests checking the BeingCreated bit in the ddx > CreateColormap routine and if it is set, calling AllocColor for > each pixel. > > This doesn't work. AllocColors calss Find<mumble> which just returns if > your visualtype is StaticColor. > > What mostly works for ms is filling a xColorItem structure and calling > StoreColors in a loop. Most things work ok unless I ask for colors up > in the high parts of the colormap, then I get core dumps. > > So how about it Xperts? Am I on the right track? Anybody else out there > been down this road? Don't tell me about cfb/sun supprt through the > STATIC_COLOR #define, that stuff seems to be a dinosaurish implementation > of a TrueColor visual. > -- > Michael Toy, secret identity: the XMAN at Silicon Graphics > Someday: mtoy@xman.sgi.com For now: {ames,decwrl,sun}!sgi!mtoy I have done exactly what Michael is attempting. I have successfully used AllocColor() from within my ddx pScreen->CreateColormap routine. If you will be implementing server colormap routines, tuck this information away for later use. I'll give only accurate answers and carefully state my assumptions. (No wild guesses this time.) First from the Mission statement I am assuming that Michael is creating a colormap using a visual of class StaticColor. The goal is to then: 1. Create the StaticColor colormap by calling dix CreateColormap() 2. Initialize the color entries using AllocColor() from within ddx pScreen->CreateColormap that is called by dix CreateColormap(). StoreColors() could also be used for server owned maps, see below. 3. Install the colormap (at some point). First to clarify some confusion. > PortingLayer doc suggests checking the BeingCreated bit in the ddx > CreateColormap routine and if it is set, calling AllocColor for > each pixel. > > This doesn't work. AllocColors calss Find<mumble> which just returns if > your visualtype is StaticColor. No not quite. Let's look at the documentation closely. "Definition of the Porting Layer for the X V11 Sample Server". page 26 5.2.7.2 Initializing a Colormap When a client requests a new colormap and when the server creates the default colormap, the procedure CreateColormap in the DIX layer is invoked. That procedure allocates memory for the colormap and related storage such as the * lists of which client owns which pixels. It then sets a bit, * BeingCreated, in the flags field of the ColormapRec and * calls the DDX layer's CreateColormap routine. This is your * chance to initialize the colormap. If the colormap is static, which you can tell by looking at the class field, you will want to fill in each color cell to match the * hardwares notion of the color for that pixel. If the color- * map is the default for the screen, which you can tell by * looking at the flags field, you will want to allocate Black- Pixel and WhitePixel to match the values you set in the pScreen structure. (Of course, you picked those values to begin with.) There are two ways to fill in the colormap. The simplest way is to use AllocColor. ... ... If for some reason AllocColor doesn't do what you want, you can do your own bookkeeping and call StoreColors yourself. This is much more difficult and shouldn't be necessary for most devices. Therefore the above documentation does NOT suggest checking the BeingCreated bit and then calling AllocColor() if it is set. It simply says to check the class and if it is static, then call AllocColor(). The BeingCreated bit is not intended to be checked by pScreen->Colormap since it will always be set prior to calling this routine. The role of the BeingCreated bit is to inform dix routines, AllocColor() and FindColor(), that they have been called specifically from pScreen->CreateColormap and that they should do something special in that case, like store rgb values in static colormap entries. The bit the above documentation is referring to check is the IsDefault bit in the flags element. This allows pScreen->Colormap to do anything special to the screen default colormap, like allocate its whitePixel and blackPixel. (I actually recommend doing this later and forcing those values to agree with the colormap and not vise versa, but I'll save that discussion for another time. No guesses, just facts right now.) One problem right now is that the IsDefault bit is never set. It should, I believe, be set in dix/colormap.c CreateColormap() to agree with the above documentation. I am submitting a bug report which suggests the following addition to CreateColormap(). AddResource(mid, RT_COLORMAP, pmap, FreeColormap, RC_CORE); pmap->mid = mid; pmap->flags = 0; /* start out with all flags clear */ + if( mid == pScreen->defColormap ) + { + pmap->flags |= IsDefault; + } pmap->pScreen = pScreen; pmap->pVisual = pVisual; pmap->class = class; If this becomes a blessed fix, then you will be able to check for if( pmap->flags & IsDefault) in your ddx pScreen->CreateColormap routine. A simple workaround is to let pScreen->CreateColormap check with the test: if( pmap->mid == pmap->pScreen->defColormap) You would only be concerned about this if you want to do something special to the default colormap during its creation. Anyway, back to the mission at hand, > This doesn't work. AllocColors calss Find<mumble> which just returns if > your visualtype is StaticColor. Now it is time to look at the code closely. If you are calling AllocColor() from within pScreen->CreateColormap this WILL work PROVIDED you called CreateColormap with alloc=AllocNone. As soon as AllocColor() is entered, if the BeingCreated bit is set then the class is changed to a dynamic one. Thus your StaticColor class was changed to PseudoColor class. What probably tripped FindColor() up was the possibility (this is a good guess) that you had called CreateColormap( , , , ,AllocAll, ) This is what is done in cfb code for static colormaps. Notice that cfb code uses pScreen->CreateColormap = cfbInitialize332Colormap which does not call AllocColor() (they do it the hard way). If this was the case, then FindColor would return without Allocating the color entry values due to the fact that pent->refcnt == AllocPrivate if alloc==AllocAll. Here is a coding sequence for static colormaps if you want to use AllocNone and AllocColor(). The code may be spread out (called from different routines) but the order is important. pScreen->CreateColormap = <your ddx>CreateColormap ; ... mid = (Colormap) FakeClientID(0); ... if( <this is your default colormap> ) { pScreen->defColormap = mid; } ... CreateColormap(mid,pScreen,pVisStatic,&pColormap,AllocNone,0); ... <Inside pScreen->CreateColormap(pColormap)> for( i=0; i<pColormap->pVisual->ColormapEntries; i++) { pixel = i; ... AllocColor(pColormap,pred,pgreen,pblue,&pixel,0); } ... pScreen->InstallColormap(pColormap); ---- If you used the argument AllocAll instead of AllocNone then you have to initialize the color entry values using StoreColors() and not AllocColor(). This scenario was given by David Carver in a previous posting. Note that, as David footnotes, only the server can create a static colormap using AllocAll. Thus if you want to initialize static colormaps being created by clients via their Xlib call to XCreateColormap, you need to use the scenario above. This is because StoreColors will not store the entries since the refcnt would be refcnt==0 in the client case. Also note that you loose some of the bookkeeping advantages when you don't use AllocColor(), but I don't think it matters since the colormap is static. Unlike AllocColor(), the call to StoreColors() will work just as nicely outside pScreen->CreateColormap where the BeingCreated bit is not set. Thus David's call to StoreColors() can be done inside or outside pScreen->CreateColormap(). I however encourage the use of AllocColor() since the same server code can initialize both server and client static colormaps. >> mid = FakeClientID(0); >> CreateColormap(mid,pScr,pVisTrue24,&pCmap,AllocAll,0); * >> StoreColors(pCmap,256,defs) >> >> * The last argument to CreateColormap is the client index, we use 0 to >> indicate that the server is the creator. >> >> -- david carver The final glitch posted was: > What mostly works for ms is filling a xColorItem structure and calling > StoreColors in a loop. Most things work ok unless I ask for colors up > in the high parts of the colormap, then I get core dumps. I am not sure what is meant by "ask for colors". Core dumps when StoreColors is called or later when large value pixels are used? If it is later, then the following explanation may help. Remember if you use StoreColors() and you pass it color defs with pixel values that are too big, pix > pVisual->ColormapEntries , then it will only correctly store to hardware using your ddx pScreen->StoreColors routine the acceptable pixel entries and will throw out the others and return a value of BadValue. Thus check the return value of StoreColors() and check the visual you are using to be sure that the value of pVisual->ColormapEntries is what you expect (want it to be). If it is too small, that may be the problem. Hope this helps. Paul Shearer M.S. 61-277 Tektronix, Inc. P.O. Box 1000 Wilsonville, OR 97070-1000 W (503) 685-2137 H (503) 224-3536 tektronix!shark!paulsh