mikew@wyse.wyse.com (Mike Wexler) (02/09/89)
Submitted-by: bradley@dsl.cis.upenn.edu (John Bradley) Posting-number: Volume 3, Issue 11 Archive-name: xcmap/patch1 This corrects two bugs in xcmap. The first bug had to do with X Servers that didn't return a power of 2 on the function "XDisplayCells()". The program wouldn't run on them. The second bug occurred when you dragged the mouse outside of the window. It would return out-of-value pixels, and eventually crash. diff -c xcmap/README xcmapnew/README *** xcmap/README Wed Feb 8 17:25:35 1989 --- xcmapnew/README Wed Feb 8 17:10:10 1989 *************** *** 1,3 **** --- 1,47 ---- xcmap is a program that displays the contents of the default colormap on 4-, 6-, and 8-bit X11 displays. It displays the colormap both as a grid of colored rectangles, and as RGB components. + + This is a very useful thing to anybody who's trying to do color-intensive + programs (such as displaying GIF pictures...) on X. + + It's also kind of neat to watch. + + John Bradley - bradley@cis.upenn.edu + + + PATCH 1: + Contributed by Dave Gorgen / Apollo Computer Inc (dpg@citi.umich.edu) + Allows xcmap to run on X servers that pre-allocate colors for the cursor, + returning an "XDisplayCells()" value != a power of 2. This would include + Apollos, DEC QDSSs, and no doubt some other machines. + + ------------- + (The full description of the problem, from Dave's letter...) + I was happy to see xcmap posted on comp.sources.x; it's one of those + programs I always meant to write but never got around to. + + However, when I ran it on my Apollo server I got: + + xcmap: dispcells = 254. This program can only deal with 4, 6, and 8-bit display + s. + + The problem is that xcmap, like many color X clients, incorrectly assumes + that if a visual is n bits deep, it must support exactly 2**n colormap entries. + The protocol explicitly allows fewer entries; this fact is used by several X + servers (Apollo color servers, DEC QDSS servers, and perhaps others) to reserve + 2 slots for the cursor colors. Unless the display hardware has a 2-color cursor + sprite, this is the only correct way to do a color cursor that I know of. + + (The Sun color cursor support on the MIT tape, which allocates the cursor + colors dynamically out of the default color map, is acknowledged by the author(s + ) + to be wrong. I don't know how IBM, HP or MacII color displays do cursors.) + + Anyway, I modified xcmap to accept any value it finds for dispcells <= 256. + It will draw the same square array of pixels, including the out-of-bounds ones, + but if you select an out-of-bounds pixel to display its RGB values, it will + just say that the pixel is out-of-bounds. For what it's worth, this also allows + xcmap to run on monochrome displays, albeit rather boringly. + ------------------ + diff -c xcmap/patchlevel.h xcmapnew/patchlevel.h *** xcmap/patchlevel.h Wed Feb 8 17:25:38 1989 --- xcmapnew/patchlevel.h Wed Feb 8 17:02:59 1989 *************** *** 1 **** ! #define PATCHLEVEL 0 --- 1 ---- ! #define PATCHLEVEL 1 diff -c xcmap/xcmap.c xcmapnew/xcmap.c *** xcmap/xcmap.c Wed Feb 8 17:25:38 1989 --- xcmapnew/xcmap.c Wed Feb 8 17:15:12 1989 *************** *** 106,123 **** theVisual = DefaultVisual(theDisp,theScreen); dispcells = DisplayCells(theDisp, theScreen); ! if (dispcells!=16 && dispcells!=64 && dispcells != 256) { ! sprintf(tmpstr,"dispcells = %d. This program can only deal with 4, 6, and 8-bit displays.",dispcells); FatalError(tmpstr); } - switch (dispcells) { - case 16: nxcells = nycells = 4; break; - case 64: nxcells = nycells = 8; break; - case 256: nxcells = nycells = 16; break; - } - - /**************** Create/Open X Resources ***************/ if ((mfinfo = XLoadQueryFont(theDisp,FONT))==NULL) { sprintf(tmpstr,"couldn't open '%s' font",FONT); --- 106,125 ---- theVisual = DefaultVisual(theDisp,theScreen); dispcells = DisplayCells(theDisp, theScreen); ! ! if (dispcells>256) { ! sprintf(tmpstr,"dispcells = %d. This program can only deal with <= 8-bit displays.",dispcells); FatalError(tmpstr); } + else if (dispcells>64) + nxcells = nycells = 16; + else if (dispcells>16) + nxcells = nycells = 8; + else if (dispcells>4) + nxcells = nycells = 4; + else + nxcells = nycells = 2; /**************** Create/Open X Resources ***************/ if ((mfinfo = XLoadQueryFont(theDisp,FONT))==NULL) { sprintf(tmpstr,"couldn't open '%s' font",FONT); *************** *** 339,344 **** --- 341,349 ---- static unsigned long pix, lastpix; static int pvaly; + if (x<0) x=0; if (x>=WIDE) x=WIDE-1; + if (y<0) y=0; if (y>=HIGH) y=HIGH-1; + if (!pvalup) { /* it's not up. make it so */ if (y >= HIGH/2) pvaly = 0; else pvaly = HIGH - 12; pvalup = 1; *************** *** 356,368 **** XSetForeground(theDisp,theGC,fcol); lastpix = def.pixel = pix; ! XQueryColor(theDisp, theCmap, &def); ! sprintf(tmpstr, "Pix %3ld = ($%04x, $%04x, $%04x)", ! pix, def.red, def.green, def.blue); ! /* make the hex uppercase */ ! for (sp=tmpstr+4; *sp; sp++) ! if (islower(*sp)) *sp = toupper(*sp); XDrawImageString(theDisp,mainW,theGC,5,pvaly+10,tmpstr,strlen(tmpstr)); } --- 361,378 ---- XSetForeground(theDisp,theGC,fcol); lastpix = def.pixel = pix; ! if (pix<dispcells) { ! XQueryColor(theDisp, theCmap, &def); ! sprintf(tmpstr, "Pix %3ld = ($%04x, $%04x, $%04x)", ! pix, def.red, def.green, def.blue); ! /* make the hex uppercase */ ! for (sp=tmpstr+4; *sp; sp++) ! if (islower(*sp)) *sp = toupper(*sp); ! } ! else { ! sprintf(tmpstr, "Pix %3ld is out of legal range. ", pix); ! } XDrawImageString(theDisp,mainW,theGC,5,pvaly+10,tmpstr,strlen(tmpstr)); } -- Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330 Moderator of comp.sources.x