[comp.sources.x] v03i011: display the default colormap, Patch1

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