Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

plot_x11.c

Go to the documentation of this file.
00001 #include "coxplot.h"
00002 
00003 /*****************************************************************************
00004   This software is copyrighted and owned by the Medical College of Wisconsin.
00005   See the file README.Copyright for details.
00006 ******************************************************************************/
00007 
00008 /*--------------------------------------------------------------------------
00009   Routines to render a memplot into an X11 window.
00010 ----------------------------------------------------------------------------*/
00011 
00012 static Display      * old_dpy = NULL ;
00013 static X11_colordef * old_cd  = NULL ;
00014 static Window         old_w   = (Window) 0 ;
00015 static GC             old_GC ;
00016 
00017 /*--------------------------------------------------------------------------
00018   If we have a new X11 display, will get its coloring scheme.
00019   Note the tacit assumption that all windows on the same
00020   display in the same program will use the same visual and colormap!
00021 ----------------------------------------------------------------------------*/
00022 
00023 static void setup_X11_plotting( Display * dpy , Window w )
00024 {
00025    XGCValues gcv;
00026 
00027    if( old_dpy == dpy ){ old_w = w ; return ; }
00028 
00029    FREE_X11_colordef(old_cd) ;
00030    old_cd = get_X11_colordef( dpy , w ) ;
00031 
00032    if( old_dpy != NULL ) XFreeGC( old_dpy , old_GC ) ;
00033    gcv.function   = GXcopy ;
00034    gcv.fill_style = FillSolid ; /* 21 Mar 2001 */
00035    old_GC         = XCreateGC( dpy , w , GCFunction|GCFillStyle , &gcv ) ;
00036 
00037    old_dpy = dpy ; old_w = getwin_from_XDBE(dpy,w) ;
00038    return ;
00039 }
00040 
00041 /*---------------------------------------------------------------------------
00042   Set the background color of a window.  This is necessary since
00043   neither memplot or plotpak contains the concept of a background color,
00044   only the concept of the line drawing color.
00045 -----------------------------------------------------------------------------*/
00046 
00047 void set_X11_background( Display * dpy , Window w ,
00048                          unsigned char rr , unsigned char gg , unsigned char bb )
00049 {
00050    unsigned long pix ;
00051 
00052    if( dpy == NULL || w == (Window) 0 ) return ;
00053 
00054    setup_X11_plotting( dpy , w ) ;
00055    pix = rgb_to_pixel( rr,gg,bb , old_cd ) ;
00056    XSetWindowBackground( dpy , getwin_from_XDBE(dpy,w) , pix ) ;
00057    return ;
00058 }
00059 
00060 /*--------------------------------------------------------------------------
00061    Set a sub-box within a window into which the next X11 plot should
00062    be scaled.  (0,0,0,0) args means use the whole window.  After
00063    each drawing (memplot_to_X11_sef), will be reset to the whole window
00064    anyway. -- 26 Feb 2001 -- RWCox
00065 ----------------------------------------------------------------------------*/
00066 
00067 static int box_xbot=0 , box_xtop=0 ,
00068            box_ybot=0 , box_ytop=0  ;
00069 
00070 void set_memplot_X11_box( int xbot, int ybot, int xtop, int ytop )
00071 {
00072    if( xbot < xtop && ybot < ytop ){
00073       box_xbot = xbot ; box_ybot = ybot ;
00074       box_xtop = xtop ; box_ytop = ytop ;
00075    } else {
00076       box_xbot = box_ybot = box_xtop = box_ytop = 0 ;
00077    }
00078 }
00079 
00080 /*------------------------------------------------------------------------*/
00081 
00082 /*------------------------------------------------------------------------*/
00083 /*! Get the layout of a window/pixmap.  [12 Mar 2002]
00084 --------------------------------------------------------------------------*/
00085 
00086 static void drawable_geom( Display *dpy , Drawable ddd ,
00087                            int *width , int *height , int *depth )
00088 {
00089    int xx,yy ;
00090    unsigned int ww,hh,bb,dd ;
00091    Window rr ;
00092 
00093    XGetGeometry( dpy,ddd , &rr,&xx,&yy,&ww,&hh,&bb,&dd ) ;
00094 
00095    if( width  != NULL ) *width  = ww ;
00096    if( height != NULL ) *height = hh ;
00097    if( depth  != NULL ) *depth  = dd ;
00098 }
00099 
00100 /*--------------------------------------------------------------------------
00101   Actually do the rendering.
00102   Plotting will start with line #start and go to #end-1.
00103   If end <= start, will do from #start to the last one in the plot.
00104   To do all lines, set start=end=0.
00105   The mask argument controls operations, and is the bitwise sum of
00106   these possibilities:
00107     MEMPLOT_FREE_ASPECT  = allow the aspect ratio to be free
00108     MEMPLOT_ERASE        = draw white over the lines
00109 ----------------------------------------------------------------------------*/
00110 
00111 #ifdef LMAX
00112 #undef LMAX
00113 #endif
00114 #define LMAX 1023  /* max number of line segments to draw at once */
00115 
00116 static XSegment xseg[LMAX] ;  /* line segment drawing buffer */
00117 static int      nseg = 0 ;    /* number in the buffer */
00118 
00119 static void draw_xseg(void) ; /* prototype for function below */
00120 
00121 void memplot_to_X11_sef( Display * dpy , Window w , MEM_plotdata * mp ,
00122                          int start , int end , int mask                )
00123 {
00124    int ii , nline , same ;
00125    float old_thick , old_color , new_color , new_thick ;
00126    float scal,xscal,yscal , xoff,yoff ;
00127    short x1,y1 , x2,y2 ;  /* X11 screen coords are shorts */
00128    int skip ;
00129    int w_width, w_height, w_depth ;  /* 12 Mar 2002 */
00130    XGCValues gcv ;
00131 
00132    int freee = (mask & MEMPLOT_FREE_ASPECT) != 0 ;  /* 16 Nov 2001 */
00133    int erase = (mask & MEMPLOT_ERASE      ) != 0 ;
00134 
00135    /*--- check for madness ---*/
00136 
00137    if( dpy == NULL || w == (Window) 0 || mp == NULL ) return ;
00138    if( start < 0 ) start = 0 ;
00139 
00140    nline = MEMPLOT_NLINE(mp) ;
00141    if( nline < 1 || start >= nline ) return ;
00142 
00143    if( end <= start || end > nline ) end = nline ;
00144 
00145    /*-- if we have a new X11 Display, get its coloring
00146         (note the tacit assumption that all windows on the same
00147          display in the same program will use the same visual and colormap!) --*/
00148 
00149    setup_X11_plotting( dpy , w ) ;
00150 
00151    /*-- 12 Mar 2002: replace use of XGetWindowAttributes with XGetGeometry --*/
00152 
00153    drawable_geom( dpy, getwin_from_XDBE(dpy,w), &w_width,&w_height,&w_depth ) ;
00154 
00155    if( w_depth != old_cd->depth ) return ;  /* this is bad */
00156 
00157    /*--- compute scaling from memplot objective
00158          coordinates to X11 window coordinates, maintaining aspect ---*/
00159 
00160    if( box_xbot >= box_xtop || box_ybot >= box_ytop ){
00161 
00162       xscal = (w_width -0.001) / mp->aspect ; /* aspect = x-axis objective size */
00163       yscal = (w_height-0.001) / 1.0 ;        /* 1.0    = y-axis objective size */
00164       xoff  = yoff = 0.0 ;
00165 
00166    } else {  /* 26 Feb 2001: scale to a given sub-box in the window */
00167 
00168       xscal = box_xtop - box_xbot ;
00169       yscal = box_ytop - box_ybot ;
00170       xoff  = box_xbot + 0.0      ;
00171       yoff  = box_ybot + 0.0      ;
00172    }
00173 
00174    if( !freee ){                           /* no aspect freedom ==> */
00175       if( yscal < xscal ) xscal = yscal ;  /* use smaller scaling   */
00176       else                yscal = xscal ;
00177    }
00178    scal = sqrt(fabs(xscal*yscal)) ;
00179 
00180    old_color = -1.0 ;            /* these don't occur naturally */
00181    old_thick = -THCODE_INVALID ;
00182 
00183    if( erase ){                  /* 16 Nov 2001: erase to white */
00184       float rr=1.0 , gg=1.0 , bb=1.0 ;
00185       unsigned long pix ;
00186       pix = rgb_to_pixel( ZO_TO_TFS(rr), ZO_TO_TFS(gg), ZO_TO_TFS(bb), old_cd ) ;
00187       XSetForeground( old_dpy , old_GC , pix ) ;
00188    }
00189 
00190    /* 23 Feb 2003: initialize line width to 0 for each entry
00191                    (in case a special case [box,circle, ...] comes first */
00192 
00193    gcv.line_width = 0 ;
00194    gcv.join_style = JoinBevel ;
00195    XChangeGC( old_dpy , old_GC , GCLineWidth | GCJoinStyle , &gcv ) ;
00196 
00197    /*--- loop over lines, scale and plot ---*/
00198 
00199    for( ii=start ; ii < end ; ii++ ){
00200 
00201       skip = 0 ;
00202 
00203       /* check if need to change color or thickness of line */
00204 
00205       new_color = MEMPLOT_COL(mp,ii) ;
00206       if( !erase && new_color != old_color ){
00207          float rr=COL_TO_RRR(new_color) ,
00208                gg=COL_TO_GGG(new_color) , bb=COL_TO_BBB(new_color) ;
00209          unsigned long pix ;
00210 
00211 #if 0
00212 fprintf(stderr,"Changing color to %f %f %f\n",rr,gg,bb) ;
00213 #endif
00214 
00215          draw_xseg() ; /* must draw before changing GC */
00216 
00217          pix = rgb_to_pixel( ZO_TO_TFS(rr), ZO_TO_TFS(gg), ZO_TO_TFS(bb), old_cd ) ;
00218          XSetForeground( old_dpy , old_GC , pix ) ;
00219          old_color = new_color ;
00220       }
00221 
00222       new_thick = MEMPLOT_TH(mp,ii) ;
00223       if( new_thick < 0.0 ){               /* 21 Mar 2001: negative thickness codes */
00224          int thc = (int)(-new_thick) ;
00225          switch( thc ){  /* default is to do nothing (e.g., thd = THCODE_INVALID) */
00226 
00227             case THCODE_RECT:{        /* rectangle */
00228                short xb,yb , xt,yt ;
00229                unsigned short w,h ;
00230                x1 = (short)( xoff + xscal * MEMPLOT_X1(mp,ii)         ) ;
00231                x2 = (short)( xoff + xscal * MEMPLOT_X2(mp,ii)         ) ;
00232                y1 = (short)( yoff + yscal * (1.0 - MEMPLOT_Y1(mp,ii)) ) ;
00233                y2 = (short)( yoff + yscal * (1.0 - MEMPLOT_Y2(mp,ii)) ) ;
00234                if( x1 < x2 ){ xb=x1; xt=x2; } else { xb=x2; xt=x1; }
00235                if( y1 < y2 ){ yb=y1; yt=y2; } else { yb=y2; yt=y1; }
00236                w = xt-xb ; h = yt-yb ;
00237                if( w || h )
00238 #if 0
00239                  XFillRectangle( old_dpy,old_w,old_GC , xb,yb,w,h ) ;
00240 #else
00241                  XDrawRectangle( old_dpy,old_w,old_GC , xb,yb,w,h ) ;
00242 #endif
00243                else
00244                  XDrawPoint( old_dpy,old_w,old_GC , xb,yb ) ;
00245                skip = 1 ;
00246             }
00247             break ;
00248 
00249             case THCODE_CIRC:{        /* circle */
00250                int xcor,ycor , xcen,ycen , xrad,yrad ;
00251                unsigned int ww, hh ;
00252                xcen = (int)(xoff + xscal * MEMPLOT_X1(mp,ii)         );
00253                ycen = (int)(yoff + yscal * (1.0 - MEMPLOT_Y1(mp,ii)) );
00254                xrad = (int)(       xscal * MEMPLOT_X2(mp,ii)         );
00255                yrad = (int)(       yscal * MEMPLOT_X2(mp,ii)         );
00256                xcor = xcen - xrad ; ww = 2*xrad ;
00257                ycor = ycen - yrad ; hh = 2*yrad ;
00258                if( ww || hh )
00259                  XDrawArc( old_dpy,old_w,old_GC , xcor,ycor,ww,hh , 0,360*64 ) ;
00260                else
00261                  XDrawPoint( old_dpy,old_w,old_GC , xcor,ycor ) ;
00262                skip = 1 ;
00263             }
00264             break ;
00265          }
00266 
00267       } else if( new_thick != old_thick ){ /* normal case: change line thickness */
00268          int lw = scal * new_thick ;
00269          if( lw < 0 ) lw = 0 ;
00270 #if 0
00271 fprintf(stderr,"Changing thickness: old=%f  new=%f\n",old_thick,new_thick) ;
00272 #endif
00273 
00274          draw_xseg() ; /* must draw before changing GC */
00275 
00276          gcv.line_width = lw ;
00277          gcv.join_style = JoinBevel ;
00278          XChangeGC( old_dpy , old_GC , GCLineWidth | GCJoinStyle , &gcv ) ;
00279          old_thick = new_thick ;
00280       }
00281 
00282       if( nseg == LMAX ) draw_xseg() ;  /* draw if list is full */
00283 
00284       /* scale coords to X11 shorts (also see zzphph.f) */
00285       /* 26 Feb 2001: xoff,yoff are now variables, instead of 0.499 */
00286 
00287       if( !skip ){
00288         x1 = (short)( xoff + xscal * MEMPLOT_X1(mp,ii)         ) ;
00289         x2 = (short)( xoff + xscal * MEMPLOT_X2(mp,ii)         ) ;
00290         y1 = (short)( yoff + yscal * (1.0 - MEMPLOT_Y1(mp,ii)) ) ;
00291         y2 = (short)( yoff + yscal * (1.0 - MEMPLOT_Y2(mp,ii)) ) ;
00292 
00293       /* add to segment list */
00294 
00295         xseg[nseg].x1 = x1 ; xseg[nseg].y1 = y1 ;
00296         xseg[nseg].x2 = x2 ; xseg[nseg].y2 = y2 ; nseg++ ;
00297       }
00298    }
00299 
00300    /*-- process any segments left over --*/
00301 
00302    draw_xseg() ;
00303    set_memplot_X11_box(0,0,0,0) ; /* 26 Feb 2001: clear box */
00304    return ;
00305 }
00306 
00307 /*---------------- draw the line segments stored in xseg -----------------*/
00308 
00309 static void draw_xseg(void)
00310 {
00311    int jbot,jtop , ii,nj ;
00312    XPoint xpt[LMAX+1] ;
00313 
00314    if( nseg <= 0 ) return ;  /* nothing to do */
00315 
00316 #if 0
00317 fprintf(stderr,"draw_xseg: %d segments input.\n",nseg) ;
00318 for( ii=0 ; ii < nseg ; ii++ )
00319   fprintf(stderr,"  %4d: x1=%4d  y1=%4d   x2=%4d  y2=%4d\n",
00320           ii , xseg[ii].x1 , xseg[ii].y1 , xseg[ii].x2 , xseg[ii].y2 ) ;
00321 #endif
00322 
00323    jbot = 0 ;
00324    while( jbot < nseg ){  /* scan the line segment list starting at jbot */
00325 
00326       /* scan forward to find a set of connected lines */
00327 
00328       jtop = jbot+1 ;
00329       while( jtop < nseg ){    /* 23 Feb 2003: more complex connection tests */
00330 
00331         if(    xseg[jtop-1].x2 == xseg[jtop].x1
00332             && xseg[jtop-1].y2 == xseg[jtop].y1 ){ jtop++; continue; } /* OK */
00333 
00334         if(    xseg[jtop-1].x2 == xseg[jtop].x2
00335             && xseg[jtop-1].y2 == xseg[jtop].y2 ){          /* OK if flipped */
00336 
00337           ii = xseg[jtop].x2; xseg[jtop].x2 = xseg[jtop].x1; xseg[jtop].x1 = ii;
00338           ii = xseg[jtop].y2; xseg[jtop].y2 = xseg[jtop].y1; xseg[jtop].y1 = ii;
00339           jtop++; continue;
00340         }
00341 
00342         break ;    /* get to here ==> jtop-1 and jtop segments not connected */
00343       }
00344 
00345       /* jbot .. jtop-1 are connected;
00346          if this is more than one line, draw them together
00347          so that the X11 server will properly join the lines */
00348 
00349       nj = jtop - jbot ;
00350       if( nj > 1 ){
00351          xpt[0].x = xseg[jbot].x1 ; xpt[0].y = xseg[jbot].y1 ;
00352          for( ii=0 ; ii < nj ; ii++ ){
00353             xpt[ii+1].x = xseg[jbot+ii].x2 ; xpt[ii+1].y = xseg[jbot+ii].y2 ;
00354          }
00355          XDrawLines( old_dpy,old_w,old_GC , xpt,nj+1 , CoordModeOrigin ) ;
00356 
00357 #if 0
00358 fprintf(stderr,"draw_xseg: XDrawLines for %d\n",nj) ;
00359 #endif
00360 
00361          jbot = jtop ; continue ;  /* start the while loop over */
00362       }
00363 
00364       /* jbot is not connected to jbot+1;
00365          scan forward to find a set of disconnected lines */
00366 
00367       while( jtop < nseg                            &&
00368              ( xseg[jtop-1].x2 != xseg[jtop].x1 ||
00369                xseg[jtop-1].y2 != xseg[jtop].y1   ) &&
00370              ( xseg[jtop-1].x2 != xseg[jtop].x2 ||
00371                xseg[jtop-1].y2 != xseg[jtop].y2   )    ) jtop++ ;
00372 
00373       /* jbot .. jtop-1 are disconnected, so draw them as such */
00374 
00375       XDrawSegments( old_dpy,old_w,old_GC , xseg+jbot , jtop-jbot ) ;
00376 
00377 #if 0
00378 fprintf(stderr,"draw_xseg: XDrawSegments for %d\n",jtop-jbot) ;
00379 #endif
00380 
00381       jbot = jtop ; continue ;  /* start the while loop over */
00382    }
00383 
00384    nseg = 0 ; return ;
00385 }
00386 
00387 /*------------------------------------------------------------------------
00388   Returns position of highest set bit in 'ul' as an integer (0-31),
00389   or returns -1 if no bit is set.
00390 --------------------------------------------------------------------------*/
00391 
00392 static int highbit(unsigned long ul)
00393 {
00394   int i;  unsigned long hb;
00395 
00396   hb = 0x80;  hb = hb << 24;   /* hb = 0x80000000UL */
00397   for (i=31; ((ul & hb) == 0) && i>=0;  i--, ul<<=1);
00398   return i;
00399 }
00400 
00401 /*-------------------------------------------------------------------------
00402   Return an X11 pixel value that represents the given color.
00403   Inputs rr,gg,bb are from 0 to 255.  Output is an unsigned long,
00404   the standard X11 format for specifying colors to a GC.
00405   Note that if the result is to be put into an XImage, further
00406   bit manipulation must be done on the result.
00407 ---------------------------------------------------------------------------*/
00408 
00409 unsigned long rgb_to_pixel( unsigned char rr , unsigned char gg ,
00410                             unsigned char bb , X11_colordef * cd )
00411 {
00412    /*--- TrueColor case: make color by appropriate bit twiddling ---*/
00413 
00414    if( cd->classKRH == TrueColor ){
00415       unsigned long r , g , b , rgb ;
00416 
00417       r = (cd->rrshift<0) ? (rr<<(-cd->rrshift))
00418                           : (rr>>cd->rrshift)   ; r = r & cd->rrmask ;
00419 
00420       g = (cd->ggshift<0) ? (gg<<(-cd->ggshift))
00421                           : (gg>>cd->ggshift)   ; g = g & cd->ggmask ;
00422 
00423       b = (cd->bbshift<0) ? (bb<<(-cd->bbshift))
00424                           : (bb>>cd->bbshift)   ; b = b & cd->bbmask ;
00425 
00426       rgb = r | g | b ;  /* assemble color from components */
00427       return rgb ;
00428    }
00429 
00430    /*--- PseudoColor case: find closest match in colormap.
00431          Red, green, and blue are weighted according
00432          to their importance to the human visual system. ---*/
00433 
00434 #define RW 2  /* the weights alluded to above */
00435 #define GW 4
00436 #define BW 1
00437 
00438    if( cd->classKRH == PseudoColor ){
00439       int ii , rdif,gdif,bdif,dif , ibest,dbest ;
00440 
00441       rdif = cd->rr[0] - rr ;
00442       gdif = cd->gg[0] - gg ;
00443       bdif = cd->bb[0] - bb ; dif = RW*abs(rdif)+GW*abs(gdif)+BW*abs(bdif) ;
00444       if( dif == 0 ) return 0 ;
00445 
00446       ibest = 0 ; dbest = dif ;
00447       for( ii=1 ; ii < cd->ncolors ; ii++ ){
00448          rdif = cd->rr[ii] - rr ;
00449          gdif = cd->gg[ii] - gg ;
00450          bdif = cd->bb[ii] - bb ; dif = RW*abs(rdif)+GW*abs(gdif)+BW*abs(bdif) ;
00451          if( dif == 0 ) return ii ;
00452          if( dif < dbest ){ ibest = ii ; dbest = dif ; }
00453       }
00454       return ibest ;
00455    }
00456 
00457    /*--- Illegal case! ---*/
00458 
00459    return 0 ;  /* always valid */
00460 }
00461 
00462 /*-------------------------------------------------------------------------*/
00463 
00464 static volatile int xwasbad ;  /* 13 Mar 2002 */
00465 
00466 typedef int (*xhandler)(Display *, XErrorEvent *) ;
00467 
00468 static int qhandler( Display *dpy , XErrorEvent *xev )
00469 {
00470    xwasbad = 1 ; return 0 ;
00471 }
00472 
00473 /*-------------------------------------------------------------------------
00474    Return a structure that defines the colors available for the given
00475    window.  This only works for PseudoColor and TrueColor visuals.
00476    Returns NULL if an error occurs.
00477 ---------------------------------------------------------------------------*/
00478 
00479 X11_colordef * get_X11_colordef( Display * display , Window w )
00480 {
00481    Status sss ;
00482    XWindowAttributes xwat ;
00483    XColor * xcol ;
00484    XVisualInfo vinfo , * vin ;
00485    X11_colordef * cd ;          /* will be the output */
00486    int count , ii ;
00487    xhandler old_handler ;       /* 13 Mar 2002 */
00488 
00489    /*--- sanity check ---*/
00490 
00491    if( display == NULL || w == (Window) 0 ) return NULL ;
00492 
00493    /*--- get window attributes ---*/
00494 
00495    /* 13 Mar 2002: deal with the error that occurs
00496                    when the Window is really a Pixmap */
00497 
00498    xwat.depth = 0 ;
00499    old_handler = XSetErrorHandler(qhandler) ; xwasbad = 0 ;
00500 
00501    XGetWindowAttributes( display, getwin_from_XDBE(display,w), &xwat ) ;
00502 
00503    (void) XSetErrorHandler(old_handler) ;
00504 
00505    if( xwasbad ){
00506       int xx,yy ; unsigned int ww,hh,bb,dd ; Window rr ;
00507       XGetGeometry( display,w , &rr,&xx,&yy,&ww,&hh,&bb,&dd ) ;
00508       XGetWindowAttributes( display, rr , &xwat ) ;
00509    }
00510    if( xwat.depth == 0 ) return NULL ;   /* bad news */
00511 
00512    /*--- get information about the window's Visual ---*/
00513 
00514    vinfo.visualid = XVisualIDFromVisual(xwat.visual) ;
00515    vin = XGetVisualInfo( display , VisualIDMask , &vinfo , &count ) ;
00516    if( count == 0 || vin == NULL ) return NULL ;
00517 
00518    /*--- PseudoColor case ---*/
00519 #if defined(__cplusplus) || defined(c_plusplus)
00520    if( vin->c_class == PseudoColor ){
00521 #else
00522    if( vin->class == PseudoColor ){
00523 #endif
00524       int iz ;
00525 
00526       /* create output */
00527 
00528       cd = (X11_colordef *) malloc( sizeof(X11_colordef) ) ;
00529       cd->classKRH = PseudoColor ;
00530       cd->depth = vin->depth ;
00531 
00532       /* get all the colors in the colormap */
00533 
00534       count = vin->colormap_size ;
00535       xcol  = (XColor *) malloc( sizeof(XColor) * count ) ;
00536       for( ii=0 ; ii < count ; ii++ ) xcol[ii].pixel = ii ;
00537 
00538       XQueryColors( display , xwat.colormap , xcol , count ) ;
00539 
00540       /* store them in the output, truncated to 8 bits */
00541 
00542       cd->ncolors = count ;
00543       cd->rr      = (unsigned char *) malloc( count ) ;
00544       cd->gg      = (unsigned char *) malloc( count ) ;
00545       cd->bb      = (unsigned char *) malloc( count ) ;
00546 
00547       for( ii=0 ; ii < count ; ii++ ){
00548          cd->rr[ii] = xcol[ii].red   >> 8 ;
00549          cd->gg[ii] = xcol[ii].green >> 8 ;
00550          cd->bb[ii] = xcol[ii].blue  >> 8 ;
00551       }
00552 
00553       /* find first all zero color; discard others at end of colormap */
00554 
00555       for( iz=0 ; iz < count ; iz++ )
00556          if( cd->rr[iz] == 0 && cd->gg[iz] == 0 && cd->bb[iz] == 0 ) break ;
00557 
00558       if( iz < count-1 ){  /* if found one before the end */
00559 
00560          for( ii=count-1 ; ii > iz ; ii-- )  /* scan backwards */
00561             if( cd->rr[ii] != 0 || cd->gg[ii] != 0 || cd->bb[ii] != 0 ) break ;
00562 
00563          count = ii+1 ;  /* number of colors left */
00564 
00565          if( count == 1 ){ /* colormap is all black?! */
00566             free(xcol) ; XFree(vin) ; FREE_X11_colordef(cd) ; return NULL ;
00567          }
00568 
00569          cd->ncolors = count ;
00570       }
00571 
00572       free(xcol) ; XFree(vin) ; return cd ;
00573    }
00574 
00575    /*--- TrueColor case ---*/
00576 #if defined(__cplusplus) || defined(c_plusplus)
00577    if( vin->c_class == TrueColor ){
00578 #else
00579    if( vin->class == TrueColor ){
00580 #endif
00581 
00582       /* create output */
00583 
00584       cd = (X11_colordef *) malloc( sizeof(X11_colordef) ) ;
00585       cd->classKRH = TrueColor ;
00586       cd->depth = vin->depth ;
00587 
00588       cd->rrmask  = vin->red_mask ;            /* bit masks for color  */
00589       cd->ggmask  = vin->green_mask ;          /* storage inside pixel */
00590       cd->bbmask  = vin->blue_mask ;
00591       cd->rrshift = 7 - highbit(cd->rrmask) ;  /* shift puts high bit of  */
00592       cd->ggshift = 7 - highbit(cd->ggmask) ;  /* a color byte into place */
00593       cd->bbshift = 7 - highbit(cd->bbmask) ;  /* +shift == >> ; - == <<  */
00594 
00595       cd->rr = cd->gg = cd->bb = NULL ;        /* not used */
00596 
00597       XFree(vin) ; return cd ;
00598    }
00599 
00600    /*--- Illegal Visual class! ---*/
00601 
00602    XFree(vin) ; return NULL ;
00603 }
00604 
00605 #ifdef HAVE_XDBE
00606 /*----------------------------------  24 Jan 1999  -------------------------------*/
00607 void init_XDBE( Display * dpy )
00608 {
00609    int sss , ii , jj ;
00610    char * ec ;
00611 
00612    if( use_xdbe >= 0 ) return ;
00613 
00614    ec = getenv("AFNI_NO_XDBE") ;  /* 28 Jan 2000 - add this environment variable */
00615    if( ec != NULL && (ec[0]=='Y' || ec[0]=='y') ){
00616       use_xdbe = 0 ;
00617    } else {
00618       sss = (int) XdbeQueryExtension( dpy , &ii , &jj ) ;
00619       use_xdbe = (sss != 0 ) ;
00620    }
00621    return ;
00622 }
00623 
00624 Window getwin_from_XDBE( Display * dpy , Drawable w )
00625 {
00626    XdbeBackBufferAttributes * bat ;
00627    Window bw ;
00628 
00629    if( w == (Window) 0 || use_xdbe <= 0 ) return w ;
00630 
00631    bat = XdbeGetBackBufferAttributes( dpy , w ) ;
00632    bw  = bat->window ; XFree(bat) ;
00633    if( bw == (Window) 0 ) bw = w ;
00634    return bw ;
00635 }
00636 #endif  /* HAVE_XDBE */
 

Powered by Plone

This site conforms to the following standards: