rnd-19980906
authorHolger Schemel <info@artsoft.org>
Sun, 6 Sep 1998 18:55:48 +0000 (20:55 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:30:33 +0000 (10:30 +0200)
src/Makefile
src/events.c
src/gifload.c
src/gifload.h
src/init.c
src/main.c
src/main.h
src/screens.c
src/send.c
src/xli.h

index 4edb193..cd1c80e 100644 (file)
@@ -21,7 +21,7 @@ SCORE_ENTRIES = -DMANY_PER_NAME               # many score entries per name
 # If you use the Xpm library, convert the GIF files to Xpm
 # files (and the mask files ('*Maske.gif') to xbm files).
 
-XPM_INCLUDE_FILE = -DXPM_INCLUDE_FILE="<X11/xpm.h>"
+XPM_INCLUDE_FILE = -DXPM_INCLUDE_FILE="<X11/xpm.h>"
 
 CONFIG = $(GAME_DIR) $(SOUNDS) $(JOYSTICK)     \
         $(SCORE_ENTRIES) $(XPM_INCLUDE_FILE)
@@ -39,8 +39,8 @@ DEBUG = -DDEBUG -g -Wall
 # LIBS = -L/usr/local/X11/lib -lXpm -lX11 -lm -lsocket -R/usr/local/X11/lib
 #                                      # for SunOS and others
 
-LIBS = -L/usr/X11R6/lib -lXpm -lX11 -lm
-LIBS = -L/usr/X11R6/lib -lX11 -lm
+LIBS = -L/usr/X11R6/lib -lXpm -lX11 -lm
+LIBS = -L/usr/X11R6/lib -lX11 -lm
 
 # CFLAGS = -O2 $(CONFIG) $(SYSTEM)
 CFLAGS = $(DEBUG) $(CONFIG) $(SYSTEM) $(INCL)
index edce9a9..5f85101 100644 (file)
@@ -612,29 +612,6 @@ void HandleKey(KeySym key, int key_status)
            Delay(1000000);
          }
 
-         break;
-
-       case XK_z:
-         {
-           static int test_picture_pos = 0;
-
-           printf("test picture %d\n", test_picture_pos);
-
-           XCopyArea(display,test_pix[test_picture_pos],window,gc,
-                     0,0, 100,100,
-                     0,0);
-           /*
-           XCopyArea(display,test_clipmask[test_picture_pos],window,gc,
-                     0,0, 100,100,
-                     100,0);
-                     */
-           XFlush(display);
-           XSync(display,FALSE);
-           Delay(1000000);
-
-           test_picture_pos = (test_picture_pos + 1) % test_picture_count;
-         }
-
          break;
 #endif
 
index f26ba5a..fc2fc28 100644 (file)
 
 #include "xli.h"
 
+#ifdef DEBUG
+#define DEBUG_TIMING
+#endif
 
 
-extern Pixmap          test_pix[];
-extern Pixmap          test_clipmask[];
-extern int             test_picture_count;
 
+extern long Counter(void);
 
 
 
-int Read_GIF_to_Pixmaps(Display *display, Window window, char *filename)
+int Read_GIF_to_Pixmaps(Display *display, Window window, char *filename,
+                       Pixmap *pixmap, Pixmap *pixmap_mask)
 {
   Image *image, *image_mask;
   XImageInfo *ximageinfo, *ximageinfo_mask;
-  Pixmap pixmap, pixmap_mask;
   int screen;
   Visual *visual;
   unsigned int depth;
 
+#ifdef DEBUG_TIMING
+  long count1, count2;
+  count1 = Counter();
+#endif
+
   /* load GIF file */
   if (!(image = gifLoad(filename)))
   {
@@ -42,6 +48,13 @@ int Read_GIF_to_Pixmaps(Display *display, Window window, char *filename)
     exit(1);
   }
 
+#ifdef DEBUG_TIMING
+  count2 = Counter();
+  printf("   LOADING '%s' IN %.2f SECONDS\n",
+        filename, (float)(count2-count1)/100.0);
+  count1 = Counter();
+#endif
+
   if (image->depth > 8)
   {
     printf("Sorry, GIFs with more than 256 colors are not supported.\n");
@@ -51,6 +64,13 @@ int Read_GIF_to_Pixmaps(Display *display, Window window, char *filename)
   /* minimize colormap */
   compress(image);
 
+#ifdef DEBUG_TIMING
+  count2 = Counter();
+  printf("   COMPRESSING IMAGE COLORMAP IN %.2f SECONDS\n",
+        (float)(count2-count1)/100.0);
+  count1 = Counter();
+#endif
+
   screen = DefaultScreen(display);
   visual = DefaultVisual(display, screen);
   depth = DefaultDepth(display, screen);
@@ -62,32 +82,40 @@ int Read_GIF_to_Pixmaps(Display *display, Window window, char *filename)
     exit(1);
   }
 
-  if (ximageinfo->cmap != DefaultColormap(display, screen))
-  {
-    /*
-    printf("--> '%s' gets own colormap\n", filename);
-    */
+#ifdef DEBUG_TIMING
+  count2 = Counter();
+  printf("   CONVERTING IMAGE TO XIMAGE IN %.2f SECONDS\n",
+        (float)(count2-count1)/100.0);
+  count1 = Counter();
+#endif
 
+  if (ximageinfo->cmap != DefaultColormap(display, screen))
     XSetWindowColormap(display, window, ximageinfo->cmap);
-  }
 
   /* convert XImage to Pixmap */
-  if ((pixmap = ximageToPixmap(display, window, ximageinfo)) == None)
+  if ((*pixmap = ximageToPixmap(display, window, ximageinfo)) == None)
   {
     fprintf(stderr, "Cannot convert XImage to Pixmap.\n");
     exit(1);
   }
 
-  /*
-  printf("test_picture_count == %d\n", test_picture_count);
-  */
-
-  test_pix[test_picture_count] = pixmap;
-
+#ifdef DEBUG_TIMING
+  count2 = Counter();
+  printf("   CONVERTING IMAGE TO PIXMAP IN %.2f SECONDS\n",
+        (float)(count2-count1)/100.0);
+  count1 = Counter();
+#endif
 
   /* create mono image for masking */
   image_mask = monochrome(image);
 
+#ifdef DEBUG_TIMING
+  count2 = Counter();
+  printf("   CONVERTING IMAGE TO MASK IN %.2f SECONDS\n",
+        (float)(count2-count1)/100.0);
+  count1 = Counter();
+#endif
+
   /* convert internal image structure to X11 XImage */
   if (!(ximageinfo_mask = imageToXImage(display, screen, visual, depth,
                                        image_mask)))
@@ -96,18 +124,26 @@ int Read_GIF_to_Pixmaps(Display *display, Window window, char *filename)
     exit(1);
   }
 
+#ifdef DEBUG_TIMING
+  count2 = Counter();
+  printf("   CONVERTING MASK TO XIMAGE IN %.2f SECONDS\n",
+        (float)(count2-count1)/100.0);
+  count1 = Counter();
+#endif
+
   /* convert XImage to Pixmap */
-  if ((pixmap_mask = ximageToPixmap(display, window, ximageinfo_mask)) == None)
+  if ((*pixmap_mask = ximageToPixmap(display, window, ximageinfo_mask)) == None)
   {
     fprintf(stderr, "Cannot convert XImage to Pixmap.\n");
     exit(1);
   }
 
-
-  test_clipmask[test_picture_count] = pixmap_mask;
-
-  test_picture_count++;
-
+#ifdef DEBUG_TIMING
+  count2 = Counter();
+  printf("   CONVERTING MASK TO PIXMAP IN %.2f SECONDS\n",
+        (float)(count2-count1)/100.0);
+  count1 = Counter();
+#endif
 
   return(GIF_Success);
 }
index ebc260a..967221d 100644 (file)
@@ -29,7 +29,7 @@
 #define GIF_NoMemory           -4
 #define GIF_ColorFailed                -5
 
-int Read_GIF_to_Pixmaps(Display *, Window, char *);
+int Read_GIF_to_Pixmaps(Display *, Window, char *, Pixmap *, Pixmap *);
 #endif
 
 #endif
index ebaeb4b..0262c37 100644 (file)
@@ -25,9 +25,7 @@
 #include <signal.h>
 
 #ifdef DEBUG
-
 #define DEBUG_TIMING
-
 #endif
 
 struct PictureFileInfo
@@ -504,16 +502,11 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
   unsigned int width,height;
   int hot_x,hot_y;
   Pixmap shapemask;
-#ifdef MSDOS
-  char *picture_ext = ".gif";
-#else
   char *picture_ext = ".xpm";
-#endif
   char *picturemask_ext = "Mask.xbm";
 #else
-  int gif_err, ilbm_err;
+  int gif_err;
   char *picture_ext = ".gif";
-  char *picturemask_ext = "Mask.ilbm";
 #endif
 
 #ifdef DEBUG_TIMING
@@ -523,38 +516,13 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
   /* Grafik laden */
   if (pic->picture_filename)
   {
-
-
-
-
-
-    sprintf(basefilename,"%s%s",pic->picture_filename,".gif");
+    sprintf(basefilename,"%s%s",pic->picture_filename,picture_ext);
     DrawInitText(basefilename,150,FC_YELLOW);
     sprintf(filename,"%s/%s",GFX_PATH,basefilename);
 
-#ifdef DEBUG_TIMING
-    count1 = Counter();
-#endif
-
-    Read_GIF_to_Pixmaps(display, window, filename);
-
-#ifdef DEBUG_TIMING
-    count2 = Counter();
-    printf("GIF LOADING %s IN %.2f SECONDS\n",
-          filename,(float)(count2-count1)/100.0);
-#endif
-
-
-
-
-
-
-    sprintf(basefilename,"%s%s",pic->picture_filename,picture_ext);
-    DrawInitText(basefilename,150,FC_YELLOW);
 #ifdef MSDOS
     rest(100);
 #endif MSDOS
-    sprintf(filename,"%s/%s",GFX_PATH,basefilename);
 
 #ifdef DEBUG_TIMING
     count1 = Counter();
@@ -563,18 +531,9 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
 #ifdef XPM_INCLUDE_FILE
 
     xpm_att[pos].valuemask = XpmCloseness;
-    xpm_att[pos].closeness = 65535;
-
-    /*
     xpm_att[pos].closeness = 20000;
-    */
-
-#if 0
     xpm_err = XpmReadFileToPixmap(display,window,filename,
                                  &pix[pos],&shapemask,&xpm_att[pos]);
-#else
-    xpm_err = XpmSuccess;
-#endif
 
     switch(xpm_err)
     {
@@ -598,9 +557,16 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
        break;
     }
 
+#ifdef DEBUG_TIMING
+    count2 = Counter();
+    printf("XPM LOADING %s IN %.2f SECONDS\n",
+          filename,(float)(count2-count1)/100.0);
+#endif
+
 #else 
 
-    gif_err = Read_GIF_to_Pixmap(display,filename,&pix[pos]);
+    gif_err = Read_GIF_to_Pixmaps(display, window, filename,
+                                 &pix[pos], &clipmask[pos]);
 
     switch(gif_err)
     {
@@ -630,57 +596,40 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
        break;
     }
 
-#endif
-
 #ifdef DEBUG_TIMING
     count2 = Counter();
-    /*
-    printf("XPM LOADING %s IN %.2f SECONDS\n",
+    printf("GIF LOADING %s IN %.2f SECONDS\n",
           filename,(float)(count2-count1)/100.0);
-          */
 #endif
 
-#if 0
+#endif
+
     if (!pix[pos])
     {
-      fprintf(stderr, "%s: cannot read graphics file '%s'.\n",
-             progname,filename);
+      fprintf(stderr, "%s: cannot get graphics for '%s'.\n",
+             progname, pic->picture_filename);
       CloseAll();
       exit(-1);
     }
-#endif
-
   }
 
   /* zugehörige Maske laden (wenn vorhanden) */
   if (pic->picture_with_mask)
   {
-#ifdef MSDOS
-    xbm_err = BitmapSuccess;
-    clipmask[pos] = DUMMY_MASK;
-    goto msdos_jmp;
-#else
+
+#ifdef XPM_INCLUDE_FILE
+
     sprintf(basefilename,"%s%s",pic->picture_filename,picturemask_ext);
     DrawInitText(basefilename,150,FC_YELLOW);
     sprintf(filename,"%s/%s",GFX_PATH,basefilename);
-#endif
 
 #ifdef DEBUG_TIMING
     count1 = Counter();
 #endif
 
-#ifdef XPM_INCLUDE_FILE
-
-#if 0
     xbm_err = XReadBitmapFile(display,window,filename,
                              &width,&height,&clipmask[pos],&hot_x,&hot_y);
-#else
-    xbm_err = BitmapSuccess;
-#endif
 
-#ifdef MSDOS
-msdos_jmp:
-#endif
     switch(xbm_err)
     {
       case BitmapSuccess:
@@ -704,58 +653,22 @@ msdos_jmp:
        break;
     }
 
-#else
-
-    ilbm_err = Read_ILBM_to_Bitmap(display,filename,&clipmask[pos]);
-
-    switch(ilbm_err)
-    {
-      case ILBM_Success:
-        break;
-      case ILBM_OpenFailed:
-        fprintf(stderr,"Cannot open ILBM file '%s' !\n",filename);
-       CloseAll();
-       exit(-1);
-      case ILBM_ReadFailed:
-        fprintf(stderr,"Cannot read ILBM file '%s' !\n",filename);
-       CloseAll();
-       exit(-1);
-      case ILBM_FileInvalid:
-       fprintf(stderr,"Invalid ILBM file '%s'!\n",filename);
-       CloseAll();
-       exit(-1);
-      case ILBM_NoMemory:
-       fprintf(stderr,"Not enough memory for ILBM file '%s'!\n",filename);
-       CloseAll();
-       exit(1);
-      default:
-       break;
-    }
-
-#endif
-
 #ifdef DEBUG_TIMING
     count2 = Counter();
-    /*
-    printf("LOADING %s IN %.2f SECONDS\n",
+    printf("XBM LOADING %s IN %.2f SECONDS\n",
           filename,(float)(count2-count1)/100.0);
-          */
 #endif
 
-#if 0
+#endif
+
     if (!clipmask[pos])
     {
-      fprintf(stderr, "%s: cannot read graphics file '%s'.\n",
-             progname,filename);
+      fprintf(stderr, "%s: cannot get clipmask for '%s'.\n",
+             progname, pic->picture_filename);
       CloseAll();
       exit(-1);
     }
-#endif
-
   }
-
-  pix[pos] = test_pix[test_picture_count-1];
-  clipmask[pos] = test_clipmask[test_picture_count-1];
 }
 
 void InitElementProperties()
@@ -1326,8 +1239,12 @@ void CloseAll()
 
   if (gc)
     XFreeGC(display, gc);
+
   if (display)
+  {
+    XAutoRepeatOn(display);
     XCloseDisplay(display);
+  }
 
   exit(0);
 }
index 08ee469..9028fb6 100644 (file)
@@ -30,12 +30,6 @@ GC           gc, clip_gc[NUM_PIXMAPS];
 Pixmap         pix[NUM_PIXMAPS];
 Pixmap         clipmask[NUM_PIXMAPS];
 
-
-Pixmap         test_pix[NUM_PICTURES];
-Pixmap         test_clipmask[NUM_PICTURES];
-int            test_picture_count = 0;
-
-
 #ifdef XPM_INCLUDE_FILE
 XpmAttributes  xpm_att[NUM_PICTURES];
 #endif
index 11a80a8..87db201 100644 (file)
@@ -271,13 +271,6 @@ extern XImage             *image[];
 extern Pixmap          clipmask[];
 extern Pixmap          pix[];
 
-
-extern Pixmap          test_pix[];
-extern Pixmap          test_clipmask[];
-extern int             test_picture_count;
-
-
-
 #ifdef XPM_INCLUDE_FILE
 extern XpmAttributes   xpm_att[];
 #endif
index 90305d7..37c8128 100644 (file)
@@ -666,7 +666,7 @@ void HandleHelpScreen(int button)
   }
   else
   {
-    if (DelayReached(&hs_delay,GAME_FRAME_DELAY))
+    if (DelayReached(&hs_delay,GAME_FRAME_DELAY * 2))
     {
       if (helpscreen_state<num_helpscreen_els_pages)
        DrawHelpScreenElAction(helpscreen_state*MAX_HELPSCREEN_ELS);
index aa55152..56a65dc 100644 (file)
@@ -421,77 +421,45 @@ static unsigned int bitsPerPixelAtDepth(Display *disp, int scrn,
   exit(1);
 }
 
-XImageInfo *imageToXImage(Display *disp,
-                         int scrn,
-                         Visual *visual,
-                         unsigned int ddepth,
-                         Image *image)
+XImageInfo *imageToXImage(Display *disp, int scrn, Visual *visual,
+                         unsigned int ddepth, Image *image)
 {
-  Pixel        *redvalue, *greenvalue, *bluevalue;
-  unsigned int  a, c=0, x, y, linelen, dpixlen, dbits;
-  XColor        xcolor;
-
-  static XColor xcolor_used[NOFLASH_COLORS];
-
-  XGCValues     gcv;
-  XImageInfo   *ximageinfo;
-  Image        *orig_image;
-
-  static Colormap our_default_cmap = 0;
-  static Pixel *our_default_index;
-  static int free_cmap_entries, max_cmap_entries;
-  int use_cmap_entry;
-
-
-  static unsigned long pixel_used[NOFLASH_COLORS];
-
+  static XColor xcolor_private[NOFLASH_COLORS];
+  static int colorcell_used[NOFLASH_COLORS];
+  static Colormap global_cmap = 0;
+  static Pixel *global_cmap_index;
+  static int num_cmap_entries, free_cmap_entries;
+  static private_cmap = FALSE;
+  Pixel *redvalue, *greenvalue, *bluevalue;
+  unsigned int a, c=0, x, y, linelen, dpixlen, dbits;
+  XColor xcolor;
+  XGCValues gcv;
+  XImageInfo *ximageinfo;
 
-  if (!our_default_cmap)
+  if (!global_cmap)
   {
-#if 0
-    our_default_cmap = DefaultColormap(disp, scrn);
-#endif
-
-    our_default_cmap = XCreateColormap(disp, RootWindow(disp, scrn),
-                                      visual, AllocNone);
-    our_default_index = (Pixel *)lmalloc(sizeof(Pixel) * NOFLASH_COLORS);
-
-    for (a=0; a<NOFLASH_COLORS; a++)   /* count entries we got */
-      if (!XAllocColorCells(disp, our_default_cmap, FALSE, NULL, 0,
-                           our_default_index + a, 1))
-       break;
-
-    free_cmap_entries = max_cmap_entries = a;
-
-    printf("We've got %d colormap entries.\n", free_cmap_entries);
-
-    for(a=0; a<max_cmap_entries; a++)  /* copy default colors */
+    if (visual == DefaultVisual(disp, scrn))
+      global_cmap = DefaultColormap(disp, scrn);
+    else
     {
-      xcolor.pixel = *(our_default_index + a);
-      XQueryColor(disp, DefaultColormap(disp, scrn), &xcolor);
-      XStoreColor(disp, our_default_cmap, &xcolor);
-
-      pixel_used[xcolor.pixel] = 0;
-      xcolor_used[xcolor.pixel] = xcolor;
+      global_cmap = XCreateColormap(disp, RootWindow(disp, scrn),
+                                        visual, AllocNone);
+      private_cmap = TRUE;
     }
   }
 
-  xcolor.flags= DoRed | DoGreen | DoBlue;
-  redvalue= greenvalue= bluevalue= NULL;
-  orig_image= image;
-  ximageinfo= (XImageInfo *)lmalloc(sizeof(XImageInfo));
-  ximageinfo->disp= disp;
-  ximageinfo->scrn= scrn;
-  ximageinfo->depth= 0;
-  ximageinfo->drawable= None;
-  ximageinfo->index= NULL;
-  ximageinfo->rootimage= FALSE;        /* assume not */
-  ximageinfo->foreground= ximageinfo->background= 0;
-  ximageinfo->gc= NULL;
-  ximageinfo->ximage= NULL;
-
-  /* do color allocation
-   */
+  xcolor.flags = DoRed | DoGreen | DoBlue;
+  redvalue = greenvalue = bluevalue = NULL;
+  ximageinfo = (XImageInfo *)lmalloc(sizeof(XImageInfo));
+  ximageinfo->disp = disp;
+  ximageinfo->scrn = scrn;
+  ximageinfo->depth = 0;
+  ximageinfo->drawable = None;
+  ximageinfo->index = NULL;
+  ximageinfo->rootimage = FALSE;
+  ximageinfo->foreground = ximageinfo->background= 0;
+  ximageinfo->gc = NULL;
+  ximageinfo->ximage = NULL;
 
   switch (visual->class)
   {
@@ -504,19 +472,11 @@ XImageInfo *imageToXImage(Display *disp,
       unsigned int redbottom, greenbottom, bluebottom;
       unsigned int redtop, greentop, bluetop;
 
-      redvalue= (Pixel *)lmalloc(sizeof(Pixel) * 256);
-      greenvalue= (Pixel *)lmalloc(sizeof(Pixel) * 256);
-      bluevalue= (Pixel *)lmalloc(sizeof(Pixel) * 256);
+      redvalue = (Pixel *)lmalloc(sizeof(Pixel) * 256);
+      greenvalue = (Pixel *)lmalloc(sizeof(Pixel) * 256);
+      bluevalue = (Pixel *)lmalloc(sizeof(Pixel) * 256);
 
-#if 1
-      if (visual == DefaultVisual(disp, scrn))
-       ximageinfo->cmap= DefaultColormap(disp, scrn);
-      else
-       ximageinfo->cmap= XCreateColormap(disp, RootWindow(disp, scrn),
-                                         visual, AllocNone);
-#else
-      ximageinfo->cmap = our_default_cmap;
-#endif
+      ximageinfo->cmap = global_cmap;
 
       retry_direct: /* tag we hit if a DirectColor allocation fails on
                     * default colormap */
@@ -524,8 +484,8 @@ XImageInfo *imageToXImage(Display *disp,
       /* calculate number of distinct colors in each band
        */
 
-      redcolors= greencolors= bluecolors= 1;
-      for (pixval= 1; pixval; pixval <<= 1)
+      redcolors = greencolors = bluecolors = 1;
+      for (pixval=1; pixval; pixval <<= 1)
       {
        if (pixval & visual->red_mask)
          redcolors <<= 1;
@@ -550,19 +510,19 @@ XImageInfo *imageToXImage(Display *disp,
       bluestep = 256 / bluecolors;
       redbottom = greenbottom = bluebottom = 0;
       redtop = greentop = bluetop = 0;
-      for (a= 0; a < visual->map_entries; a++)
+      for (a=0; a<visual->map_entries; a++)
       {
        if (redbottom < 256)
-         redtop= redbottom + redstep;
+         redtop = redbottom + redstep;
        if (greenbottom < 256)
-         greentop= greenbottom + greenstep;
+         greentop = greenbottom + greenstep;
        if (bluebottom < 256)
-         bluetop= bluebottom + bluestep;
+         bluetop = bluebottom + bluestep;
 
-       xcolor.red= (redtop - 1) << 8;
-       xcolor.green= (greentop - 1) << 8;
-       xcolor.blue= (bluetop - 1) << 8;
-       if (! XAllocColor(disp, ximageinfo->cmap, &xcolor))
+       xcolor.red = (redtop - 1) << 8;
+       xcolor.green = (greentop - 1) << 8;
+       xcolor.blue = (bluetop - 1) << 8;
+       if (!XAllocColor(disp, ximageinfo->cmap, &xcolor))
        {
          /* if an allocation fails for a DirectColor default visual then
           * we should create a private colormap and try again.
@@ -571,13 +531,10 @@ XImageInfo *imageToXImage(Display *disp,
          if ((visual->class == DirectColor) &&
              (visual == DefaultVisual(disp, scrn)))
          {
-#if 1
-           ximageinfo->cmap = XCreateColormap(disp, RootWindow(disp, scrn),
-                                              visual, AllocNone);
-#else
-           our_default_cmap = XCopyColormapAndFree(disp, our_default_cmap);
-           ximageinfo->cmap = our_default_cmap;
-#endif
+           global_cmap = XCopyColormapAndFree(disp, global_cmap);
+           ximageinfo->cmap = global_cmap;
+           private_cmap = TRUE;
+
            goto retry_direct;
          }
 
@@ -596,144 +553,136 @@ XImageInfo *imageToXImage(Display *disp,
         */
 
        while ((redbottom < 256) && (redbottom < redtop))
-         redvalue[redbottom++]= xcolor.pixel & visual->red_mask;
+         redvalue[redbottom++] = xcolor.pixel & visual->red_mask;
        while ((greenbottom < 256) && (greenbottom < greentop))
-         greenvalue[greenbottom++]= xcolor.pixel & visual->green_mask;
+         greenvalue[greenbottom++] = xcolor.pixel & visual->green_mask;
        while ((bluebottom < 256) && (bluebottom < bluetop))
-         bluevalue[bluebottom++]= xcolor.pixel & visual->blue_mask;
+         bluevalue[bluebottom++] = xcolor.pixel & visual->blue_mask;
       }
       break;
     }
 
     case PseudoColor:
 
-      ximageinfo->index= (Pixel *)lmalloc(sizeof(Pixel) * (image->rgb.used+NOFLASH_COLORS));
-
-
-      /* get the colormap to use.
-       */
-
-      ximageinfo->cmap = our_default_cmap;
-
-      /* allocate colors shareable (if we can)
-       */
+      ximageinfo->cmap = global_cmap;
+      ximageinfo->index = (Pixel *)lmalloc(sizeof(Pixel) * image->rgb.used);
 
-      for (a = 0; a < image->rgb.used; a++)
+      for (a=0; a<image->rgb.used; a++)
       {
+       XColor xcolor2;
+       unsigned short mask;
+       int color_found;
        int i;
-       XColor xcolor2;
-  
-       xcolor2.flags = DoRed | DoGreen | DoBlue;
   
-       xcolor.red= *(image->rgb.red + a);
-       xcolor.green= *(image->rgb.green + a);
-       xcolor.blue= *(image->rgb.blue + a);
+       xcolor.red = *(image->rgb.red + a);
+       xcolor.green = *(image->rgb.green + a);
+       xcolor.blue = *(image->rgb.blue + a);
   
        /* look if this color already exists in our colormap */
-  
-  #if 0
-       for (i=max_cmap_entries-1; i>=free_cmap_entries; i--)
-  
-  #else
-       for (i=max_cmap_entries-1; i>=0; i--)
-       {
-         /*
-         if (!pixel_used[i])
-           continue;
-           */
-  #endif
-  
-         xcolor2.pixel = *(our_default_index + i);
-  
-  #if 0
-         XQueryColor(disp, ximageinfo->cmap, &xcolor2);
-  #else
-         xcolor2 = xcolor_used[xcolor2.pixel];
-  #endif
-  
-         if ((xcolor.red >> 8) == (xcolor2.red >> 8) &&
-             (xcolor.green >> 8) == (xcolor2.green >> 8) &&
-             (xcolor.blue >> 8) == (xcolor2.blue >> 8))
-           break;
-       }
-  
-       use_cmap_entry = i;
-  
-       if (0 && use_cmap_entry < free_cmap_entries)    /* not found in colormap */
-       {
-         free_cmap_entries--;
-       }
-       else if (0 && use_cmap_entry < free_cmap_entries)       /* not found in colormap */
-       {
-       }
-       else if (use_cmap_entry < 0)    /* not found in colormap */
-       {
-         /* look for an existing 'unused' color near the one we want */
-  
-         for (i=free_cmap_entries-1; i>=0; i--)
-         {
-           int closeness = 14;
-  
-           if (pixel_used[i])
-             continue;
-  
-           xcolor2.pixel = *(our_default_index + i);
-  
-  #if 0
-           XQueryColor(disp, ximageinfo->cmap, &xcolor2);
-  #else
-           xcolor2 = xcolor_used[xcolor2.pixel];
-  #endif
-  
-  
-           if ((xcolor.red >> closeness) == (xcolor2.red >> closeness) &&
-               (xcolor.green >> closeness) == (xcolor2.green >> closeness) &&
-               (xcolor.blue >> closeness) == (xcolor2.blue >> closeness))
-             break;
-         }
-  
-         use_cmap_entry = i;
-  
-         if (use_cmap_entry < 0)               /* no 'near' color found */
-         {
-           /* look for the next free color */
-  
-           while (pixel_used[--free_cmap_entries])
-             ;
-           use_cmap_entry = free_cmap_entries;
-         }
-       }
-  
-       if (free_cmap_entries < 0)
-       {
-         printf("imageToXImage: too many global colors!\n");
-         exit(0);
-       }
-  
-  
-       /*
-         printf("--> eating color %d\n", use_cmap_entry);
-         */
-  
-  
-  
-       xcolor.pixel = use_cmap_entry;
-  
-       xcolor_used[xcolor.pixel] = xcolor;
-  
-       *(ximageinfo->index + a) = xcolor.pixel;
-  
-       XStoreColor(disp, ximageinfo->cmap, &xcolor);
-  
-       pixel_used[use_cmap_entry] = 1;
+       if (!XAllocColor(disp, ximageinfo->cmap, &xcolor))
+       {
+         if (!private_cmap)
+         {
+           /*
+           printf("switching to private colormap...\n");
+           */
+
+           /* we just filled up the default colormap -- get a private one
+              which contains all already allocated colors */
+
+           global_cmap = XCopyColormapAndFree(disp, global_cmap);
+           ximageinfo->cmap = global_cmap;
+           private_cmap = TRUE;
+
+           /* allocate the rest of the color cells read/write */
+           global_cmap_index =
+             (Pixel *)lmalloc(sizeof(Pixel) * NOFLASH_COLORS);
+           for (i=0; i<NOFLASH_COLORS; i++)
+             if (!XAllocColorCells(disp, global_cmap, FALSE, NULL, 0,
+                                   global_cmap_index + i, 1))
+               break;
+           num_cmap_entries = free_cmap_entries = i;
+
+           /*
+           printf("We've got %d free colormap entries.\n", free_cmap_entries);
+           */
+
+           /* to minimize colormap flashing, copy default colors and try
+              to keep them as near as possible to the old values */
+
+           for(i=0; i<num_cmap_entries; i++)
+           {
+             xcolor2.pixel = *(global_cmap_index + i);
+             XQueryColor(disp, DefaultColormap(disp, scrn), &xcolor2);
+             XStoreColor(disp, global_cmap, &xcolor2);
+             xcolor_private[xcolor2.pixel] = xcolor2;
+             colorcell_used[xcolor2.pixel] = FALSE;
+           }
+
+           /* now we have the default colormap private: all colors we
+              successfully allocated so far are read-only, which is okay,
+              because we don't want to change them anymore -- if we need
+              an existing color again, we get it by XAllocColor; all other
+              colors are read/write and we can set them by XStoreColor,
+              but we will try to overwrite those color cells with our new
+              color which are as close as possible to our new color */
+         }
+
+         /* look for an existing default color close the one we want */
+
+         mask = 0xf000;
+         color_found = FALSE;
+
+         while (!color_found)
+         {
+           for (i=num_cmap_entries-1; i>=0; i--)
+           {
+             xcolor2.pixel = *(global_cmap_index + i);
+             xcolor2 = xcolor_private[xcolor2.pixel];
+
+             if (colorcell_used[xcolor2.pixel])
+               continue;
+
+             if ((xcolor.red & mask) == (xcolor2.red & mask) &&
+                 (xcolor.green & mask) == (xcolor2.green & mask) &&
+                 (xcolor.blue & mask) == (xcolor2.blue & mask))
+             {
+               /*
+               printf("replacing color cell %ld with a close color\n",
+                      xcolor2.pixel);
+                      */
+               color_found = TRUE;
+               break;
+             }
+           }
+
+           if (mask == 0x0000)
+             break;
+
+           mask = (mask << 1) & 0xffff;
+         }
+
+         if (!color_found)             /* no more free color cells */
+         {
+           printf("Sorry, cannot allocate enough colors!\n");
+           exit(0);
+         }
+
+         xcolor.pixel = xcolor2.pixel;
+         xcolor_private[xcolor.pixel] = xcolor;
+         colorcell_used[xcolor.pixel] = TRUE;
+         XStoreColor(disp, ximageinfo->cmap, &xcolor);
+         free_cmap_entries--;
+       }
+
+       *(ximageinfo->index + a) = xcolor.pixel;
       }
-      
-      ximageinfo->no = a;    /* number of pixels allocated in default visual */
 
-      /*  
+      /*
       printf("still %d free colormap entries\n", free_cmap_entries);
       */
 
+      ximageinfo->no = a;      /* number of pixels allocated for this image */
       break;
   
     default:
@@ -742,8 +691,6 @@ XImageInfo *imageToXImage(Display *disp,
       break;
   }
 
-
-
   /* create an XImage and related colormap based on the image type
    * we have.
    */
@@ -889,8 +836,6 @@ XImageInfo *imageToXImage(Display *disp,
     lfree((byte *)bluevalue);
   }
 
-  if (image != orig_image)
-    freeImage(image);
   return(ximageinfo);
 }
 
index 1bdf669..dc60fb9 100644 (file)
--- a/src/xli.h
+++ b/src/xli.h
@@ -74,7 +74,7 @@ typedef struct rgbmap {
  */
 
 typedef struct {
-  char         *title;  /* name of image */
+  char        *title;  /* name of image */
   unsigned int  type;   /* type of image */
   RGBMap        rgb;    /* RGB map of image if IRGB type */
   unsigned int  width;  /* width of image in pixels */