From: Daniel J S. <dan...@ie...> - 2004-09-20 22:34:08
|
Petr Mikulik wrote: >But that's completely different from the patch you have sent: > XFreePixmap(dpy, plot->pixmap); > plot->pixmap = None; > } >+ if (plot != current_plot) >+ RecolorWindow(plot); > display(plot); >+ if (plot != current_plot) >+ RecolorWindow(current_plot); > } > } > >Thus, what's the patch? > Oh, that one at first escaped me. But looking back in the emails, I think that was the first attempt to make the link list contain information about palettes. But soon after that I realized that such code already exists. So the above patch you are referring to was jettisoned. >>That fixes the problem of keeping track of the color map, but it also >>results in an incorrect color map. It looks like a tricky bit of code >>because it is recursive. I'm not exactly sure why it is recursive, as >>opposed to calling a subroutine twice. In fact, I'm looking at some code >>there and wondering what in fact it does. Here is the code in question: >> >>Notice that the second portion of the if/else statement alters two local >>variables, previous and unique_colors, and that is all. That's a useless >>bit of code, as I see it. I wish there were a short note explaining why >>this is recursive, i.e., on the second time through, what portion of the >>code is important? >> >> > >I remember from the old times when Johannes was coding "Make Palette" >function for X11 (term->makepalette(NULL)), that number of available colors >is not known under some visual modes. Then, you have to try to allocate >color palette several times until you find the limit. Can this explain the >recursion? > >However, I wonder why this happens -- once the palette is constructed >(according to t_sm_palette) and copied into plot->cmap, it should be used in >every replot of that window. > If I recall, I think I tracked down the flaw in program flow. Let me look for that... here's a portion of what I wrote before: ===== I think that is the problem. The first time in, the min_colors will be 2 or 10 in one of the examples Petr gives. However, the default cmap, what plot->cmap points to by default has more than 10 allocated values. Hence, that test never passes and the code which dynamically allocates the cmap never gets called. ===== Regardless of whether that is correct or not, I think I'm getting a better view of the big picture here. The real flaw may not necessarily be in PaletteMake(), although I think PaletteMake() needs a good going over to weed out cruft. Well, I shouldn't say that, because I think this problem could be fixed in multiple ways. The problem may be the following. When a plot window is first created, its "plot->cmap" is set equal to the default "cmap". I propose that rather than just pointing to the default colormap, the colomap should be *duplicated* in memory. The reason is that PaletteMake() doesn't necessarily create a new version of color map unless those strange conditions (which I don't fully understand) are met, i.e., if (plot->cmap->allocated < min_colors && !recursion) { ReleaseColormap(plot); /* create a private colormap. */ fprintf(stderr, "switching to private colormap\n"); plot->cmap = (cmap_t *) malloc(sizeof(cmap_t)); assert(plot->cmap); CmapClear(plot->cmap); plot->cmap->colormap = XCreateColormap(dpy, root, vis, AllocNone); assert(plot->cmap->colormap); pr_color(plot->cmap); /* set default colors for lines */ RecolorWindow(plot); recursion = 1; PaletteMake(plot, (t_sm_palette *) tpal); } else { The above is the only place in PaletteMake() that plot->cmap is malloced. That means that if that condition above is not met, which is almost certain to be the case, then the rest of PaletteMake() must act upon the "plot->cmap". So, say two plots are created and by default they are both set to "plot->cmap = cmap". Then whenever PaletteMake() is run on the colormap for one of the plots, it is effectively changing the color map for the other. So, that is why I'm saying that somewhere along the way upon the creation of a plots color map, it must *duplicate* the default palette, i.e., malloc an equal amount of memory as "cmap" and then use memcpy(). That is, if one wants color maps to be preserved in plots. I assume that when the palette is changed at gnuplot's command line, that change is supposed to apply to the default palette as well as the current plot's palette. Dan |