Logo Search packages:      
Sourcecode: randim version File versions  Download package

win_setup.c

/* win_setup.c: Window specification/initialization functions for randim. */

/* This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.  Please see the file "COPYING"
   for details.  If you have not received it along with this program,
   please write to the Free Software Foundation, Inc., 675 Mass. Ave.,
   Cambridge, MA 02139, USA. */

#include "randim.h"
#include <dirent.h>

/* win_setup() sets up the main windows then calls panel_setup() and
    edit_setup() to set up the main panel and the edit popup window
    respectively. The basic method of window setup/creation is to create
    things called "widgets" which are combinations of windows and i/o
    flow-control mechanisms by putting desired specifications into the
    arg structure and then calling create function.*/
void
win_setup()
{
  Cursor    cursor;           /*for setting cursor in draw window*/
  XtVarArgsList bkbd;
  XSetWindowAttributes setattr;

  int i;

  /*Get some basic information from server then define the main window
  as a Form widget, which simply holds windows and rearranges them on
  resizes.*/
  display = XtDisplay(pwidget);
  screen_n = DefaultScreen(display);
  white = WhitePixel(display,screen_n), black = BlackPixel(display,screen_n);
  /* We could try to make everything proportional to the screen size, but this
     would be hard given that we must provide absolute coordinates during
     construction... */
  /*dwidth = DisplayWidth(display,screen_n);
    dheight = DisplayHeight(display,screen_n);*/

  /* put the thing in the top left of the screen */
  XtVaSetValues(pwidget,XtNgeometry,"+1+0",NULL);

  XLoadFont(display,"cursor");
  cursor = XCreateFontCursor(display,XC_crosshair);
  bkbd = XtVaCreateArgsList(NULL, XtNbackground,black,
                            XtNborderColor,white, NULL);

  mframe = XtVaCreateManagedWidget("mainwidget",formWidgetClass,pwidget,
                         XtVaNestedList,bkbd,NULL);

  /*Subwindow to be drawn into*/
  cwidg = XtVaCreateManagedWidget("cwidg",simpleWidgetClass,mframe,
                       XtVaNestedList,bkbd, XtNwidth,450, XtNheight,450,
                       XtNcursor,cursor,NULL);

  /*If this is resized, call function resize() to rescale drawing*/
  XtAddEventHandler(cwidg,StructureNotifyMask,False,(XtEventHandler) resize,0);

  /*Auxiliary panel, a child of mframe to hold transreps*/
  apanel = XtVaCreateManagedWidget("apanel",formWidgetClass,mframe,
                       XtVaNestedList,bkbd, XtNwidth,56, XtNheight,440,
                       XtNhorizDistance,460, XtNvertDistance,4,NULL);

  /*If resized/exposed, call rep_resize() to rescale coordinates/replot. */
  XtAddEventHandler(apanel,StructureNotifyMask | ExposureMask ,False,
                (XtEventHandler) rep_resize,0);

  /*If it is exposed, call function rep_resize() to rescale coordinates*/
  XtAddEventHandler(apanel,StructureNotifyMask,False,
                (XtEventHandler) rep_resize,0);

  /*Now create TRANSREPN subwidgets for representing transformations*/
  for (i=0;i<TRANSREPN;i++) {
    trepWidg[i] = XtVaCreateManagedWidget("trepwidg",simpleWidgetClass,apanel,
                        XtVaNestedList,bkbd, XtNwidth,54, XtNheight,50,
                        XtNhorizDistance,4, XtNvertDistance, i*54+3,
                        XtNcursor,cursor,NULL);
    repdat[i] = i;
    }
  transreps_on(); /*activate sensitivity to buttons*/

/*Main panel, a child of mframe to hold buttons, etc. for user interaction*/
  mpanel = XtVaCreateManagedWidget("mpanelw",formWidgetClass,mframe,
                        XtVaNestedList,bkbd, XtNwidth,50, XtNheight,450,
                        XtNhorizDistance,528, XtNvertDistance,4,NULL);

/* Set up the main panel, edit window, and aux window */
  panel_setup();
  edit_setup();
  ss_setup();

  /*Realize the parent widget, which maps all children except the popup
  epopup and its children*/
  XtRealizeWidget(pwidget);

  /* set its colormap */
  /* //if (isPrivateCmap)
     XSetWindowColormap(display, XtWindow(pwidget), cmap); */

  /*Get id of window for canvas widget so we can draw directly into it*/
  canvas = XtWindow(cwidg);
  for (i=0;i<TRANSREPN;i++)
    trepWin[i] = XtWindow(trepWidg[i]);

  /* initialize colors to user specified or default colormap */
  build_colorfile_list();
  init_colors(cmapName);

  /* Create a Pixmap for hidden drawing purposes */
  hcanvas = XCreatePixmap(display,canvas,450,450,depth);

  XtFree(bkbd);

  setattr.backing_store = WhenMapped;
  XChangeWindowAttributes(display,canvas,CWBackingStore,&setattr);

}

  
/* panel_setup() lays out buttons, labels for output, and dialogs for input
   on main panel.*/
void
panel_setup()
{
  XtVarArgsList bketc;

  bketc = XtVaCreateArgsList(NULL, XtNbackground,black, XtNborderColor,white,
                       XtNforeground,white, XtNhorizDistance,5, NULL);

  /*Buttons - each one is defined in its position, then a callback is
  defined to be called when pressed.  Each position is specified
  relative to previous.*/

  mbutton[0] = XtVaCreateManagedWidget("mbutton0",commandWidgetClass,mpanel,
                          XtVaNestedList,bketc, XtNvertDistance,5,
                          XtNshapeStyle,XmuShapeRoundedRectangle,
                          XtNlabel,"Next", NULL);
  XtAddCallback(mbutton[0],"callback",next_imt,0);

#define Vbutton(_var,_num,_name,_func) \
      _var[_num] = XtVaCreateManagedWidget(_name,commandWidgetClass,mpanel, \
                       XtVaNestedList,bketc, XtNvertDistance,5, \
                       XtNshapeStyle,XmuShapeRoundedRectangle, \
                       XtNlabel,_name,XtNfromVert,_var[_num-1], NULL); \
      XtAddCallback(_var[_num],"callback",_func,0)

  Vbutton(mbutton,1,"Pause",pause_toggle);
  Vbutton(mbutton,2,"Edit",edit_trans);
  Vbutton(mbutton,3,"Zoom pt",zoom_point);
  Vbutton(mbutton,4,"Zoom rect",zoom_rect);
  Vbutton(mbutton,5,"Set Zmag",zmag_query);
  Vbutton(mbutton,6,"XformColor",colorToggle1); /* 1 color per transform */
  Vbutton(mbutton,7,"DepthColor",colorToggle2); /* 'depth' color */
  Vbutton(mbutton,8,"DensIntens",togDensIntens); /* density-based intensity */
  Vbutton(mbutton,9,"ChangeCmap",change_cmap);
  Vbutton(mbutton,10,"DiffEq",diffEqToggle);
  Vbutton(mbutton,11,"E.vals",printEvals);
  Vbutton(mbutton,12,"Slideshow",slideshow_toggle);
  Vbutton(mbutton,13,"Animate",animation_toggle);
  Vbutton(mbutton,14,"Rescale",rescale);
  Vbutton(mbutton,15,"Quit",shut_down);

  /*Text output area (mmlabel) for message displays; */
  mmlabel[0] = XtVaCreateManagedWidget("mmlabel0",labelWidgetClass,mpanel,
                          XtVaNestedList,bketc, XtNvertDistance,54,
                          XtNwidth,80, XtNlabel," ",
                          XtNfromVert,mbutton[15], NULL);

  XtFree(bketc);

}


/* edit_setup() does same as panel_setup() did, except for edit window, and
   it sets holding parent widget for edit up as a transient popup shell.*/
void
edit_setup()
{
  int       i;          /*an index*/
  Cursor    cursor;           /*to assign a cursor to the edit window*/
  Widget    wtitle;

  cursor = XCreateFontCursor(display,XC_left_ptr);

  /*Create a popup shell widget to hold edit window*/
  epopup = XtVaCreatePopupShell("epop",topLevelShellWidgetClass,pwidget,
                        XtNx,50, XtNy,50, XtNcursor,cursor,
                        XtNtitle,"Edit",XtNgeometry,"+50+100",NULL);
  /*                    XtNcolormap,cmap,NULL); */

  /*containing frame and its title*/
  eframe = XtVaCreateManagedWidget("eframew",formWidgetClass,epopup,
                           XtNbackground,black, XtNborderColor,white,
                           XtNborderWidth,2,NULL);

  /* use manual arg setting to save repetition */
  arg[0].name= XtNbackground, arg[0].value = (XtArgVal) black;
  arg[1].name= XtNborderColor, arg[1].value = (XtArgVal) white;
  arg[2].name = XtNforeground, arg[2].value = (XtArgVal) white;
  arg[3].name = XtNlabel, arg[3].value = (XtArgVal) "EDIT TRANSFORMATIONS:";
  arg[4].name = XtNhorizDistance, arg[4].value = (XtArgVal) 190;
  wtitle = XtCreateManagedWidget("title",labelWidgetClass,eframe,arg,5);

/*Heading and radio buttons for transformation type selection*/

  arg[3].value = (XtArgVal) "Transformation Type:";
  arg[4].name = XtNvertDistance, arg[4].value = (XtArgVal) 40;
  arg[5].name = XtNborderWidth, arg[5].value = (XtArgVal) 0;
  XtCreateManagedWidget("ttitle",labelWidgetClass,eframe,arg,6); /*Title*/

  arg[3].value = (XtArgVal) "Fully random";
  arg[4].value = (XtArgVal) 75;
  arg[5].name = XtNfromVert, arg[5].value = (XtArgVal) NULL;
  trdat[0] = 0;
  arg[6].name = XtNradioData, arg[6].value = (XtArgVal) &trdat[0];
  arg[7].name = XtNshapeStyle, arg[7].value = (XtArgVal) XmuShapeOval;
  tradbutton[0] =
    XtCreateManagedWidget("tradbutton0",toggleWidgetClass,eframe,arg,8);
  arg[4].value = (XtArgVal) 10;
  arg[8].name = XtNradioGroup, arg[8].value = (XtArgVal) tradbutton[0]; \

#define Vradbutton(_var,_dat,_num,_name) arg[3].value = (XtArgVal) _name; \
  arg[5].value = (XtArgVal) _var[_num-1]; \
  _dat[_num] = _num, arg[6].value = (XtArgVal) &_dat[_num]; \
  _var[_num] = XtCreateManagedWidget(_name,toggleWidgetClass,eframe,arg,9)

  Vradbutton(tradbutton,trdat,1,"Fully Symmetric");
  Vradbutton(tradbutton,trdat,2,"Randomized Symmetric");
  Vradbutton(tradbutton,trdat,3,"Rotational, constant r");
  Vradbutton(tradbutton,trdat,4,"Rotational, random r");
  Vradbutton(tradbutton,trdat,5,"Hybrid");
  Vradbutton(tradbutton,trdat,6,"Fern");

  /*Set initial state of radio buttons, and set function to be called on
  toggle - same function no matter which one is hit.*/
  XtVaSetValues(tradbutton[6],XtNstate,True,NULL);
  for (i=0;i<TRANSTYPES;i++)
    XtAddCallback(tradbutton[i],"callback", (XtCallbackProc) set_ttype,&i);

/*Radio buttons for dimension selection*/

  arg[3].value = (XtArgVal) "Dimension";
  arg[5].value = (XtArgVal) NULL, arg[4].value = (XtArgVal) 40;
  arg[6].name = XtNhorizDistance, arg[6].value = (XtArgVal) 250;
  XtCreateManagedWidget("ttitle",labelWidgetClass,eframe,arg,7);  /*Title*/

  arg[3].value = (XtArgVal) "2";
  drdat[0] = 0;
  arg[4].value = (XtArgVal) 80;
  arg[7].value = (XtArgVal) XmuShapeRoundedRectangle;
  arg[8].name = XtNradioData, arg[8].value = (XtArgVal) &drdat[0];
  dradbutton[0] =
    XtCreateManagedWidget("dradbutton0",toggleWidgetClass,eframe,arg,9);
  arg[4].value = (XtArgVal) 10;

  arg[3].value = (XtArgVal) "3";
  arg[4].value = (XtArgVal) 10, arg[5].value = (XtArgVal) dradbutton[0];
  drdat[1] = 1, arg[8].value = (XtArgVal) &drdat[1];
  arg[9].name = XtNradioGroup, arg[9].value = (XtArgVal) dradbutton[0];
  dradbutton[1] =
    XtCreateManagedWidget("dradbutton1",toggleWidgetClass,eframe,arg,10);

  /*Set initial state, and set function to be called on toggle.*/
  XtVaSetValues(dradbutton[0],XtNstate,True,NULL);
  for (i=0;i<2;i++)
    XtAddCallback(dradbutton[i],"callback", (XtCallbackProc) set_dim,&i);

/*Dialogs for numeric entry.*/

  /* number of trans */
  arg[6].value = (XtArgVal) 250;
  arg[3].value = (XtArgVal) "Log/#trans";
  arg[4].value = (XtArgVal) 20, arg[5].value = (XtArgVal) dradbutton[1];
  arg[7].name = XtNvalue, arg[7].value = (XtArgVal) "2";
  e_in[0] = XtCreateManagedWidget("ein0",dialogWidgetClass,eframe,arg,8);

  arg[3].value = (XtArgVal) "Log/#rtrans:";
  arg[4].value = (XtArgVal) 10, arg[5].value = (XtArgVal) e_in[0];
  arg[7].value = (XtArgVal) "0";
  e_in[1] = XtCreateManagedWidget("ein1",dialogWidgetClass,eframe,arg,8);

  /* animation params */
  arg[6].value = (XtArgVal) 400;  /*move over horizontally for next stuff*/

  arg[3].value = (XtArgVal) "Anim #/mods:";
  arg[4].value = (XtArgVal) 40, arg[5].value = (XtArgVal) NULL;
  arg[7].value = (XtArgVal) "3";
  e_in[2] = XtCreateManagedWidget("ein2",dialogWidgetClass,eframe,arg,8);

  arg[3].value = (XtArgVal) "Anim Step:";
  arg[4].value = (XtArgVal) 10, arg[5].value = (XtArgVal) e_in[2];
  arg[7].value = (XtArgVal) "0.1";
  e_in[3] = XtCreateManagedWidget("ein3",dialogWidgetClass,eframe,arg,8);

  arg[3].value = (XtArgVal) "Anim Persist:";
  arg[4].value = (XtArgVal) 10, arg[5].value = (XtArgVal) e_in[3];
  arg[7].value = (XtArgVal) "20";
  e_in[4] = XtCreateManagedWidget("ein4",dialogWidgetClass,eframe,arg,8);

  /* rand seed */
  arg[3].value = (XtArgVal) "Randseed:";
  arg[4].value = (XtArgVal) 10, arg[5].value = (XtArgVal) e_in[4];
  arg[7].value = (XtArgVal) "77";
  e_in[5] = XtCreateManagedWidget("ein5",dialogWidgetClass,eframe,arg,8);

  /*Finally, create a DONE button*/

  arg[3].value = (XtArgVal) "Done";
  arg[6].value = (XtArgVal) 420;
  arg[4].value = (XtArgVal) 10, arg[5].value = (XtArgVal) NULL;
  arg[7].name = XtNshapeStyle, arg[7].value = (XtArgVal) XmuShapeEllipse;
  ebutton = XtCreateManagedWidget("ebutton",commandWidgetClass,eframe,arg,8);
  XtAddCallback(ebutton,"callback",close_edit,0);

}

/* ss_setup() does same as edit_setup() but for small dialog window for
   slideshow or animation point-number and zoom magnification setting */
void
ss_setup()
{
  Cursor    cursor;

  cursor = XCreateFontCursor(display,XC_left_ptr);

  /*Create a popup shell widget to hold slideshow set window*/
  dpopup = XtVaCreatePopupShell("sspop",transientShellWidgetClass,pwidget,
                XtNx,250, XtNy,250,
              XtNcursor,cursor, XtNtitle,"SlideShow",
              XtNcolormap,cmap,NULL);

  /* window contains a frame and its title*/
  ssframe = XtVaCreateManagedWidget("ssframe",formWidgetClass,dpopup,
             XtNbackground,black, XtNborderColor,white,
             XtNborderWidth,2,NULL);

  ss_in = XtVaCreateManagedWidget("ssin0",dialogWidgetClass,ssframe,
             XtNbackground,black, XtNborderColor,white,
             XtNlabel,"                        ", XtNvalue,"        ",NULL);

  ssbutton = XtVaCreateManagedWidget("ssbu",commandWidgetClass,ssframe,
              XtNshapeStyle,XmuShapeRoundedRectangle,
            XtNbackground,black, XtNborderColor,white,
            XtNvertDistance,5, XtNhorizDistance,55,   XtNfromVert,ss_in, 
            XtNlabel,"Enter", XtNforeground,white, NULL);
  XtAddCallback(ssbutton,"callback",dpopset,0);

}

/*************************************************************************/
/* auxiliary setup functions */

void alloc_gc();
void getIntensitySet(char *hue, char intSet[N_INTS][20]);

/* init_colors() goes through the complicated dance to get some colors out
   of X, as specified by the fractint colormap file 'uFname'.  Currently
   not much flexibility - it either gets NCOLORS
   (or (NCOLORS+1)*N_INTS+NCOLORS, if isLargeCmode is true) colors or it
   gives up. */
void
init_colors(char *uFname)
{
  int       i,j;
  FILE            *fp = NULL;
  int       rval, gval, bval, t;
  char            rstr[3], gstr[3], bstr[3];
  float           g;
  XVisualInfo     visual_info;
  char            cfname[100], line[160];
  char            cnames[NCOLORS+1][20];
  char            intSet[N_INTS][20];
  int       brightestColor = 0, dimmestColor = 0;

  plane_masks[0] = 0;

  ncolors = isLargeCmap ? (NCOLORS+1) * N_INTS + NCOLORS : NCOLORS;
  cdefs = (XColor *) malloc(sizeof(XColor) * ncolors);
  colors = (unsigned long *) malloc(sizeof(unsigned long) * ncolors);
  if (!cdefs || !colors) {
    printf("Out of memory in init_colors().\n");
    exit(1);
  }

  /* attempt to read in a list of colors (if not, the variable has
     already been set internally) */
  if (strlen(uFname) > 0) {
    if (!(fp = fopen(uFname, "r"))) { /* try it as a path */
      sprintf(cfname,"%s/%s",LIBDIR,uFname);
      if (!(fp = fopen(cfname,"r"))) { /* try it in the libdir */
        printf("Unable to find the colormap \"%s\" in the directory %s.  Checking for default \"randim.map\"...\n", uFname,LIBDIR);
      }
    }
  }
  if (!fp) {                    /* no success via user file; try default */
    strcpy(cfname,LIBDIR);
    strcat(cfname,"/randim.map");
    if (!(fp = fopen(cfname,"r"))) {
      printf("Using default colormap: shades of grey.\nTo customize, make a file named %s\nwith %d colorspecs in it, one per line, in fractint (3 byte values) format.\n\n",cfname,NCOLORS);
    }
  }
  if (!fp) {                    /* no success via any file; use internal */
    for (i=0;i<NCOLORS;i++) {
      g = (float) i/NCOLORS * 256.0; 
      itoh((int)g,rstr), itoh((int)g,gstr), itoh((int)g,bstr);
      sprintf(cnames[i],"rgb:%s/%s/%s",rstr,gstr,bstr);
      }
    }
  else {
    for (i=0;i<NCOLORS;i++) {
      /* convert 3 decimal values to rgb intensity spec */
      if (!getnextline(fp,line)) {
      printf("***ERROR!  color file has less than %d usable lines.\n",
             NCOLORS);
      exit(1);
      }
      sscanf(line,"%d %d %d\n",&rval,&gval,&bval);
      itoh(rval,rstr), itoh(gval,gstr), itoh(bval,bstr);
      sprintf(cnames[i],"rgb:%s/%s/%s",rstr,gstr,bstr);
      }
    fclose(fp);
  }
  /* grey */
  strcpy(cnames[NCOLORS],"rgb:80/80/80");

  /* gather default information on server */
  depth = DefaultDepth(display,screen_n);
  visual = DefaultVisual(display,screen_n);
  cmap = DefaultColormap(display,screen_n);
  isPrivateCmap = 0;

  if (depth == 1) {
    printf("\nScreen depth = 1: running in black & white mode.\n\n");
    gcflag = 0;
    alloc_gc();
    free(cdefs);
    return;
    }

  /* get best possible "visual" (color accessing scheme) */
  for (i=5;!XMatchVisualInfo(display, screen_n, depth, i, &visual_info);i--);
  
  if (i < StaticColor) { /* only greyscale */
    printf("\nGreyscale only: running in black & white mode.\n\n");
    gcflag = 0;
    alloc_gc();
    free(cdefs);
    return;
    }

  else if ((i == PseudoColor) || (i == DirectColor)) {
    /* have ability to allocate read/write cells, so try that route */
    if (!XAllocColorCells(display,cmap,False,plane_masks,1,colors,ncolors)) {
      gcflag = 0;
      printf("\nUnable to allocate read/write color cells; ");
      printf("trying read-only.\n");
    } else {
      /* small colormap portion */
      for (i=0;i<NCOLORS;i++) {
      if (!XParseColor(display,cmap,cnames[i],&(cdefs[i]))) {
        printf("\nYour server's color list has zero selection! %d read/write colors actually gotten.\n\n",i);
        exit(1);
        }
      cdefs[i].pixel = colors[i];
      cdefs[i].flags = DoRed | DoGreen | DoBlue;
      }

      /* large colormap portion */
      if (isLargeCmap) {
        for (i=0; i<NCOLORS+1; i++) {
          getIntensitySet(cnames[i], intSet);
          for (j=0; j<N_INTS; j++) {
            if (!XParseColor(display,cmap,intSet[j],
                             &(cdefs[NCOLORS+i*N_INTS+j]))) {
              printf("\nCouldn't find a color! %d read/write colors actually gotten.\n\n",NCOLORS+i*N_INTS+j);
              exit(1);
            }
          }
        }
      }

      XStoreColors(display,cmap,cdefs,ncolors);
      gcflag = 1;
      }
  }  /* PseudoColor or DirectColor */

  if (gcflag == 0) {
    /* have a read-only situation (StaticColor or TrueColor), or,
       have a writable situation but couldn't get enough colorcells */
    
    /* small colormap portion */
    for (i=0;i<NCOLORS;i++) {
        if (!XParseColor(display,cmap,cnames[i],&(cdefs[i]))) {
      printf("\nYour server's color list has zero selection! %d read-only colors actually gotten.\n\n",i);
      exit(1);
      }

      if (!XAllocColor(display,cmap,&cdefs[i])) {
      if (!isPrivateCmap) {
        /* try a private color map */
        cmap = XCreateColormap(display, RootWindow(display,screen_n),
                         visual, AllocNone);
        XInstallColormap(display,cmap);
        isPrivateCmap = 1;
        printf("\nGot only %d read-only colors; trying private colormap.\n\n"
                 ,i);
        if (i > 0)
          XFreeColors(display,DefaultColormap(display,screen_n),
                        colors,i,plane_masks[0]);
        i = -1;
        continue;
        }
      else {
        printf("\nI am unable to allocate a color from your server. %d colors actually allocated.\n\n",i);
        if (isPrivateCmap) XUninstallColormap(display,cmap);
        exit(1);
        }
      }
      colors[i] = cdefs[i].pixel;
      }

    /* large colormap portion */
      if (isLargeCmap) {
        for (i=0; i<NCOLORS+1; i++) {
          getIntensitySet(cnames[i], intSet);
          for (j=0; j<N_INTS; j++) {
            /* break out one more level */
            if (j == -1) {
              i = -1;
              getIntensitySet(cnames[0], intSet);
              continue;
            }
            if (!XParseColor(display,cmap,intSet[j],
                             &(cdefs[NCOLORS+i*N_INTS+j]))) {
              printf("\nCouldn't find a color! %d read/write colors actually gotten.\n\n",(i+1)*NCOLORS+j);
              exit(1);
            }
            if (!XAllocColor(display, cmap, &cdefs[NCOLORS+i*N_INTS+j])) {
              if (!isPrivateCmap) {
                /* try a private colormap */
                cmap = XCreateColormap(display, RootWindow(display,screen_n),
                                       visual, AllocNone);
                XInstallColormap(display,cmap);
                isPrivateCmap = 1;
                printf("\nGot only %d read-only colors; ");
                printf("trying private colormap.\n\n",i);
                if ((i+1)*NCOLORS + j > 0)
                  XFreeColors(display,DefaultColormap(display,screen_n),
                              colors,NCOLORS+i*N_INTS+j,plane_masks[0]);
                j = -2;  /* see above */
                continue;
              }
              else {
                printf("\nI am unable to allocate a color from your server. ");
                printf("%d colors actually allocated.\n\n",NCOLORS+i*N_INTS+j);
                if (isPrivateCmap) XUninstallColormap(display,cmap);
                exit(1);
              }
            }
            colors[NCOLORS+i*N_INTS+j] = cdefs[NCOLORS+i*N_INTS+j].pixel;
          }
        }
      }

    gcflag = 1;
    if (isPrivateCmap) {
      /* find brightest and dimmest colors and set to black and white */
      for (i=0;i<NCOLORS;i++) {
      t = brightness(cdefs[i]);
      if (t > brightness(cdefs[brightestColor])) brightestColor = i;
      if (t < brightness(cdefs[dimmestColor])) dimmestColor = i;
      }
      white = cdefs[brightestColor].pixel, black = cdefs[dimmestColor].pixel;
      }
  }

  if (isPrivateCmap) XSetWindowColormap(display, XtWindow(pwidget), cmap);
  alloc_gc();
  free(cdefs);
  return;

}

void
alloc_gc()
{
  XGCValues gcvals;           /*for setting graphics context*/
  int i;

/*Set the graphics contexts for drawing - basic info like color and copymask*/
  gcvals.background = black, gcvals.foreground = white;
  gc = XCreateGC(display,canvas,GCBackground|GCForeground,&gcvals);
  gcCopy = XCreateGC(display,canvas,GCForeground,&gcvals);
  gcClear = XCreateGC(display,canvas,GCBackground,&gcvals);
  for (i=0;i<NCOLORS;i++) {
    if (gcflag) gcvals.foreground = colors[i];
    cgc[i] = XCreateGC(display,canvas,GCBackground|GCForeground,&gcvals);
    }
  if (isLargeCmap) {
    gcvals.foreground = colors[i];
    cgc[i] = XCreateGC(display,canvas,GCBackground|GCForeground,&gcvals);
  }
}

/* getIntensitySet() returns a set of N_INTS RGB color specifications
   representing a range of intensities of this hue; currently it assumes
   the hue has been normalized for brightness but makes range checks*/
void
getIntensitySet(char *hue, char intset[N_INTS][20])
{
  unsigned int    r, g, b,
            rval, gval, bval,
            i;
  unsigned int    largest, smallest;
  float           lfactor, sfactor, factor, inc;
  char            rstr[3], gstr[3], bstr[3];

  sscanf(hue,"rgb:%x/%x/%x", &r,&g,&b);
/*printf("Scanned %d %d %d\n",r,g,b);*/
  largest = max(max(r,g),b),  smallest = min(min(r,g),b);
  if (smallest == 0) smallest = 1;
  lfactor = 255.0/largest,  sfactor = 1.0/(2.0*smallest);
/*printf("Largest: %d, %f\tSmallest: %d, %f\n",largest,lfactor,smallest,sfactor);*/
  inc = (lfactor - sfactor) / (float)N_INTS;

  for (factor=sfactor, i=0; i<N_INTS; factor+=inc, i++) {
    rval=(float)factor*r, gval=(float)factor*g, bval=(float)factor*b;
    itoh(rval,rstr), itoh(gval,gstr), itoh(bval,bstr);
    sprintf(intset[i],"rgb:%s/%s/%s",rstr,gstr,bstr);
/*printf("%s\n",intset[i]);*/
  }

}


/* free_colors() frees up the color resources allocated by init_colors so
   that another set can be allocated (for colormap switching). */
void
free_colors()
{
  int i, ncolors;

  ncolors = isLargeCmap ? (NCOLORS+1) * N_INTS + NCOLORS : NCOLORS;

  XFreeGC(display, gc), XFreeGC(display, gcCopy), XFreeGC(display, gcClear);
  for (i=0;i<NCOLORS;i++) {
    XFreeGC(display, cgc[i]);
  }
    
  if (isPrivateCmap) {
    XSetWindowColormap(display, XtWindow(pwidget),
                       DefaultColormap(display,screen_n));
    XUninstallColormap(display,cmap);
    isPrivateCmap = 0;
  
  } else {
    XFreeColors(display, cmap, colors, ncolors,
                plane_masks[0]);
  }

  free(colors);
  gcflag=0;
}


int isMap(const struct dirent *entry);

/* build_colorfile_list() scans the colormap directory and builds the array
   'colorFileNames[] of all ".map" files. */
void
build_colorfile_list()
{
  char dirName[180];
  struct dirent **dirEntries;
  int i;

  nColorFiles = 0;
  
  strcpy(dirName,LIBDIR);
  if (dirName[strlen(dirName)-1] == '/')
    dirName[strlen(dirName)-1] = '\0';
  if ((nColorFiles = scandir(dirName, &dirEntries, isMap, alphasort)) == -1) {
    printf("**Warning: couldn't open colormap data directory \"%s\"\n",
           dirName);
    return;
  }
  
  if (nColorFiles > 0) {
    colorFileNames = (char **) malloc(nColorFiles * sizeof(char *));
    for (i=0; i<nColorFiles; i++) {
      colorFileNames[i] = strdup(dirEntries[i]->d_name);
      free(dirEntries[i]);
    }
    free(dirEntries);
  }
  printf("Found %d colormap files.\n", nColorFiles);
  return;
}

/* Return nonzero if is a colormap file matching pattern "*.map" */
int
isMap(const struct dirent *entry)
{
  const char *lastThree;

  if (strlen(entry->d_name) < 5) return 0;
  lastThree = entry->d_name + (strlen(entry->d_name) - 4);
  /* printf("Returning '%d' for \"%s\".\n",
     !strcmp(lastThree, ".map"), entry->d_name); */
  return !strcmp(lastThree, ".map");
}

Generated by  Doxygen 1.6.0   Back to index