home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume3 / xcmap / part01 next >
Encoding:
Text File  |  1989-02-02  |  13.4 KB  |  529 lines

  1. Path: uunet!wyse!mikew
  2. From: mikew@wyse.wyse.com (Mike Wexler)
  3. Newsgroups: comp.sources.x
  4. Subject: v03i008:  display the default colormap, Part01/01
  5. Message-ID: <2031@wyse.wyse.com>
  6. Date: 3 Feb 89 01:21:46 GMT
  7. Organization: Wyse Technology, San Jose
  8. Lines: 518
  9. Approved: mikew@wyse.com
  10.  
  11. Submitted-by: bradley@scotty.dccs.upenn.edu (John Bradley)
  12. Posting-number: Volume 3, Issue 8
  13. Archive-name: xcmap/part01
  14.  
  15.  
  16.  
  17. xcmap is a program that displays the contents of the default colormap on 
  18. 4-, 6-, and 8-bit X11 displays.  It displays the colormap both as a grid of
  19. colored rectangles, and as RGB components.
  20.  
  21. This is a very useful thing to anybody who's trying to do color-intensive
  22. programs (such as displaying GIF pictures...) on X.
  23.  
  24. It's also kind of neat to watch.
  25.  
  26. John Bradley  -  bradley@cis.upenn.edu
  27.  
  28. -------------------------(cut here)--------------------------------
  29. #!/bin/sh
  30. # to extract, remove the header and type "sh filename"
  31. if `test ! -d ./xcmap`
  32. then
  33.   mkdir ./xcmap
  34.   echo "mkdir ./xcmap"
  35. fi
  36. if `test ! -s ./xcmap/README`
  37. then
  38. echo "writing ./xcmap/README"
  39. cat > ./xcmap/README << '\Rogue\Monster\'
  40. xcmap is a program that displays the contents of the default colormap on 
  41. 4-, 6-, and 8-bit X11 displays.  It displays the colormap both as a grid of
  42. colored rectangles, and as RGB components.
  43. \Rogue\Monster\
  44. else
  45.   echo "will not over write ./xcmap/README"
  46. fi
  47. if `test ! -s ./xcmap/xcmap.man`
  48. then
  49. echo "writing ./xcmap/xcmap.man"
  50. cat > ./xcmap/xcmap.man << '\Rogue\Monster\'
  51. .TH xcmap 1X
  52. .SH NAME
  53. xcmap \- displays the default colormap on X11 displays
  54. .SH SYNTAX
  55. \fBxcmap\fP [ [-d] \fIdisplay\fP] [ [-g] \fIgeometry\fP]
  56. .SH DESCRIPTION
  57. \fBxcmap\fP is an X11 program that displays the contents of the colormap
  58. on 4-, 6-, and 8-bit color (or greyscale) displays.  It displays a grid 
  59. of squares, (4x4, 8x8, or 16x16 grid, depending on the number of planes)
  60. that correspond to entries in the colormap.  The squares are (of course)
  61. drawn in their corresponding color.
  62. .PP
  63. You may click (with the left button) on any of these squares.  Doing so
  64. will display the pixel number corresponding to that square, and its red,
  65. green, and blue components (as 4-digit hex numbers).  It will continue to do
  66. this as long as you hold the button down.
  67. .PP
  68. Note:  This program points out a bug in the X11R2 server for the IBM RT
  69. Megapel display.  Essentially, the problem is a discrepancy between what the 
  70. server THINKS the colormap is, and what the colormap in the hardware 
  71. ACTUALLY is.
  72. .PP
  73. .SH AUTHOR
  74. John Bradley  -  bradley@cis.upenn.edu
  75. \Rogue\Monster\
  76. else
  77.   echo "will not over write ./xcmap/xcmap.man"
  78. fi
  79. if `test ! -s ./xcmap/Makefile`
  80. then
  81. echo "writing ./xcmap/Makefile"
  82. cat > ./xcmap/Makefile << '\Rogue\Monster\'
  83. XLIB = -lX11
  84. CFLAGS = -O
  85.  
  86. OBJS = xcmap.o
  87.  
  88. all: xcmap
  89.  
  90. xcmap: $(OBJS)
  91.     cc $(CFLAGS) -o xcmap $(OBJS) $(XLIB) $(CLIBS)
  92.  
  93. clean:
  94.     rm -f $(OBJS)
  95.  
  96.  
  97. \Rogue\Monster\
  98. else
  99.   echo "will not over write ./xcmap/Makefile"
  100. fi
  101. if `test ! -s ./xcmap/xcmap.c`
  102. then
  103. echo "writing ./xcmap/xcmap.c"
  104. cat > ./xcmap/xcmap.c << '\Rogue\Monster\'
  105. /*
  106.  * xcmap.c - shows the contents of the colormap on 4, 6, or 8-bit X11 displays
  107.  *
  108.  *  Author:    John Bradley, University of Pennsylvania
  109.  *                (bradley@cis.upenn.edu)
  110.  */
  111.  
  112. #define REVDATE   "Rev: 2/1/89"
  113.  
  114. /* include files */
  115. #include <stdio.h>
  116. #include <strings.h>
  117. #include <ctype.h>
  118.  
  119. #include <X11/Xos.h>
  120. #include <X11/Xlib.h>
  121. #include <X11/Xutil.h>
  122. #include <X11/cursorfont.h>
  123.  
  124. typedef unsigned char byte;
  125.  
  126. /* text centering macros for X11 */
  127. #define CENTERX(f,x,str) ((x)-XTextWidth(f,str,strlen(str))/2)
  128. #define CENTERY(f,y) ((y)-((f->ascent+f->descent)/2)+f->ascent)
  129.  
  130. #define FONT "8x13"
  131.  
  132. /* X stuff */
  133. Display       *theDisp;
  134. int           theScreen, dispcells;
  135. Colormap      theCmap;
  136. Window        rootW, mainW;
  137. GC            theGC;
  138. unsigned long fcol,bcol;
  139. Font          mfont;
  140. XFontStruct   *mfinfo;
  141. Visual        *theVisual;
  142.  
  143.  
  144. /* global vars */
  145. int            WIDE,HIGH,cWIDE,cHIGH,nxcells,nycells, pvalup;
  146. XColor         defs[256];
  147. char          *cmd, tmpstr[128];
  148.  
  149.  
  150.  
  151. /*******************************************/
  152. main(argc, argv)
  153.     int   argc;
  154.     char *argv[];
  155. /*******************************************/
  156. {
  157.     int        i;
  158.     char      *display, *geom;
  159.     XEvent     event;
  160.  
  161.     cmd = argv[0];
  162.     display = geom = NULL;
  163.  
  164.  
  165.     /*********************Options*********************/
  166.  
  167.     for (i = 1; i < argc; i++) {
  168.         char *strind;
  169.  
  170.         if (!strncmp(argv[i],"-g",2)) {        /* geometry */
  171.             i++;
  172.             geom = argv[i];
  173.             continue;
  174.             }
  175.  
  176.         if (argv[i][0] == '=') {        /* old-style geometry */
  177.             geom = argv[i];
  178.             continue;
  179.             }
  180.  
  181.         if (!strncmp(argv[i],"-d",2)) {        /* display */
  182.             i++;
  183.             display = argv[i];
  184.             continue;
  185.             }
  186.  
  187.         strind = index(argv[i], ':');        /* old-style display */
  188.         if(strind != NULL) {
  189.             display = argv[i];
  190.             continue;
  191.             }
  192.  
  193.         Syntax(cmd);
  194.     }
  195.  
  196.  
  197.     /*****************************************************/
  198.  
  199.     /* Open up the display. */
  200.  
  201.     if ( (theDisp=XOpenDisplay(display)) == NULL)
  202.         FatalError("can't open display");
  203.  
  204.     theScreen = DefaultScreen(theDisp);
  205.     theCmap   = DefaultColormap(theDisp, theScreen);
  206.     rootW     = RootWindow(theDisp,theScreen);
  207.     theGC     = DefaultGC(theDisp,theScreen);
  208.     fcol      = WhitePixel(theDisp,theScreen);
  209.     bcol      = BlackPixel(theDisp,theScreen);
  210.     theVisual = DefaultVisual(theDisp,theScreen);
  211.  
  212.     dispcells = DisplayCells(theDisp, theScreen);
  213.     if (dispcells!=16 && dispcells!=64 && dispcells != 256) {
  214.         sprintf(tmpstr,"dispcells = %d.  This program can only deal with 4, 6, and 8-bit displays.",dispcells);
  215.         FatalError(tmpstr);
  216.         }
  217.  
  218.     switch (dispcells) {
  219.     case  16:  nxcells = nycells =  4;  break;
  220.     case  64:  nxcells = nycells =  8;  break;
  221.     case 256:  nxcells = nycells = 16;  break;
  222.         }
  223.     
  224.  
  225.     /**************** Create/Open X Resources ***************/
  226.     if ((mfinfo = XLoadQueryFont(theDisp,FONT))==NULL) {
  227.        sprintf(tmpstr,"couldn't open '%s' font",FONT);
  228.        FatalError(tmpstr);
  229.        }
  230.  
  231.     mfont=mfinfo->fid;
  232.     XSetFont(theDisp,theGC,mfont);
  233.     XSetForeground(theDisp,theGC,fcol);
  234.     XSetBackground(theDisp,theGC,bcol);
  235.  
  236.     CreateMainWindow(cmd,geom,argc,argv);
  237.     Resize(WIDE,HIGH);
  238.  
  239.     XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask 
  240.                                | StructureNotifyMask | ButtonPressMask);
  241.     XMapWindow(theDisp,mainW);
  242.  
  243.     /**************** Main loop *****************/
  244.     while (1) {
  245.         XNextEvent(theDisp, &event);
  246.         HandleEvent(&event);
  247.         }
  248. }
  249.  
  250.  
  251.  
  252. /****************/
  253. HandleEvent(event)
  254.     XEvent *event;
  255. /****************/
  256. {
  257.     switch (event->type) {
  258.         case Expose: {
  259.             XExposeEvent *exp_event = (XExposeEvent *) event;
  260.  
  261.             if (exp_event->window==mainW) 
  262.                 DrawWindow(exp_event->x,exp_event->y,
  263.                            exp_event->width, exp_event->height);
  264.             }
  265.             break;
  266.  
  267.         case ButtonPress: {
  268.             XButtonEvent *but_event = (XButtonEvent *) event;
  269.  
  270.             if (but_event->window == mainW && but_event->button == Button1) 
  271.                 TrackMouse(but_event->x, but_event->y);
  272.             }
  273.             break;
  274.  
  275.         case KeyPress: {
  276.             XKeyEvent *key_event = (XKeyEvent *) event;
  277.             KeySym ks;
  278.             XComposeStatus status;
  279.  
  280.             XLookupString(key_event,tmpstr,128,&ks,&status);
  281.             if (tmpstr[0]=='q' || tmpstr[0]=='Q') Quit();
  282.             }
  283.             break;
  284.  
  285.         case ConfigureNotify: {
  286.             XConfigureEvent *conf_event = (XConfigureEvent *) event;
  287.  
  288.             if (conf_event->window == mainW && 
  289.                  (conf_event->width != WIDE || conf_event->height != HIGH))
  290.                 Resize(conf_event->width, conf_event->height);
  291.             }
  292.             break;
  293.  
  294.  
  295.         case CirculateNotify:
  296.         case MapNotify:
  297.         case DestroyNotify:
  298.         case GravityNotify:
  299.         case ReparentNotify:
  300.         case UnmapNotify:       break;
  301.  
  302.         default:
  303.             printf("event type=%ld\n",event->type); 
  304.             FatalError("Unexpected X_Event");
  305.  
  306.         }  /* end of switch */
  307. }
  308.  
  309.  
  310. /***********************************/
  311. Syntax()
  312. {
  313.     printf("Usage: %s filename [=geometry | -geometry geom] [ [-display] display]\n",cmd);
  314.     exit(1);
  315. }
  316.  
  317.  
  318. /***********************************/
  319. FatalError (identifier)
  320.        char *identifier;
  321. {
  322.     fprintf(stderr, "%s: %s\n",cmd, identifier);
  323.     exit(-1);
  324. }
  325.  
  326.  
  327. /***********************************/
  328. Quit()
  329. {
  330.     exit(0);
  331. }
  332.  
  333.  
  334. /***********************************/
  335. CreateMainWindow(name,geom,argc,argv)
  336.     char *name,*geom,**argv;
  337.     int   argc;
  338. {
  339.     XSetWindowAttributes xswa;
  340.     unsigned int xswamask;
  341.     XSizeHints hints;
  342.     int i,x,y,w,h;
  343.  
  344.     WIDE = HIGH = 256;            /* default window size */
  345.  
  346.     x=y=w=h=1;
  347.     i=XParseGeometry(geom,&x,&y,&w,&h);
  348.     if (i&WidthValue)  WIDE = w;
  349.     if (i&HeightValue) HIGH = h;
  350.  
  351.     if (i&XValue || i&YValue) hints.flags = USPosition;  
  352.                          else hints.flags = PPosition;
  353.  
  354.     hints.flags |= USSize;
  355.  
  356.     if (i&XValue && i&XNegative) 
  357.         x = XDisplayWidth(theDisp,theScreen)-WIDE-abs(x);
  358.     if (i&YValue && i&YNegative) 
  359.         y = XDisplayHeight(theDisp,theScreen)-HIGH-abs(y);
  360.  
  361.     hints.x=x;             hints.y=y;
  362.     hints.width  = WIDE;   hints.height = HIGH;
  363.     hints.max_width  = DisplayWidth(theDisp,theScreen);
  364.     hints.max_height = DisplayHeight(theDisp,theScreen);
  365.     hints.min_width  = 16;
  366.     hints.min_height = 16;
  367.     hints.width_inc = hints.height_inc = 16;
  368.     hints.flags |= PMaxSize | PMinSize | PResizeInc;
  369.  
  370.     xswa.background_pixel = bcol;
  371.     xswa.border_pixel     = fcol;
  372.     xswa.cursor = XCreateFontCursor (theDisp, XC_top_left_arrow);
  373.     xswamask = CWBackPixel | CWBorderPixel | CWCursor;
  374.  
  375.     mainW = XCreateWindow(theDisp,rootW,x,y,WIDE,HIGH,2,0,CopyFromParent,
  376.                           CopyFromParent, xswamask, &xswa);
  377.  
  378.     XSetStandardProperties(theDisp,mainW,"xcmap","xcmap",None,
  379.                             argv,argc,&hints);
  380.  
  381.     if (!mainW) FatalError("Can't open main window");
  382.  
  383. }
  384.  
  385.  
  386. /***********************************/
  387. DrawWindow(x,y,w,h)
  388.        int x,y,w,h;
  389. {
  390.     int i,j,x1,y1,x2,y2;
  391.  
  392.     x1 = x / cWIDE;      y1 = y / cHIGH;    /* (x1,y1) (x2,y2): bounding */
  393.     x2 = ((x+w) + cWIDE - 1) / cWIDE;        /*       rect in cell coords */
  394.     y2 = ((y+h) + cHIGH - 1) / cHIGH;
  395.  
  396.     for (i=y1; i<y2; i++) {
  397.         for (j=x1; j<x2; j++) {
  398.             XSetForeground(theDisp,theGC,(unsigned long) (i*nycells+j) );
  399.             XFillRectangle(theDisp,mainW,theGC,j*cWIDE,i*cHIGH,cWIDE,cHIGH);
  400.             }
  401.         }
  402. }
  403.  
  404.  
  405. /***********************************/
  406. Resize(w,h)
  407. int w,h;
  408. {
  409.     cWIDE = (w + nxcells - 1) / nxcells;
  410.     cHIGH = (h + nycells - 1) / nycells;
  411.     WIDE = w;  HIGH = h;
  412. }
  413.                 
  414.  
  415. /***********************************/
  416. TrackMouse(mx,my)
  417.        int mx,my;
  418. {
  419.     /* called when there's a button press in the window.  draws the pixel
  420.        value, and loops until button is released */
  421.  
  422.     Window        rootW,childW;
  423.     int           rx,ry,x,y;
  424.     unsigned int  mask;
  425.  
  426.     pvalup = 0;
  427.     DrawPixValue(mx,my);
  428.  
  429.     while (1) {
  430.         if (XQueryPointer(theDisp,mainW,&rootW,&childW,&rx,&ry,&x,&y,&mask)) {
  431.             if (!(mask & Button1Mask)) break;    /* button released */
  432.             
  433.             DrawPixValue(x,y);
  434.             }
  435.         }
  436. }
  437.  
  438.                     
  439. /***********************************/
  440. DrawPixValue(x,y)
  441.          int x,y;
  442. {
  443.     static unsigned long pix, lastpix;
  444.     static int           pvaly;
  445.  
  446.     if (!pvalup) {    /* it's not up.  make it so */
  447.         if (y >= HIGH/2) pvaly = 0;  else pvaly = HIGH - 12;
  448.         pvalup = 1;
  449.         lastpix = 0xffff;        /* kludge to force redraw on first */
  450.     XClearArea(theDisp,mainW,0,pvaly,WIDE,13,True);
  451.         }
  452.  
  453.     x /= cWIDE;  y /= cHIGH;
  454.  
  455.     pix = y * nxcells + x;
  456.  
  457.     if (pix != lastpix) {
  458.         XColor def;
  459.         char  *sp;
  460.  
  461.     XSetForeground(theDisp,theGC,fcol);
  462.         lastpix = def.pixel = pix;
  463.         XQueryColor(theDisp, theCmap, &def);
  464.         sprintf(tmpstr, "Pix %3ld = ($%04x, $%04x, $%04x)",
  465.                          pix, def.red, def.green, def.blue);
  466.  
  467.         /* make the hex uppercase */        
  468.         for (sp=tmpstr+4; *sp; sp++) 
  469.             if (islower(*sp)) *sp = toupper(*sp);
  470.  
  471.         XDrawImageString(theDisp,mainW,theGC,5,pvaly+10,tmpstr,strlen(tmpstr));
  472.         }
  473. }
  474.  
  475. \Rogue\Monster\
  476. else
  477.   echo "will not over write ./xcmap/xcmap.c"
  478. fi
  479. if `test ! -s ./xcmap/patchlevel.h`
  480. then
  481. echo "writing ./xcmap/patchlevel.h"
  482. cat > ./xcmap/patchlevel.h << '\Rogue\Monster\'
  483. #define PATCHLEVEL 0
  484. \Rogue\Monster\
  485. else
  486.   echo "will not over write ./xcmap/patchlevel.h"
  487. fi
  488. if `test ! -s ./xcmap/AUTHOR`
  489. then
  490. echo "writing ./xcmap/AUTHOR"
  491. cat > ./xcmap/AUTHOR << '\Rogue\Monster\'
  492. Written by John Bradley (bradley@cis.upenn.edu), one of the fine folks at 
  493. the University of Pennsylvania.
  494.  
  495. Do whatever you want with this program, though it *would* be nice if my name
  496. remained on it somewhere...  Other than that, it may be freely modified,
  497. distributed, and used to fill up disk space.
  498.  
  499. --jhb
  500. \Rogue\Monster\
  501. else
  502.   echo "will not over write ./xcmap/AUTHOR"
  503. fi
  504. if `test ! -s ./xcmap/Imakefile`
  505. then
  506. echo "writing ./xcmap/Imakefile"
  507. cat > ./xcmap/Imakefile << '\Rogue\Monster\'
  508. LOCAL_LIBRARIES = $(XLIB)
  509.  
  510. OBJS = \
  511.         xcmap.o
  512.  
  513. SRCS = \
  514.         xcmap.c
  515.  
  516. ComplexProgramTarget(xcmap)
  517.  
  518. \Rogue\Monster\
  519. else
  520.   echo "will not over write ./xcmap/Imakefile"
  521. fi
  522. echo "Finished archive 1 of 1"
  523. exit
  524.  
  525.  
  526. -- 
  527. Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
  528. Moderator of comp.sources.x
  529.