source: abuse/branches/pd/imlib/port/x11/dfb.c @ 528

Last change on this file since 528 was 49, checked in by Sam Hocevar, 15 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 19.6 KB
Line 
1#include <X11/Xlib.h>
2#include <X11/Xutil.h>
3#include <X11/keysym.h>
4
5#ifndef NO_XSHM
6#include <sys/ipc.h>
7#include <sys/shm.h>
8#include <X11/extensions/XShm.h>
9#include <signal.h>
10#endif
11
12#include <string.h>
13#ifdef _AIX
14#include <strings.h>
15#endif
16
17#include "filter.hpp"
18#include "globals.hpp"
19#include "system.h"
20#include "video.hpp"
21#include "dos.h"
22#include "xinclude.h"
23#include "macs.hpp"
24#include "bitmap.h"
25#include "image.hpp"
26#include "jmalloc.hpp"
27
28unsigned char current_background;
29extern unsigned int xres,yres;
30extern palette *lastl;
31int X_xoff,Y_yoff,vmode;
32image *screen;
33char display_name[120];
34
35Window root;
36Display *display;
37int screen_num;
38Screen *screen_ptr;
39unsigned border_width,depth;
40Colormap XCMap;
41Window mainwin;
42GC gc;
43XFontStruct *font_info;
44XVisualInfo *my_visual;
45Visual *X_visual;
46
47static int pixel_scale=1;
48
49uchar last_load_palette[256*4];  // store word alligned for faster access
50
51
52
53
54// ========================================================================
55// makes a null cursor
56// ========================================================================
57
58static Cursor CreateNullCursor(Display *display, Window root)
59{
60    Pixmap cursormask;
61    XGCValues xgc;
62    GC gc;
63    XColor dummycolour;
64    Cursor cursor;
65
66    cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
67    xgc.function = GXclear;
68    gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
69    XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
70    dummycolour.pixel = 0;
71    dummycolour.red = 0;
72    dummycolour.flags = 04;
73    cursor = XCreatePixmapCursor(display, cursormask, cursormask,
74          &dummycolour,&dummycolour, 0,0);
75    XFreePixmap(display,cursormask);
76    XFreeGC(display,gc);
77    return cursor;
78}
79
80
81
82#ifndef NO_XSHM
83// ************** SHM Vars *******************
84int shm_base,shm_error_base,shm_finish_event,doShm=0;
85
86
87struct event_node
88{
89  XEvent report; 
90  event_node *next; 
91} ;
92
93
94void wait_shm_finish()
95{
96  event_node *en,*first=NULL;
97  while (1)
98  {
99    en=(event_node *)jmalloc(sizeof(event_node),"shm_wait : event");
100    XNextEvent(display, &en->report);
101
102    // if this is the finishing event, put all the stored events back
103    // on the que
104#ifndef NO_XSHM
105    if (en->report.type==shm_base+ShmCompletion)
106    {
107      jfree(en);
108     
109      while (first)
110      {
111        XPutBackEvent(display,&first->report);
112        en=first;
113        first=first->next;
114        jfree(en);     
115      }
116      return ;     
117    } else // put the event on the que to be puback
118#endif
119    {
120      en->next=first;     // put the back in reverse order
121      first=en;
122    }   
123  }
124}
125
126   
127#endif
128
129
130int get_vmode()
131{ return vmode; }
132
133void getGC(Window win, GC *gc, XFontStruct *font_info)
134{
135  XGCValues values;
136  *gc=XCreateGC(display,win,0,&values);
137  XSetFont(display, *gc, font_info->fid);
138  XSetForeground(display, *gc, BlackPixel(display,screen_num));
139  XSetLineAttributes(display, *gc, 1, LineSolid, CapRound, JoinRound);
140}
141
142
143class XImage_Info             // stored in the extended desciptor
144{
145public :
146 
147#ifndef NO_XSHM
148  XShmSegmentInfo X_shminfo;   
149#endif
150  XImage *XImg;
151} ;
152
153
154void image::make_page(short width, short height, unsigned char *page_buffer)
155{
156  XImage_Info *xi; 
157  if (special && !special->static_mem)
158  {
159    xi=new XImage_Info;
160    special->extended_descriptor=(void *)xi;   
161#ifndef NO_XSHM
162    if (doShm)
163    {
164      width=(width+3)&(0xffffffff-3);
165      // create the image
166      xi->XImg = XShmCreateImage(display,
167                                 X_visual,
168                                 my_visual->depth,
169                                 ZPixmap,
170                                 0,
171                                 &xi->X_shminfo,
172                                 width*pixel_scale,
173                                 height*pixel_scale);
174
175          w = width = xi->XImg->bytes_per_line / pixel_scale;
176
177      // create the shared memory segment
178      xi->X_shminfo.shmid = shmget (IPC_PRIVATE,
179                width*height*pixel_scale*pixel_scale, IPC_CREAT | 0777);
180      ERROR(xi->X_shminfo.shmid>=0,"shmget() failed, go figure");
181
182      xi->X_shminfo.readOnly=False;
183
184      // attach to the shared memory segment to us
185      xi->XImg->data = xi->X_shminfo.shmaddr =
186                (char *) shmat(xi->X_shminfo.shmid, 0, 0);
187      ERROR(xi->XImg->data,"shmat() failed, go figure");
188
189      // get the X server to attach to it to the X server
190      ERROR(XShmAttach(display, &xi->X_shminfo),"XShmAttach() failed, go figure");
191      XSync(display,False); // make sure segment gets attached
192      ERROR(shmctl(xi->X_shminfo.shmid,IPC_RMID,NULL)==0,"shmctl failed, why?");
193
194          if (pixel_scale == 1)
195            data=(unsigned char *) (xi->XImg->data);
196          else
197            data=(unsigned char *) jmalloc(width*height, "unscaled image");
198    } else
199#endif
200    {
201      width=(width+3)&(0xffffffff-3);       
202      if (!page_buffer)
203        page_buffer=
204                        (unsigned char *)jmalloc(width*height*pixel_scale*pixel_scale,
205                        "image::data");
206     
207      xi->XImg = XCreateImage(  display,
208                                X_visual,
209                                my_visual->depth,
210                                ZPixmap,
211                                0,
212                                (char *)page_buffer,
213                                width*pixel_scale,
214                                height*pixel_scale,
215                                32,
216                                0 );
217      ERROR(xi->XImg,"XCreateImage failed");
218
219          w = width = xi->XImg->bytes_per_line / pixel_scale;
220
221          if (pixel_scale == 1)
222            data=(unsigned char *) (xi->XImg->data);
223          else
224            data=(unsigned char *) jmalloc(width*height, "unscaled image");
225    }   
226  }
227  else
228  {
229    if (!page_buffer)
230      data=(unsigned char *)jmalloc(width*height,"image::data");
231    else data=page_buffer;
232  }
233
234  if (special)
235    special->resize(width,height);
236
237}
238
239void image::delete_page()
240{
241  XImage_Info *xi; 
242  if (special && !special->static_mem && special->extended_descriptor)
243  {   
244    xi=(XImage_Info *)special->extended_descriptor;   
245#ifndef NO_XSHM
246    if (doShm)
247    {   
248      XFlush(display);
249      XSync(display,False);  // maker sure anything with this image is drawn!
250
251      // Dettach the memory from the server
252      ERROR(XShmDetach(display, &xi->X_shminfo),"XShmDetach() failed, go figure");
253
254      XSync(display,False);  // maker sure server detached
255
256      // detach the memory from us, it will be deleted!
257      ERROR(shmdt(xi->X_shminfo.shmaddr)>=0,"shmdt failed, oops");
258
259      xi->XImg->data=NULL;  // tell X not to try to free the memory, cause we already did.
260
261      XDestroyImage(xi->XImg);   
262
263      if (pixel_scale > 1)
264        jfree(data);
265
266    } else
267#endif
268    {
269      if (!special->static_mem)
270        jfree(xi->XImg->data);
271      xi->XImg->data=NULL;                  // make sure X doesn't try to free static memory
272      XDestroyImage(xi->XImg);   
273
274      if (pixel_scale > 1)
275        jfree(data);
276    }
277    delete xi;
278  }
279  else if (!special)
280    jfree(data);     
281}
282
283
284#ifndef NO_XSHM
285#ifdef __sgi
286void clean_shm(...)
287#else
288void clean_shm(int why)      // on exit, delete all images, so shm get de-allocated.
289#endif
290{
291  while (image_list.first())
292  {
293    image *i=(image *)image_list.first();
294    delete i;
295  }
296}
297#endif
298
299void set_mode(int mode, int argc, char **argv)
300{
301  unsigned char *page;
302  vmode=mode;
303  XVisualInfo vis_info;
304  int items,i;
305  XEvent report;
306  XWMHints *wm_hints;
307  XClassHint *class_hints;
308  XTextProperty winName,iconName;
309  XSizeHints *size_hints;
310  char *win_name=argv[0],        // name the window and the icon the executable name
311       *icon_name=argv[0];
312  Pixmap icon_pixmap;
313 
314  // get the default display name from the enviroment variable DISPLAY
315  char *ds_name=getenv("DISPLAY");
316  if (!ds_name) ds_name="unix:0.0";
317  strcpy(display_name,ds_name);
318 
319  int suppress_shm=0;
320
321  // check for command line display name
322  for (i=1;i<argc;i++)
323  {
324    if (!strcasecmp(argv[i],"-display") || !strcasecmp(argv[i],"-disp"))
325    {
326      i++;     
327      strcpy(display_name,argv[i]); 
328    }   
329    else if (!strcasecmp(argv[i],"-noshm"))
330      suppress_shm=1;
331    else if (!strcasecmp(argv[i],"-pixel_scale"))
332      pixel_scale=atoi(argv[i+1]);
333  }
334   
335  display=XOpenDisplay(display_name); 
336  if (!display)
337  {
338    printf("Cound not connect to X server named '%s'\n",display_name);
339    exit(1);
340  }
341
342#ifndef NO_XSHM
343  // check for the MITSHM extension
344  int major_op;
345 
346  if (suppress_shm)
347    doShm=0;
348  else
349    doShm = XQueryExtension(display,"MIT-SHM",&major_op,&shm_base,&shm_error_base);
350
351  // make sure it's a local connection
352  if (doShm)
353  {   
354    char *d = display_name;
355    while (*d && (*d != ':')) d++;
356    if (*d) *d = 0;
357    if (strcasecmp(display_name, "unix") && display_name[0]!=0)
358      doShm = 0;   
359  }
360
361  if (doShm)
362  {
363    printf("Using MITSHM extension!\n");
364    int sigs[29]={SIGHUP,SIGINT,SIGQUIT,SIGILL,SIGTRAP,
365                SIGABRT,SIGIOT,SIGBUS,SIGFPE,SIGKILL,
366                SIGUSR1,SIGSEGV,SIGUSR2,SIGPIPE,SIGALRM,
367                SIGTERM,SIGCHLD,SIGCONT,SIGSTOP,
368                SIGTSTP,SIGTTIN,SIGTTOU,SIGIO,
369                SIGURG,SIGXCPU,SIGXFSZ,SIGVTALRM,SIGPROF,
370                SIGWINCH};
371
372    for (int i=0;i<29;i++)
373      signal(sigs[i],clean_shm);
374  }
375#endif
376  depth=8;
377  screen_num = DefaultScreen(display);
378  screen_ptr = DefaultScreenOfDisplay(display);
379  ERROR(XGetGeometry(display,RootWindow(display,screen_num), &root,
380        &X_xoff,&Y_yoff,&xres,&yres,&border_width,&depth),
381        "can't get root window attributes");
382
383  {
384    vis_info.c_class=PseudoColor;       
385    vis_info.depth=8;
386    my_visual=XGetVisualInfo(display,VisualClassMask | VisualDepthMask, &vis_info,&items);
387    X_visual=my_visual->visual;
388
389    if (items>0)
390    {
391      int rc;
392
393      vmode=XWINDOWS_256;
394
395      rc=XMatchVisualInfo(display, screen_num, 8, PseudoColor, &vis_info);
396      ERROR(rc, "What the hell? Non-8 bit Psuedo color..\n");
397      X_visual = my_visual->visual = vis_info.visual;
398      //    ERROR(my_visual->depth==8,"What the hell? Non-8 bit Psuedo color..\n");
399      printf("Using 8 bit Psuedo color\n");
400    }
401    else
402    {
403      printf("X windows screen type not supported\n");
404      exit(0);
405    }
406  }
407
408  xres=320; yres=200;
409  for (i=1;i<argc;i++)
410  { if (!strcmp(argv[i],"-size"))
411    { i++; if (!sscanf(argv[i],"%d",&xres)) xres=320;
412      i++; if (!sscanf(argv[i],"%d",&yres)) yres=200;
413    }
414  }
415
416
417  Colormap tmpcmap;
418 
419  tmpcmap = XCreateColormap(display, XRootWindow(display,
420                                                my_visual->screen), X_visual, AllocNone);
421
422  int attribmask = CWColormap | CWBorderPixel;
423  XSetWindowAttributes attribs;
424  attribs.border_pixel = 0;
425  attribs.colormap = tmpcmap;
426 
427  mainwin=XCreateWindow(display,
428                        XRootWindow(display,my_visual->screen),
429                        0,0,xres*pixel_scale, yres*pixel_scale,
430                        0,
431                        my_visual->depth,
432                        InputOutput,
433                        X_visual,
434                        attribmask,
435                        &attribs);
436  xres--; yres--;
437
438
439  icon_pixmap=XCreateBitmapFromData(display,mainwin,bitmap_bits,
440        bitmap_width, bitmap_height);
441  ERROR((size_hints=XAllocSizeHints()),"memory allocation error");
442  ERROR((wm_hints=XAllocWMHints()),"memory allocation error");
443  ERROR((class_hints=XAllocClassHint()),"memory allocation error");
444
445  int lock=0;
446  for (i=1;i<argc;i++)
447    if (!strcmp(argv[i],"-lock_size"))
448     lock=1;
449
450  if (lock)
451  {
452    size_hints->flags=PPosition | PSize | PMinSize | PMaxSize;
453    size_hints->min_width  = (xres+1)*pixel_scale;
454    size_hints->min_height = (yres+1)*pixel_scale;
455    size_hints->max_width  = (xres+1)*pixel_scale;
456    size_hints->max_height = (yres+1)*pixel_scale;
457  }
458  else
459  {
460    size_hints->flags=PPosition | PSize | PMinSize;
461    size_hints->min_width  = 320;
462    size_hints->min_height = 200;
463  }
464
465
466  ERROR(XStringListToTextProperty(&win_name,1,&winName),"alloc failed");
467  ERROR(XStringListToTextProperty(&icon_name,1,&iconName),"alloc fialed");
468  wm_hints->initial_state=NormalState;  // not iconified at first
469  wm_hints->input=1;                  // needs keyboard input
470  wm_hints->icon_pixmap=icon_pixmap;
471  wm_hints->flags=StateHint | IconPixmapHint | InputHint;
472  class_hints->res_name=argv[0];
473  class_hints->res_class="(C) 1995 Crack dot Com, Jonathan Clark";
474  XSetWMProperties(display,mainwin,&winName,&iconName,argv,argc,size_hints,
475        wm_hints,class_hints);
476  XSelectInput(display,mainwin,ExposureMask|KeyPressMask|ButtonPressMask|
477        StructureNotifyMask);
478  ERROR(font_info=XLoadQueryFont(display,"9x15"),"cannot open 9x15");
479  getGC(mainwin,&gc,font_info);
480
481/* try to determine what type of monitor we are using */
482
483
484  // detect which type of screen the X client will run on...
485  // if they requested 24 bit mode, check for that type of display
486 
487
488
489  XSetBackground(display,gc,BlackPixel(display,screen_num));
490
491  XMapWindow(display,mainwin);
492  do
493  { XNextEvent(display, &report);
494  } while (report.type!= Expose);     // wait for our window to pop up
495
496
497  XDefineCursor(display,mainwin, CreateNullCursor(display,mainwin));
498
499  screen=new image(xres+1,yres+1,NULL,2); 
500
501  XCMap=XCreateColormap(display,mainwin,X_visual,AllocAll); 
502  screen->clear();
503  update_dirty(screen);
504
505  for (i=1;i<argc;i++)
506  { if (!strcmp(argv[i],"-grab_pointer"))
507    {
508      i++;
509      int sec;
510      if (i<argc && sscanf(argv[i],"%d",&sec))
511      { printf("-grab_pointer : delaying for %d seconds\n",sec);
512        sleep(sec);
513      }
514      if (XGrabPointer(display,mainwin,True,
515                       PointerMotionMask|ButtonMotionMask|
516                       Button1MotionMask|
517                       Button2MotionMask|
518                       Button3MotionMask|
519                       Button4MotionMask|
520                       Button5MotionMask,
521                       GrabModeAsync,
522                       GrabModeAsync,
523                       mainwin,
524                       None,
525                       CurrentTime)==GrabSuccess)
526        printf("Pointer grab in effect!\n");
527      else
528        printf("Unable to grab pointer  :(\n");
529    }
530  }
531   
532}
533
534void close_graphics()
535{
536  if (lastl) delete lastl; lastl=NULL;
537  delete screen;
538  XUnloadFont(display,font_info->fid);
539  XFreeGC(display,gc);
540  XFree((char *)my_visual);
541  XCloseDisplay(display);
542}
543
544void scale_image(image *im, int src_x, int src_y, int src_w, int src_h)
545{
546
547  uchar *src;
548  ushort *dst;
549  ushort pixel;
550  int dx;
551  int y;
552  int next_dst_line;
553  int w;
554  XImage_Info *xi=(XImage_Info *)im->special->extended_descriptor;
555
556  if (pixel_scale == 2)
557  {
558          src=im->scan_line(src_y)+src_x;
559      dst=(ushort *) (xi->XImg->data+src_y*xi->XImg->bytes_per_line*2+src_x*2);
560          next_dst_line = xi->XImg->bytes_per_line/2;
561          w = im->width();
562
563          for (y=src_h;y;y--)
564          {
565                for (dx=0;dx<src_w;dx++)
566                {
567                  pixel = *(src+dx);
568                  pixel |= pixel<<8;
569                  *(dst+dx) = pixel;
570                  *(dst+dx+next_dst_line) = pixel;
571                }
572                src += w;
573                dst += xi->XImg->bytes_per_line;
574          }
575
576  }
577
578}
579
580void copy_24part(uchar *Xdata, image *im, int x1, int y1, int x2, int y2)
581{
582  uchar *src=im->scan_line(y1)+x1;
583  ushort *dst=(ushort *)Xdata+(y1*2)*im->width()+x1;
584
585  int src_add=im->width()-(x2-x1+1);
586
587  int x,y,w=(x2-x1+1)*2;
588  ushort v;
589  for (y=y1;y<=y2;y++)
590  {
591    for (x=x1;x<=x2;x++)
592    {
593      v=*(src++);
594      *(dst++)=(v|(v<<8));
595    }   
596    dst=(ushort *) ((uchar *)dst+src_add*2);
597    memcpy(dst,(uchar *)dst-im->width()*2,w);
598    dst=(ushort *)((uchar *)dst+im->width()*2);
599
600    src+=src_add;
601  }
602}
603
604
605
606void put_part_image(Window win, image *im, int x, int y, int x1, int y1, int x2, int y2)
607{
608  CHECK(im->special);
609  XImage_Info *xi=(XImage_Info *)im->special->extended_descriptor;
610
611  if (pixel_scale>1)
612    scale_image(im,x1,y1,x2-x1+1,y2-y1+1);
613
614#ifndef NO_XSHM
615  if (doShm)
616  {   
617    XEvent ev;
618    XSync(display,False);
619    if (XCheckTypedEvent(display, ConfigureNotify,&ev)==False)
620    {
621      XShmPutImage(display,win,gc,xi->XImg,x1*pixel_scale,y1*pixel_scale,
622            x*pixel_scale,y*pixel_scale,(x2-x1+1)*pixel_scale,
623                (y2-y1+1)*pixel_scale,True);
624      // wait for the Put to finish
625      wait_shm_finish();
626    } else     // screen size changed,  better wait till this event is handled cause put might be invalid
627      XPutBackEvent(display,&ev);
628
629  } 
630  else 
631#endif
632    XPutImage(display,win,gc,xi->XImg,x1*pixel_scale,y1*pixel_scale,
633      x*pixel_scale,y*pixel_scale,(x2-x1+1)*pixel_scale,(y2-y1+1)*pixel_scale);
634
635}
636
637void put_image(image *im, int x, int y)
638{
639  put_part_image(mainwin,im,x,y,0,0,im->width()-1,im->height()-1); 
640}
641
642
643
644void update_dirty_window(Window win, image *im, int xoff, int yoff)
645{
646
647  int count;
648  dirty_rect *dr,*q;
649  image *Xim;
650  CHECK(im->special);  // make sure the image has the ablity to contain dirty areas
651  if (im->special->keep_dirt==0)
652    put_image(im,xoff,yoff);
653  else
654  {
655    count=im->special->dirties.number_nodes();
656    if (!count) return;  // if nothing to update, return
657    dr= (dirty_rect *) (im->special->dirties.first());
658    while (count>0)
659    {
660      put_part_image(win,im,xoff+dr->dx1,yoff+dr->dy1,dr->dx1,dr->dy1,dr->dx2,dr->dy2);     
661//      XDrawRectangle(display,mainwin,gc,xoff+dr->dx1,yoff+dr->dy1,
662//                   xoff+dr->dx2-dr->dx1+1,yoff+dr->dy2-dr->dy1+1);
663      q=dr;
664      dr=(dirty_rect *) (dr->next());
665      im->special->dirties.unlink((linked_node *)q);
666      delete q;
667      count--;
668    }
669  }
670//  XFlush(display);
671}
672
673void update_dirty(image *im, int xoff, int yoff)
674{ update_dirty_window(mainwin,im,xoff,yoff); }
675
676void palette::load()
677{
678  if (lastl)
679    delete lastl;
680  lastl=copy();
681
682  {
683    int i;
684    if (get_vmode()!=XWINDOWS_2)
685    {
686      XColor color;
687      color.flags=DoRed|DoBlue|DoGreen;
688      for (i=0;i<ncolors;i++)
689      {
690        color.pixel=i;
691        color.red=red(i)<<8|0xff; color.green=green(i)<<8|0xff; color.blue=blue(i)<<8|0xff;
692        XStoreColor(display,XCMap,&color);
693      }
694      XSetWindowColormap(display,mainwin,XCMap);
695    }
696    else lastl->black_white();
697    current_background=bg;
698  }
699}
700
701struct hist_entry
702{
703  long total;
704  unsigned char org;
705} ;
706
707static int histcompare(const void *i, const void *j)
708{
709  if (((hist_entry *)i)->org==0) return -1;  // make sure the background gets allocated
710  else return(((hist_entry *)j)->total - ((hist_entry *)i)->total);
711}
712
713
714void palette::load_nice()
715{
716  int i,fail,y,x,wd,j;
717  long closest_val,closest_pixel,k;
718  char *gotten;
719  image *im;
720  unsigned char *sl;
721  palette *Xpal;
722  hist_entry *histogram;
723  Colormap stdcm;
724  XColor color;
725
726  if (get_vmode()!=XWINDOWS_2) 
727  {
728    filter f(ncolors);
729
730    histogram=(hist_entry *)jmalloc(sizeof(hist_entry)*ncolors,"palette::histogram");
731    gotten=(char *)jmalloc(ncolors,"palette::gotten_colors");
732
733    memset(gotten,0,ncolors);
734    for (i=0;i<ncolors;i++)
735    { histogram[i].total=0;
736      histogram[i].org=i;
737    }
738
739    for (i=image_list.number_nodes(),im=(image *)image_list.first();i;i--,im=(image *)im->next())
740    {
741      if (im!=screen)
742      {
743        wd=im->width();
744        for (y=im->height();y;y--)
745        {
746          sl=im->scan_line(y-1);
747          for (x=0;x<wd;x++)
748            histogram[sl[x]].total++;
749        }
750      }
751    }
752    qsort(histogram,ncolors,sizeof(hist_entry),histcompare);
753    stdcm=XDefaultColormap(display,screen_num);
754    Xpal=NULL;
755    for (i=0,fail=0;i<ncolors;i++)
756    {
757      color.red=red(histogram[i].org)<<8;
758      color.green=green(histogram[i].org)<<8;
759      color.blue=blue(histogram[i].org)<<8;
760
761      if (XAllocColor(display,stdcm,&color))
762        f.set(histogram[i].org,color.pixel);
763      else  // if we couldn't allocate that color from X, find the closest.
764      {
765        if (!Xpal)
766        { Xpal=new palette(ncolors);
767          for (j=0;j<ncolors;j++)
768          {
769            color.pixel=j;
770            XQueryColor(display,stdcm,&color);
771            Xpal->set(j,color.red>>8,color.green>>8,color.blue>>8);
772          }
773        }
774        closest_val=0xfffffff;
775        for (j=0;j<ncolors;j++)
776        {
777          k=Xpal->red(j)*Xpal->red(j)+Xpal->green(j)*Xpal->green(j)+
778            Xpal->blue(j)*Xpal->blue(j);
779          if (k<closest_val)
780          { closest_val=k;
781            closest_pixel=j;
782          }
783        }
784        f.set(histogram[i].org,closest_pixel);
785      }
786    }
787    if (!Xpal)
788      Xpal=new palette(ncolors);
789    // store the color mapping we created back to the palette.
790    for (j=0;j<ncolors;j++)
791      Xpal->set(j,red(f.get_mapping(j)),green(f.get_mapping(j)),blue(f.get_mapping(j)));
792    for (j=0;j<ncolors;j++)
793      set(j,Xpal->red(j),Xpal->green(j),Xpal->blue(j)); 
794    bg=f.get_mapping(bg);
795     
796    // now remap all the images to fit this colormap!
797    for (i=image_list.number_nodes(),im=(image *)image_list.first();i;i--,im=(image *)im->next())
798      f.apply(im);
799
800    delete Xpal;
801    jfree(histogram);
802    jfree(gotten);
803  }
804  current_background=bg;
805}
806
Note: See TracBrowser for help on using the repository browser.