source: abuse/tags/pd/macabuse/imlib/port/x11/video.c @ 49

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