Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2002:
[Freeciv-Dev] (PR#2484) Xaw client colour allocation patch
Home

[Freeciv-Dev] (PR#2484) Xaw client colour allocation patch

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] (PR#2484) Xaw client colour allocation patch
From: "Vasco Alexandre Da Silva Costa via RT" <rt@xxxxxxxxxxxxxx>
Date: Tue, 3 Dec 2002 15:17:33 -0800
Reply-to: rt@xxxxxxxxxxxxxx


Hello,

This patch moves some colour allocation code used for PNG loading in
graphics.c to colors.c. It also replaces the old colour allocation code.
As a bonus this code should allow the Xaw client to run on grayscale and
monochrome displays. This will require removing get_visual().
It should also now startup on 16 colour displays.
One thing it does differently is it no longer tries to use a private
colormap on pseudo-color displays when it runs out of entries in the
colormap. But I always found that very annoying.

---
Vasco Alexandre da Silva Costa @ Instituto Superior Tecnico, Lisboa

--- client/gui-xaw/colors.c     14 Nov 2002 09:15:00 -0000      1.12
+++ client/gui-xaw/colors.c     3 Dec 2002 23:05:46 -0000
@@ -21,11 +21,13 @@
 #include <X11/Xutil.h>
 #include <X11/Xos.h>
 
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #include "fcintl.h"
 #include "log.h"
+#include "mem.h"
 
 #include "gui_main.h"
 
@@ -76,6 +78,7 @@
 /*************************************************************
 ...
 *************************************************************/
+#ifdef UNUSED
 void color_error(void)
 {
   static int using_private_cmap;
@@ -91,31 +94,28 @@
     XtVaSetValues(toplevel, XtNcolormap, cmap, NULL);
     using_private_cmap=1;
   }
-  
 }
-
+#endif
 
 /*************************************************************
 ...
 *************************************************************/
 static void alloc_standard_colors(void)
 {
+  XColor mycolors[COLOR_STD_LAST];
   int i;
 
   for(i=0; i<COLOR_STD_LAST; i++) {
-    XColor mycolor;
+    mycolors[i].red = colors_standard_rgb[i].r<<8;
+    mycolors[i].green = colors_standard_rgb[i].g<<8;
+    mycolors[i].blue =  colors_standard_rgb[i].b<<8;
+  }
 
-    mycolor.red=colors_standard_rgb[i].r<<8;
-    mycolor.green=colors_standard_rgb[i].g<<8;
-    mycolor.blue=colors_standard_rgb[i].b<<8;
-    
-    if(XAllocColor(display, cmap, &mycolor))
-      colors_standard[i]=mycolor.pixel;
-    else
-      color_error();
-  
+  alloc_colors(mycolors, COLOR_STD_LAST);  
+
+  for(i=0; i<COLOR_STD_LAST; i++) {
+    colors_standard[i] = mycolors[i].pixel;
   }
-  
 }
 
 /*************************************************************
@@ -184,7 +184,7 @@
 *************************************************************/
 void init_color_system(void)
 {
-  cmap=DefaultColormap(display, screen_number);
+  cmap = DefaultColormap(display, screen_number);
 
   alloc_standard_colors();
 }
@@ -192,7 +192,63 @@
 /*************************************************************
 ...
 *************************************************************/
+void alloc_colors(XColor *colors, int ncols)
+{
+  int i;
+
+  for (i = 0; i < ncols; i++) {
+    if (!XAllocColor(display, cmap, &colors[i])) {
+      /* We're out of colors.  For the rest of the palette, just
+         find the closest match and use it. */
+      XColor *cells;
+      int ncells, j;
+
+      ncells = DisplayCells(display, screen_number);
+      cells = fc_malloc(sizeof(XColor) * ncells);
+
+      for (j = 0; j < ncells; j++) {
+        cells[j].pixel = j;
+      }
+
+      XGrabServer(display);
+
+      XQueryColors(display, cmap, cells, ncells);
+
+      for (; i < ncols; i++) {
+        int best = INT_MAX;
+        unsigned long pixel=0;
+
+        for (j = 0; j < ncells; j++) {
+          int rd, gd, bd, dist;
+          
+          rd = (cells[j].red - colors[i].red) >> 8;
+          gd = (cells[j].green - colors[i].green) >> 8;
+          bd = (cells[j].blue - colors[i].blue) >> 8;
+          dist = rd * rd + gd * gd + bd * bd;
+          
+          if (dist < best) {
+            best = dist;
+            pixel = j;
+          }
+        }
+
+       XAllocColor(display, cmap, &cells[pixel]);
+        colors[i].pixel = pixel;
+      }
+
+      XUngrabServer(display);
+      free(cells);
+      break;
+    }
+  }
+}
+
+/*************************************************************
+...
+*************************************************************/
 void free_colors(unsigned long *pixels, int ncols)
 {
+/*
   XFreeColors(display, cmap, pixels, ncols, 0);
+*/
 }
--- client/gui-xaw/colors.h     15 Jun 2002 16:56:11 -0000      1.6
+++ client/gui-xaw/colors.h     3 Dec 2002 23:05:46 -0000
@@ -19,6 +19,7 @@
 
 #include "colors_g.h"
 
+void alloc_colors(XColor *colors, int ncols);
 void free_colors(unsigned long *pixels, int ncols);
 
 extern unsigned long colors_standard[COLOR_STD_LAST];
--- client/gui-xaw/graphics.c   20 Nov 2002 03:41:21 -0000      1.45
+++ client/gui-xaw/graphics.c   3 Dec 2002 23:05:47 -0000
@@ -380,62 +380,25 @@
 
   if (png_get_PLTE(pngp, infop, &palette, &npalette)) {
     int i;
+    XColor *mycolors;
 
     pcolorarray = fc_malloc(npalette * sizeof(*pcolorarray));
 
+    mycolors = fc_malloc(npalette * sizeof(*mycolors));
+
     for (i = 0; i < npalette; i++) {
-      XColor mycolor;
+      mycolors[i].red  = palette[i].red << 8;
+      mycolors[i].green = palette[i].green << 8;
+      mycolors[i].blue = palette[i].blue << 8;
+    }
 
-      mycolor.red  = palette[i].red << 8;
-      mycolor.green = palette[i].green << 8;
-      mycolor.blue = palette[i].blue << 8;
-
-      if (XAllocColor(display, cmap, &mycolor)) {
-       pcolorarray[i] = mycolor.pixel;
-      } else {
-       /* We're out of colors.  For the rest of the palette, just
-          find the closes match and use it. */
-       XColor *cols;
-       int ncols, j;
-
-       ncols = DefaultVisual(display, screen_number)->map_entries;
-       cols = fc_malloc(sizeof(XColor) * ncols);
-
-       for (j = 0; j < ncols; j++) {
-         cols[j].pixel = j;
-       }
-
-       XGrabServer(display);
-
-       XQueryColors(display, cmap, cols, ncols);
-
-       for (; i < npalette; i++) {
-         int best = INT_MAX;
-         unsigned long pixel=0;
-
-         for (j = 0; j < ncols; j++) {
-           int rd, gd, bd, dist;
-           
-           rd = (cols[j].red  >> 8) - palette[i].red;
-           gd = (cols[j].green >> 8) - palette[i].green;
-           bd = (cols[j].blue >> 8) - palette[i].blue;
-           dist = rd * rd + gd * gd + bd * bd;
-           
-           if (dist < best) {
-             best = dist;
-             pixel = j;
-           }
-         }
-
-         XAllocColor(display, cmap, &cols[pixel]);
-         pcolorarray[i] = pixel;
-       }
-
-       XUngrabServer(display);
-       free(cols);
-       break;
-      }
+    alloc_colors(mycolors, npalette);
+
+    for (i = 0; i < npalette; i++) {
+      pcolorarray[i] = mycolors[i].pixel;
     }
+
+    free(mycolors);
   } else {
     freelog(LOG_FATAL, _("PNG file has no palette: %s"), filename);
     exit(EXIT_FAILURE);
@@ -532,7 +495,7 @@
   if (s->has_mask) {
     XFreePixmap(display, s->mask);
   }
-  XFreeColors(display, cmap, s->pcolorarray, s->ncols, 0);
+  free_colors(s->pcolorarray, s->ncols);
   free(s->pcolorarray);
   free(s);
 }

[Prev in Thread] Current Thread [Next in Thread]