asvisual.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001,2000,1999 Sasha Vasko <sasha at aftercode.net>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 #ifdef _WIN32
00020 #include "win32/config.h"
00021 #else
00022 #include "config.h"
00023 #endif
00024 
00025 #define LOCAL_DEBUG
00026 #undef DEBUG_SL2XIMAGE
00027 #include <string.h>
00028 #ifdef HAVE_UNISTD_H
00029 #include <unistd.h>
00030 #endif
00031 #ifdef HAVE_STDLIB_H
00032 #include <stdlib.h>
00033 #endif
00034 #ifdef HAVE_STDARG_H
00035 #include <stdarg.h>
00036 #endif
00037  
00038 #ifdef _WIN32
00039 # include "win32/afterbase.h"
00040 #else
00041 # include "afterbase.h"
00042 #endif
00043 #include "asvisual.h"
00044 #include "scanline.h"
00045 
00046 #if defined(XSHMIMAGE) && !defined(X_DISPLAY_MISSING) 
00047 # include <sys/ipc.h>
00048 # include <sys/shm.h>
00049 # include <X11/extensions/XShm.h>
00050 #else
00051 # undef XSHMIMAGE
00052 #endif
00053 
00054 #if defined(HAVE_GLX) && !defined(X_DISPLAY_MISSING) 
00055 # include <GL/gl.h>
00056 # include <GL/glx.h>
00057 #else
00058 # undef HAVE_GLX
00059 #endif
00060 
00061 
00062 
00063 #ifndef X_DISPLAY_MISSING
00064 static int  get_shifts (unsigned long mask);
00065 static int  get_bits (unsigned long mask);
00066 
00067 void _XInitImageFuncPtrs(XImage*);
00068 
00069 int
00070 asvisual_empty_XErrorHandler (Display * dpy, XErrorEvent * event)
00071 {
00072     return 0;
00073 }
00074 /***************************************************************************/
00075 #if defined(LOCAL_DEBUG) && !defined(NO_DEBUG_OUTPUT)
00076 Status
00077 debug_AllocColor( const char *file, int line, ASVisual *asv, Colormap cmap, XColor *pxcol )
00078 {
00079         Status sret ;
00080         sret = XAllocColor( asv->dpy, cmap, pxcol );
00081         show_progress( " XAllocColor in %s:%d has %s -> cmap = %lX, pixel = %lu(%8.8lX), color = 0x%4.4X, 0x%4.4X, 0x%4.4X",
00082                                    file, line, (sret==0)?"failed":"succeeded", (long)cmap, (unsigned long)(pxcol->pixel), (unsigned long)(pxcol->pixel), pxcol->red, pxcol->green, pxcol->blue );
00083         return sret;
00084 }
00085 #define ASV_ALLOC_COLOR(asv,cmap,pxcol)  debug_AllocColor(__FILE__, __LINE__, (asv),(cmap),(pxcol))
00086 #else
00087 #define ASV_ALLOC_COLOR(asv,cmap,pxcol)  XAllocColor((asv)->dpy,(cmap),(pxcol))
00088 #endif
00089 
00090 #else
00091 #define ASV_ALLOC_COLOR(asv,cmap,pxcol)   0
00092 #endif   /* ndef X_DISPLAY_MISSING */
00093 
00094 /**********************************************************************/
00095 /* returns the maximum number of true colors between a and b          */
00096 long
00097 ARGB32_manhattan_distance (long a, long b)
00098 {
00099         register int d = (int)ARGB32_RED8(a)   - (int)ARGB32_RED8(b);
00100         register int t = (d < 0 )? -d : d ;
00101 
00102         d = (int)ARGB32_GREEN8(a) - (int)ARGB32_GREEN8(b);
00103         t += (d < 0)? -d : d ;
00104         d = (int)ARGB32_BLUE8(a)  - (int)ARGB32_BLUE8(b);
00105         return (t+((d < 0)? -d : d)) ;
00106 }
00107 
00108 
00109 
00110 /***************************************************************************
00111  * ASVisual :
00112  * encoding/decoding/querying/setup
00113  ***************************************************************************/
00114 int get_bits_per_pixel(Display *dpy, int depth)
00115 {
00116 #if 0
00117 #ifndef X_DISPLAY_MISSING
00118         register ScreenFormat *fmt = dpy->pixmap_format;
00119         register int i;
00120 
00121         for (i = dpy->nformats + 1; --i; ++fmt)
00122                 if (fmt->depth == depth)
00123                         return(fmt->bits_per_pixel);
00124 #endif
00125 #endif
00126         if (depth <= 4)
00127             return 4;
00128         if (depth <= 8)
00129             return 8;
00130         if (depth <= 16)
00131             return 16;
00132         return 32;
00133  }
00134 
00135 /* ********************* ASVisual ************************************/
00136 ASVisual *_set_default_asvisual( ASVisual *new_v );
00137 
00138 #ifndef X_DISPLAY_MISSING
00139 static XColor black_xcol = { 0, 0x0000, 0x0000, 0x0000, DoRed|DoGreen|DoBlue };
00140 static XColor white_xcol = { 0, 0xFFFF, 0xFFFF, 0xFFFF, DoRed|DoGreen|DoBlue };
00141 
00142 static void find_useable_visual( ASVisual *asv, Display *dpy, int screen,
00143                                      Window root, XVisualInfo *list, int nitems,
00144                                                                  XSetWindowAttributes *attr )
00145 {
00146         int k ;
00147         int (*oldXErrorHandler) (Display *, XErrorEvent *) =
00148                                                 XSetErrorHandler (asvisual_empty_XErrorHandler);
00149         Colormap orig_cmap = attr->colormap ;
00150 
00151         for( k = 0  ; k < nitems ; k++ )
00152         {
00153                 Window       w = None, wjunk;
00154                 unsigned int width, height, ujunk ;
00155                 int          junk;
00156                 /* try and use default colormap when possible : */
00157                 if( orig_cmap == None )
00158                 {
00159                         if( list[k].visual == DefaultVisual( dpy, (screen) ) )
00160                         {
00161                                 attr->colormap = DefaultColormap( dpy, screen );
00162                                 LOCAL_DEBUG_OUT( "Using Default colormap %lX", attr->colormap );
00163                         }else
00164                         {
00165                                 attr->colormap = XCreateColormap( dpy, root, list[k].visual, AllocNone);
00166                                 LOCAL_DEBUG_OUT( "DefaultVisual is %p, while ours is %p, so Created new colormap %lX", DefaultVisual( dpy, (screen) ), list[k].visual, attr->colormap );
00167                         }
00168                 }
00169                 ASV_ALLOC_COLOR( asv, attr->colormap, &black_xcol );
00170                 ASV_ALLOC_COLOR( asv, attr->colormap, &white_xcol );
00171                 attr->border_pixel = black_xcol.pixel ;
00172 
00173 /*fprintf( stderr, "checking out visual ID %d, class %d, depth = %d mask = %X,%X,%X\n", list[k].visualid, list[k].class, list[k].depth, list[k].red_mask, list[k].green_mask, list[k].blue_mask         );*/
00174                 w = XCreateWindow (dpy, root, -10, -10, 10, 10, 0, list[k].depth, CopyFromParent, list[k].visual, CWColormap|CWBorderPixel, attr );
00175                 if( w != None && XGetGeometry (dpy, w, &wjunk, &junk, &junk, &width, &height, &ujunk, &ujunk))
00176                 {
00177                         /* don't really care what's in it since we do not use it anyways : */
00178                         asv->visual_info = list[k] ;
00179                         XDestroyWindow( dpy, w );
00180                         asv->colormap = attr->colormap ;
00181                         asv->own_colormap = (attr->colormap != DefaultColormap( dpy, screen ));
00182                         asv->white_pixel = white_xcol.pixel ;
00183                         asv->black_pixel = black_xcol.pixel ;
00184                         break;
00185                 }
00186                 if( orig_cmap == None )
00187                 {
00188                         if( attr->colormap != DefaultColormap( dpy, screen ))
00189                                 XFreeColormap( dpy, attr->colormap );
00190                         attr->colormap = None ;
00191                 }
00192         }
00193         XSetErrorHandler(oldXErrorHandler);
00194 }
00195 #endif
00196 
00197 /* Main procedure finding and querying the best visual */
00198 Bool
00199 query_screen_visual_id( ASVisual *asv, Display *dpy, int screen, Window root, int default_depth, VisualID visual_id, Colormap cmap )
00200 {
00201 #ifndef X_DISPLAY_MISSING
00202         int nitems = 0 ;
00203         /* first  - attempt locating 24bpp TrueColor or DirectColor RGB or BGR visuals as the best cases : */
00204         /* second - attempt locating 32bpp TrueColor or DirectColor RGB or BGR visuals as the next best cases : */
00205         /* third  - lesser but still capable 16bpp 565 RGB or BGR modes : */
00206         /* forth  - even more lesser 15bpp 555 RGB or BGR modes : */
00207         /* nothing nice has been found - use whatever X has to offer us as a default :( */
00208         int i ;
00209 
00210         XVisualInfo *list = NULL;
00211         XSetWindowAttributes attr ;
00212         static XVisualInfo templates[] =
00213                 /* Visual, visualid, screen, depth, class      , red_mask, green_mask, blue_mask, colormap_size, bits_per_rgb */
00214                 {{ NULL  , 0       , 0     , 24   , TrueColor  , 0xFF0000, 0x00FF00  , 0x0000FF , 0            , 0 },
00215                  { NULL  , 0       , 0     , 24   , TrueColor  , 0x0000FF, 0x00FF00  , 0xFF0000 , 0            , 0 },
00216                  { NULL  , 0       , 0     , 24   , TrueColor  , 0x0     , 0x0       , 0x0      , 0            , 0 },
00217                  { NULL  , 0       , 0     , 32   , TrueColor  , 0xFF0000, 0x00FF00  , 0x0000FF , 0            , 0 },
00218                  { NULL  , 0       , 0     , 32   , TrueColor  , 0x0000FF, 0x00FF00  , 0xFF0000 , 0            , 0 },
00219                  { NULL  , 0       , 0     , 32   , TrueColor  , 0x0     , 0x0       , 0x0      , 0            , 0 },
00220                  { NULL  , 0       , 0     , 16   , TrueColor  , 0xF800  , 0x07E0    , 0x001F   , 0            , 0 },
00221                  { NULL  , 0       , 0     , 16   , TrueColor  , 0x001F  , 0x07E0    , 0xF800   , 0            , 0 },
00222                  /* big endian or MBR_First modes : */
00223                  { NULL  , 0       , 0     , 16   , TrueColor  , 0x0     , 0xE007    , 0x0      , 0            , 0 },
00224                  /* some misrepresented modes that really are 15bpp : */
00225                  { NULL  , 0       , 0     , 16   , TrueColor  , 0x7C00  , 0x03E0    , 0x001F   , 0            , 0 },
00226                  { NULL  , 0       , 0     , 16   , TrueColor  , 0x001F  , 0x03E0    , 0x7C00   , 0            , 0 },
00227                  { NULL  , 0       , 0     , 16   , TrueColor  , 0x0     , 0xE003    , 0x0      , 0            , 0 },
00228                  { NULL  , 0       , 0     , 15   , TrueColor  , 0x7C00  , 0x03E0    , 0x001F   , 0            , 0 },
00229                  { NULL  , 0       , 0     , 15   , TrueColor  , 0x001F  , 0x03E0    , 0x7C00   , 0            , 0 },
00230                  { NULL  , 0       , 0     , 15   , TrueColor  , 0x0     , 0xE003    , 0x0      , 0            , 0 },
00231 /* no suitable TrueColorMode found - now do the same thing to DirectColor :*/
00232                  { NULL  , 0       , 0     , 24   , DirectColor, 0xFF0000, 0x00FF00  , 0x0000FF , 0            , 0 },
00233                  { NULL  , 0       , 0     , 24   , DirectColor, 0x0000FF, 0x00FF00  , 0xFF0000 , 0            , 0 },
00234                  { NULL  , 0       , 0     , 24   , DirectColor, 0x0     , 0x0       , 0x0      , 0            , 0 },
00235                  { NULL  , 0       , 0     , 32   , DirectColor, 0xFF0000, 0x00FF00  , 0x0000FF , 0            , 0 },
00236                  { NULL  , 0       , 0     , 32   , DirectColor, 0x0000FF, 0x00FF00  , 0xFF0000 , 0            , 0 },
00237                  { NULL  , 0       , 0     , 32   , DirectColor, 0x0     , 0x0       , 0x0      , 0            , 0 },
00238                  { NULL  , 0       , 0     , 16   , DirectColor, 0xF800  , 0x07E0    , 0x001F   , 0            , 0 },
00239                  { NULL  , 0       , 0     , 16   , DirectColor, 0x001F  , 0x07E0    , 0xF800   , 0            , 0 },
00240                  { NULL  , 0       , 0     , 16   , DirectColor, 0x0     , 0xE007    , 0x0      , 0            , 0 },
00241                  { NULL  , 0       , 0     , 16   , DirectColor, 0x7C00  , 0x03E0    , 0x001F   , 0            , 0 },
00242                  { NULL  , 0       , 0     , 16   , DirectColor, 0x001F  , 0x03E0    , 0x7C00   , 0            , 0 },
00243                  { NULL  , 0       , 0     , 16   , DirectColor, 0x0     , 0xE003    , 0x0      , 0            , 0 },
00244                  { NULL  , 0       , 0     , 15   , DirectColor, 0x7C00  , 0x03E0    , 0x001F   , 0            , 0 },
00245                  { NULL  , 0       , 0     , 15   , DirectColor, 0x001F  , 0x03E0    , 0x7C00   , 0            , 0 },
00246                  { NULL  , 0       , 0     , 15   , DirectColor, 0x0     , 0xE003    , 0x0      , 0            , 0 },
00247                  { NULL  , 0       , 0     , 0    , 0          , 0       , 0         , 0        , 0            , 0 },
00248                 } ;
00249 #endif /*ifndef X_DISPLAY_MISSING */
00250         if( asv == NULL )
00251                 return False ;
00252         memset( asv, 0x00, sizeof(ASVisual));
00253 
00254         asv->dpy = dpy ;
00255 
00256 #ifndef X_DISPLAY_MISSING
00257         memset( &attr, 0x00, sizeof( attr ));
00258         attr.colormap = cmap ;
00259 
00260         if( visual_id == 0 )
00261         {
00262                 for( i = 0 ; templates[i].depth != 0 ; i++ )
00263                 {
00264                         int mask = VisualScreenMask|VisualDepthMask|VisualClassMask ;
00265 
00266                         templates[i].screen = screen ;
00267                         if( templates[i].red_mask != 0 )
00268                                 mask |= VisualRedMaskMask;
00269                         if( templates[i].green_mask != 0 )
00270                                 mask |= VisualGreenMaskMask ;
00271                         if( templates[i].blue_mask != 0 )
00272                                 mask |= VisualBlueMaskMask ;
00273 
00274                         if( (list = XGetVisualInfo( dpy, mask, &(templates[i]), &nitems ))!= NULL )
00275                         {
00276                                 find_useable_visual( asv, dpy, screen, root, list, nitems, &attr );
00277                                 XFree( list );
00278                                 list = NULL ;
00279                                 if( asv->visual_info.visual != NULL )
00280                                         break;
00281                         }
00282                 }
00283         }else
00284         {
00285                 templates[0].visualid = visual_id ;
00286                 if( (list = XGetVisualInfo( dpy, VisualIDMask, &(templates[0]), &nitems )) != NULL )
00287                 {
00288                         find_useable_visual( asv, dpy, screen, root, list, nitems, &attr );
00289                         XFree( list );
00290                         list = NULL ;
00291                 }
00292                 if( asv->visual_info.visual == NULL )
00293                         show_error( "Visual with requested ID of 0x%X is unusable - will try default instead.", visual_id );
00294         }
00295 
00296         if( asv->visual_info.visual == NULL )
00297         {  /* we ain't found any decent Visuals - that's some crappy screen you have! */
00298                 register int vclass = 6 ;
00299                 while( --vclass >= 0 )
00300                         if( XMatchVisualInfo( dpy, screen, default_depth, vclass, &(asv->visual_info) ) )
00301                                 break;
00302                 if( vclass < 0 )
00303                         return False;
00304                 /* try and use default colormap when possible : */
00305                 if( asv->visual_info.visual == DefaultVisual( dpy, screen ) )
00306                         attr.colormap = DefaultColormap( dpy, screen );
00307                 else
00308                         attr.colormap = XCreateColormap( dpy, root, asv->visual_info.visual, AllocNone);
00309                 ASV_ALLOC_COLOR( asv, attr.colormap, &black_xcol );
00310                 ASV_ALLOC_COLOR( asv, attr.colormap, &white_xcol );
00311                 asv->colormap = attr.colormap ;
00312                 asv->own_colormap = (attr.colormap != DefaultColormap( dpy, screen ));
00313                 asv->white_pixel = white_xcol.pixel ;
00314                 asv->black_pixel = black_xcol.pixel ;
00315         }
00316         if( get_output_threshold() >= OUTPUT_VERBOSE_THRESHOLD )
00317         {
00318                 fprintf( stderr, "Selected visual 0x%lx: depth %d, class %d\n RGB masks: 0x%lX, 0x%lX, 0x%lX, Byte Ordering: %s\n",
00319                                  (unsigned long)asv->visual_info.visualid,
00320                                  asv->visual_info.depth,
00321                                  asv->visual_info.class,
00322                                  (unsigned long)asv->visual_info.red_mask,
00323                                  (unsigned long)asv->visual_info.green_mask,
00324                                  (unsigned long)asv->visual_info.blue_mask,
00325                                  (ImageByteOrder(asv->dpy)==MSBFirst)?"MSBFirst":"LSBFirst" );
00326         }
00327 #else
00328         asv->white_pixel = ARGB32_White ;
00329         asv->black_pixel = ARGB32_Black ;
00330 #endif /*ifndef X_DISPLAY_MISSING */
00331         return True;
00332 }
00333 
00334 ASVisual *
00335 create_asvisual_for_id( Display *dpy, int screen, int default_depth, VisualID visual_id, Colormap cmap, ASVisual *reusable_memory )
00336 {
00337         ASVisual *asv = reusable_memory ;
00338 #ifndef X_DISPLAY_MISSING
00339     Window root = dpy?RootWindow(dpy,screen):None;
00340 #endif /*ifndef X_DISPLAY_MISSING */
00341 
00342         if( asv == NULL )
00343         asv = safecalloc( 1, sizeof(ASVisual) );
00344 #ifndef X_DISPLAY_MISSING
00345     if( dpy )
00346     {
00347         if( query_screen_visual_id( asv, dpy, screen, root, default_depth, visual_id, cmap ) )
00348         {   /* found visual - now off to decide about color handling on it : */
00349             if( !setup_truecolor_visual( asv ) )
00350             {  /* well, we don't - lets try and preallocate as many colors as we can but up to
00351                 * 1/4 of the colorspace or 12bpp colors, whichever is smaller */
00352                 setup_pseudo_visual( asv );
00353                 if( asv->as_colormap == NULL )
00354                     setup_as_colormap( asv );
00355             }
00356         }else
00357         {
00358             if( reusable_memory != asv )
00359                 free( asv );
00360             asv = NULL ;
00361         }
00362     }
00363 #endif /*ifndef X_DISPLAY_MISSING */
00364         _set_default_asvisual( asv );
00365         return asv;
00366 }
00367 
00368 ASVisual *
00369 create_asvisual( Display *dpy, int screen, int default_depth, ASVisual *reusable_memory )
00370 {
00371         VisualID visual_id = 0;
00372         char *id_env_var ;
00373 
00374         if( (id_env_var = getenv( ASVISUAL_ID_ENVVAR )) != NULL )
00375                 visual_id = strtol(id_env_var,NULL,16);
00376 
00377         return create_asvisual_for_id( dpy, screen, default_depth, visual_id, None, reusable_memory );
00378 }
00379 
00380 
00381 void
00382 destroy_asvisual( ASVisual *asv, Bool reusable )
00383 {
00384         if( asv )
00385         {
00386                 if( get_default_asvisual() == asv )
00387                         _set_default_asvisual( NULL );
00388 #ifndef X_DISPLAY_MISSING
00389                 if( asv->own_colormap )
00390                 {
00391                         if( asv->colormap )
00392                                 XFreeColormap( asv->dpy, asv->colormap );
00393                 }
00394                 if( asv->as_colormap )
00395                 {
00396                         free( asv->as_colormap );
00397                         if( asv->as_colormap_reverse.xref != NULL )
00398                         {
00399                                 if( asv->as_colormap_type == ACM_12BPP )
00400                                         destroy_ashash( &(asv->as_colormap_reverse.hash) );
00401                                 else
00402                                         free( asv->as_colormap_reverse.xref );
00403                         }
00404                 }
00405 #ifdef HAVE_GLX
00406                 if( asv->glx_scratch_gc_direct )
00407                         glXDestroyContext(asv->dpy, asv->glx_scratch_gc_direct );
00408                 if( asv->glx_scratch_gc_indirect )
00409                         glXDestroyContext(asv->dpy, asv->glx_scratch_gc_indirect );
00410 #endif
00411                 if( asv->scratch_window ) 
00412                         XDestroyWindow( asv->dpy, asv->scratch_window );
00413 
00414 #endif /*ifndef X_DISPLAY_MISSING */
00415                 if( !reusable )
00416                         free( asv );
00417         }
00418 }
00419 
00420 int as_colormap_type2size( int type )
00421 {
00422         switch( type )
00423         {
00424                 case ACM_3BPP :
00425                         return 8 ;
00426                 case ACM_6BPP :
00427                         return 64 ;
00428                 case ACM_12BPP :
00429                         return 4096 ;
00430                 default:
00431                         return 0 ;
00432         }
00433 }
00434 
00435 Bool
00436 visual2visual_prop( ASVisual *asv, size_t *size_ret,
00437                                                                    unsigned long *version_ret,
00438                                                                    unsigned long **data_ret )
00439 {
00440         int cmap_size = 0 ;
00441         unsigned long *prop ;
00442         size_t size;
00443 
00444         if( asv == NULL || data_ret == NULL)
00445                 return False;
00446 
00447         cmap_size = as_colormap_type2size( asv->as_colormap_type );
00448 
00449         if( cmap_size > 0 && asv->as_colormap == NULL )
00450                 return False ;
00451         size = (1+1+2+1+cmap_size)*sizeof(unsigned long);
00452         prop = safemalloc( size ) ;
00453 #ifndef X_DISPLAY_MISSING
00454         prop[0] = asv->visual_info.visualid ;
00455         prop[1] = asv->colormap ;
00456         prop[2] = asv->black_pixel ;
00457         prop[3] = asv->white_pixel ;
00458         prop[4] = asv->as_colormap_type ;
00459         if( cmap_size > 0 )
00460         {
00461                 register int i;
00462                 for( i = 0 ; i < cmap_size ; i++ )
00463                         prop[i+5] = asv->as_colormap[i] ;
00464         }
00465         if( size_ret )
00466                 *size_ret = size;
00467 #endif /*ifndef X_DISPLAY_MISSING */
00468         if( version_ret )
00469                 *version_ret = (1<<16)+0;                        /* version is 1.0 */
00470         *data_ret = prop ;
00471         return True;
00472 }
00473 
00474 Bool
00475 visual_prop2visual( ASVisual *asv, Display *dpy, int screen,
00476                                                                    size_t size,
00477                                                                    unsigned long version,
00478                                                                    unsigned long *data )
00479 {
00480 #ifndef X_DISPLAY_MISSING
00481         XVisualInfo templ, *list ;
00482         int nitems = 0 ;
00483         int cmap_size = 0 ;
00484 #endif /*ifndef X_DISPLAY_MISSING */
00485 
00486         if( asv == NULL )
00487                 return False;
00488 
00489         asv->dpy = dpy ;
00490 
00491         if( size < (1+1+2+1)*sizeof(unsigned long) ||
00492                 (version&0x00FFFF) != 0 || (version>>16) != 1 || data == NULL )
00493                 return False;
00494 
00495         if( data[0] == None || data[1] == None ) /* we MUST have valid colormap and visualID !!!*/
00496                 return False;
00497 
00498 #ifndef X_DISPLAY_MISSING
00499         templ.screen = screen ;
00500         templ.visualid = data[0] ;
00501 
00502         list = XGetVisualInfo( dpy, VisualScreenMask|VisualIDMask, &templ, &nitems );
00503         if( list == NULL || nitems == 0 )
00504                 return False;   /* some very bad visual ID has been requested :( */
00505 
00506         asv->visual_info = *list ;
00507         XFree( list );
00508 
00509         if( asv->own_colormap && asv->colormap )
00510                 XFreeColormap( dpy, asv->colormap );
00511 
00512         asv->colormap = data[1] ;
00513         asv->own_colormap = False ;
00514         asv->black_pixel = data[2] ;
00515         asv->white_pixel = data[3] ;
00516         asv->as_colormap_type = data[4];
00517 
00518         cmap_size = as_colormap_type2size( asv->as_colormap_type );
00519 
00520         if( cmap_size > 0 )
00521         {
00522                 register int i ;
00523                 if( asv->as_colormap )
00524                         free( asv->as_colormap );
00525                 asv->as_colormap = safemalloc( cmap_size );
00526                 for( i = 0 ; i < cmap_size ; i++ )
00527                         asv->as_colormap[i] = data[i+5];
00528         }else
00529                 asv->as_colormap_type = ACM_None ;     /* just in case */
00530 #else
00531 
00532 #endif /*ifndef X_DISPLAY_MISSING */
00533         return True;
00534 }
00535 
00536 Bool
00537 setup_truecolor_visual( ASVisual *asv )
00538 {
00539 #ifndef X_DISPLAY_MISSING
00540         XVisualInfo *vi = &(asv->visual_info) ;
00541 
00542         if( vi->class != TrueColor )
00543                 return False;
00544 
00545 #ifdef HAVE_GLX
00546         if( glXQueryExtension (asv->dpy, NULL, NULL))
00547         {
00548                 int val = False;
00549                 glXGetConfig(asv->dpy, vi, GLX_USE_GL, &val);           
00550                 if( val ) 
00551                 {
00552                         asv->glx_scratch_gc_indirect = glXCreateContext (asv->dpy, &(asv->visual_info), NULL, False);
00553                         if( asv->glx_scratch_gc_indirect ) 
00554                         {       
00555                                 set_flags( asv->glx_support, ASGLX_Available );
00556                                 if( glXGetConfig(asv->dpy, vi, GLX_RGBA, &val) == 0 )
00557                                         if( val ) set_flags( asv->glx_support, ASGLX_RGBA );
00558                                 if( glXGetConfig(asv->dpy, vi, GLX_DOUBLEBUFFER, &val) == 0 )
00559                                         if( val ) set_flags( asv->glx_support, ASGLX_DoubleBuffer );
00560                                 if( glXGetConfig(asv->dpy, vi, GLX_DOUBLEBUFFER, &val) == 0 )
00561                                         if( val ) set_flags( asv->glx_support, ASGLX_DoubleBuffer );
00562                                 
00563                                 if( (asv->glx_scratch_gc_direct = glXCreateContext (asv->dpy, &(asv->visual_info), NULL, True)) != NULL ) 
00564                                         if( !glXIsDirect( asv->dpy, asv->glx_scratch_gc_direct ) )
00565                                         {       
00566                                                 glXDestroyContext(asv->dpy, asv->glx_scratch_gc_direct );
00567                                                 asv->glx_scratch_gc_direct = NULL ;
00568                                         }
00569 #if 0                          /* that needs some more research :  */
00570                                 /* under Cygwin that seems to be 40% faster then regular XImage for some reason */
00571                                 set_flags( asv->glx_support, ASGLX_UseForImageTx );
00572 #endif
00573                         }
00574                 }        
00575         }        
00576 #endif
00577 
00578         asv->BGR_mode = ((vi->red_mask&0x0010)!=0) ;
00579         asv->rshift = get_shifts (vi->red_mask);
00580         asv->gshift = get_shifts (vi->green_mask);
00581         asv->bshift = get_shifts (vi->blue_mask);
00582         asv->rbits = get_bits (vi->red_mask);
00583         asv->gbits = get_bits (vi->green_mask);
00584         asv->bbits = get_bits (vi->blue_mask);
00585         asv->true_depth = vi->depth ;
00586         asv->msb_first = (ImageByteOrder(asv->dpy)==MSBFirst);
00587 
00588         if( asv->true_depth == 16 && ((vi->red_mask|vi->blue_mask)&0x8000) == 0 )
00589                 asv->true_depth = 15;
00590         /* setting up conversion handlers : */
00591         switch( asv->true_depth )
00592         {
00593                 case 24 :
00594                 case 32 :
00595                         asv->color2pixel_func     = (asv->BGR_mode)?color2pixel32bgr:color2pixel32rgb ;
00596                         asv->pixel2color_func     = (asv->BGR_mode)?pixel2color32bgr:pixel2color32rgb ;
00597                         asv->ximage2scanline_func = ximage2scanline32 ;
00598                         asv->scanline2ximage_func = scanline2ximage32 ;
00599                     break ;
00600 /*              case 24 :
00601                         scr->color2pixel_func     = (bgr_mode)?color2pixel24bgr:color2pixel24rgb ;
00602                         scr->pixel2color_func     = (bgr_mode)?pixel2color24bgr:pixel2color24rgb ;
00603                         scr->ximage2scanline_func = ximage2scanline24 ;
00604                         scr->scanline2ximage_func = scanline2ximage24 ;
00605                     break ;
00606   */    case 16 :
00607                         asv->color2pixel_func     = (asv->BGR_mode)?color2pixel16bgr:color2pixel16rgb ;
00608                         asv->pixel2color_func     = (asv->BGR_mode)?pixel2color16bgr:pixel2color16rgb ;
00609                         asv->ximage2scanline_func = ximage2scanline16 ;
00610                         asv->scanline2ximage_func = scanline2ximage16 ;
00611                     break ;
00612                 case 15 :
00613                         asv->color2pixel_func     = (asv->BGR_mode)?color2pixel15bgr:color2pixel15rgb ;
00614                         asv->pixel2color_func     = (asv->BGR_mode)?pixel2color15bgr:pixel2color15rgb ;
00615                         asv->ximage2scanline_func = ximage2scanline15 ;
00616                         asv->scanline2ximage_func = scanline2ximage15 ;
00617                     break ;
00618         }
00619 #endif /*ifndef X_DISPLAY_MISSING */
00620         return (asv->ximage2scanline_func != NULL) ;
00621 }
00622 
00623 ARGB32 *
00624 make_reverse_colormap( unsigned long *cmap, size_t size, int depth, unsigned short mask, unsigned short shift )
00625 {
00626         unsigned int max_pixel = 0x01<<depth ;
00627         ARGB32 *rcmap = safecalloc( max_pixel, sizeof( ARGB32 ) );
00628         register int i ;
00629 
00630         for( i = 0 ; i < (int)size ; i++ )
00631                 if( cmap[i] < max_pixel )
00632                         rcmap[cmap[i]] = MAKE_ARGB32( 0xFF, (i>>(shift<<1))& mask, (i>>(shift))&mask, i&mask);
00633         return rcmap;
00634 }
00635 
00636 ASHashTable *
00637 make_reverse_colorhash( unsigned long *cmap, size_t size, int depth, unsigned short mask, unsigned short shift )
00638 {
00639         ASHashTable *hash = create_ashash( 0, NULL, NULL, NULL );
00640         register unsigned int i ;
00641 
00642         if( hash )
00643         {
00644                 for( i = 0 ; i < size ; i++ )
00645                         add_hash_item( hash, (ASHashableValue)cmap[i], (void*)((long)MAKE_ARGB32( 0xFF, (i>>(shift<<1))& mask, (i>>(shift))&mask, i&mask)) );
00646         }
00647         return hash;
00648 }
00649 
00650 void
00651 setup_pseudo_visual( ASVisual *asv  )
00652 {
00653 #ifndef X_DISPLAY_MISSING
00654         XVisualInfo *vi = &(asv->visual_info) ;
00655 
00656         /* we need to allocate new usable list of colors based on available bpp */
00657         asv->true_depth = vi->depth ;
00658         if( asv->as_colormap == NULL )
00659         {
00660                 if( asv->true_depth < 8 )
00661                         asv->as_colormap_type = ACM_3BPP ;
00662                 else if( asv->true_depth < 12 )
00663                         asv->as_colormap_type = ACM_6BPP ;
00664                 else
00665                         asv->as_colormap_type = ACM_12BPP ;
00666         }
00667         /* then we need to set up hooks : */
00668         switch( asv->as_colormap_type )
00669         {
00670                 case ACM_3BPP:
00671                         asv->ximage2scanline_func = ximage2scanline_pseudo3bpp ;
00672                         asv->scanline2ximage_func = scanline2ximage_pseudo3bpp ;
00673                         asv->color2pixel_func = color2pixel_pseudo3bpp ;
00674                     break ;
00675                 case ACM_6BPP:
00676                         asv->ximage2scanline_func = ximage2scanline_pseudo6bpp ;
00677                         asv->scanline2ximage_func = scanline2ximage_pseudo6bpp ;
00678                         asv->color2pixel_func = color2pixel_pseudo6bpp ;
00679                     break ;
00680                 default:
00681                         asv->as_colormap_type = ACM_12BPP ;
00682                 case ACM_12BPP:
00683                         asv->ximage2scanline_func = ximage2scanline_pseudo12bpp ;
00684                         asv->scanline2ximage_func = scanline2ximage_pseudo12bpp ;
00685                         asv->color2pixel_func = color2pixel_pseudo12bpp ;
00686                     break ;
00687         }
00688         if( asv->as_colormap != NULL )
00689         {
00690                 if( asv->as_colormap_type == ACM_3BPP || asv->as_colormap_type == ACM_6BPP )
00691                 {
00692                         unsigned short mask = 0x0003, shift = 2 ;
00693                         if( asv->as_colormap_type==ACM_3BPP )
00694                         {
00695                                 mask = 0x0001 ;
00696                                 shift = 1 ;
00697                         }
00698                         asv->as_colormap_reverse.xref = make_reverse_colormap( asv->as_colormap,
00699                                                                                                                           as_colormap_type2size( asv->as_colormap_type ),
00700                                                                                                                           asv->true_depth, mask, shift );
00701                 }else if( asv->as_colormap_type == ACM_12BPP )
00702                 {
00703                         asv->as_colormap_reverse.hash = make_reverse_colorhash( asv->as_colormap,
00704                                                                                                                           as_colormap_type2size( asv->as_colormap_type ),
00705                                                                                                                           asv->true_depth, 0x000F, 4 );
00706                 }
00707         }
00708 #endif /*ifndef X_DISPLAY_MISSING */
00709 }
00710 
00711 #ifndef X_DISPLAY_MISSING
00712 static unsigned long*
00713 make_3bpp_colormap( ASVisual *asv )
00714 {
00715         XColor colors_3bpp[8] =
00716         /* list of non-white, non-black colors in order of decreasing importance: */
00717         {   { 0, 0, 0xFFFF, 0, DoRed|DoGreen|DoBlue, 0},
00718                 { 0, 0xFFFF, 0, 0, DoRed|DoGreen|DoBlue, 0},
00719                 { 0, 0, 0, 0xFFFF, DoRed|DoGreen|DoBlue, 0},
00720                 { 0, 0xFFFF, 0xFFFF, 0, DoRed|DoGreen|DoBlue, 0},
00721             { 0, 0, 0xFFFF, 0xFFFF, DoRed|DoGreen|DoBlue, 0},
00722             { 0, 0xFFFF, 0, 0xFFFF, DoRed|DoGreen|DoBlue, 0}} ;
00723         unsigned long *cmap ;
00724 
00725         cmap = safemalloc( 8 * sizeof(unsigned long) );
00726         /* fail safe code - if any of the alloc fails - colormap entry will still have
00727          * most suitable valid value ( black or white in 1bpp mode for example ) : */
00728         cmap[0] = cmap[1] = cmap[2] = cmap[3] = asv->black_pixel ;
00729         cmap[7] = cmap[6] = cmap[5] = cmap[4] = asv->white_pixel ;
00730         if( ASV_ALLOC_COLOR( asv, asv->colormap, &colors_3bpp[0] ))  /* pure green */
00731                 cmap[0x02] = cmap[0x03] = cmap[0x06] = colors_3bpp[0].pixel ;
00732         if( ASV_ALLOC_COLOR( asv, asv->colormap, &colors_3bpp[1] ))  /* pure red */
00733                 cmap[0x04] = cmap[0x05] = colors_3bpp[1].pixel ;
00734         if( ASV_ALLOC_COLOR( asv, asv->colormap, &colors_3bpp[2] ))  /* pure blue */
00735                 cmap[0x01] = colors_3bpp[2].pixel ;
00736         if( ASV_ALLOC_COLOR( asv, asv->colormap, &colors_3bpp[3] ))  /* yellow */
00737                 cmap[0x06] = colors_3bpp[3].pixel ;
00738         if( ASV_ALLOC_COLOR( asv, asv->colormap, &colors_3bpp[4] ))  /* cyan */
00739                 cmap[0x03] = colors_3bpp[4].pixel ;
00740         if( ASV_ALLOC_COLOR( asv, asv->colormap, &colors_3bpp[5] ))  /* magenta */
00741                 cmap[0x05] = colors_3bpp[5].pixel ;
00742         return cmap;
00743 }
00744 
00745 static unsigned long*
00746 make_6bpp_colormap( ASVisual *asv, unsigned long *cmap_3bpp )
00747 {
00748         unsigned short red, green, blue ;
00749         unsigned long *cmap = safemalloc( 0x0040*sizeof( unsigned long) );
00750         XColor xcol ;
00751 
00752         cmap[0] = asv->black_pixel ;
00753 
00754         xcol.flags = DoRed|DoGreen|DoBlue ;
00755         for( blue = 0 ; blue <= 0x0003 ; blue++ )
00756         {
00757                 xcol.blue = (0xFFFF*blue)/3 ;
00758                 for( red = 0 ; red <= 0x0003 ; red++ )
00759                 {                                       /* red has highier priority then blue */
00760                         xcol.red = (0xFFFF*red)/3 ;
00761 /*                      green = ( blue == 0 && red == 0 )?1:0 ; */
00762                         for( green = 0 ; green <= 0x0003 ; green++ )
00763                         {                                  /* green has highier priority then red */
00764                                 unsigned short index_3bpp = ((red&0x0002)<<1)|(green&0x0002)|((blue&0x0002)>>1);
00765                                 unsigned short index_6bpp = (red<<4)|(green<<2)|blue;
00766                                 xcol.green = (0xFFFF*green)/3 ;
00767 
00768                                 if( (red&0x0001) == ((red&0x0002)>>1) &&
00769                                         (green&0x0001) == ((green&0x0002)>>1) &&
00770                                         (blue&0x0001) == ((blue&0x0002)>>1) )
00771                                         cmap[index_6bpp] = cmap_3bpp[index_3bpp];
00772                                 else
00773                                 {
00774                                         if( ASV_ALLOC_COLOR( asv, asv->colormap, &xcol) != 0 )
00775                                                 cmap[index_6bpp] = xcol.pixel ;
00776                                         else
00777                                                 cmap[index_6bpp] = cmap_3bpp[index_3bpp] ;
00778                                 }
00779                         }
00780                 }
00781         }
00782         return cmap;
00783 }
00784 
00785 static unsigned long*
00786 make_9bpp_colormap( ASVisual *asv, unsigned long *cmap_6bpp )
00787 {
00788         unsigned long *cmap = safemalloc( 512*sizeof( unsigned long) );
00789         unsigned short red, green, blue ;
00790         XColor xcol ;
00791 
00792         cmap[0] = asv->black_pixel ;               /* just in case  */
00793 
00794         xcol.flags = DoRed|DoGreen|DoBlue ;
00795         for( blue = 0 ; blue <= 0x0007 ; blue++ )
00796         {
00797                 xcol.blue = (0xFFFF*blue)/7 ;
00798                 for( red = 0 ; red <= 0x0007 ; red++ )
00799                 {                                       /* red has highier priority then blue */
00800                         xcol.red = (0xFFFF*red)/7 ;
00801                         for( green = 0 ; green <= 0x0007 ; green++ )
00802                         {                                  /* green has highier priority then red */
00803                                 unsigned short index_6bpp = ((red&0x0006)<<3)|((green&0x0006)<<1)|((blue&0x0006)>>1);
00804                                 unsigned short index_9bpp = (red<<6)|(green<<3)|blue;
00805                                 xcol.green = (0xFFFF*green)/7 ;
00806 
00807                                 if( (red&0x0001) == ((red&0x0002)>>1) &&
00808                                         (green&0x0001) == ((green&0x0002)>>1) &&
00809                                         (blue&0x0001) == ((blue&0x0002)>>1) )
00810                                         cmap[index_9bpp] = cmap_6bpp[index_6bpp];
00811                                 else
00812                                 {
00813                                         if( ASV_ALLOC_COLOR( asv, asv->colormap, &xcol) != 0 )
00814                                                 cmap[index_9bpp] = xcol.pixel ;
00815                                         else
00816                                                 cmap[index_9bpp] = cmap_6bpp[index_6bpp] ;
00817                                 }
00818                         }
00819                 }
00820         }
00821         return cmap;
00822 }
00823 
00824 static unsigned long*
00825 make_12bpp_colormap( ASVisual *asv, unsigned long *cmap_9bpp )
00826 {
00827         unsigned long *cmap = safemalloc( 4096*sizeof( unsigned long) );
00828         unsigned short red, green, blue ;
00829         XColor xcol ;
00830 
00831         cmap[0] = asv->black_pixel ;               /* just in case  */
00832 
00833         xcol.flags = DoRed|DoGreen|DoBlue ;
00834         for( blue = 0 ; blue <= 0x000F ; blue++ )
00835         {
00836                 xcol.blue = (0xFFFF*blue)/15 ;
00837                 for( red = 0 ; red <= 0x000F ; red++ )
00838                 {                                       /* red has highier priority then blue */
00839                         xcol.red = (0xFFFF*red)/15 ;
00840                         for( green = 0 ; green <= 0x000F ; green++ )
00841                         {                                  /* green has highier priority then red */
00842                                 unsigned short index_9bpp = ((red&0x000E)<<5)|((green&0x000E)<<2)|((blue&0x000E)>>1);
00843                                 unsigned short index_12bpp = (red<<8)|(green<<4)|blue;
00844                                 xcol.green = (0xFFFF*green)/15 ;
00845 
00846                                 if( (red&0x0001) == ((red&0x0002)>>1) &&
00847                                         (green&0x0001) == ((green&0x0002)>>1) &&
00848                                         (blue&0x0001) == ((blue&0x0002)>>1) )
00849                                         cmap[index_12bpp] = cmap_9bpp[index_9bpp];
00850                                 else
00851                                 {
00852                                         if( ASV_ALLOC_COLOR( asv, asv->colormap, &xcol) != 0 )
00853                                                 cmap[index_12bpp] = xcol.pixel ;
00854                                         else
00855                                                 cmap[index_12bpp] = cmap_9bpp[index_9bpp] ;
00856                                 }
00857                         }
00858                 }
00859         }
00860         return cmap;
00861 }
00862 #endif /*ifndef X_DISPLAY_MISSING */
00863 
00864 void
00865 setup_as_colormap( ASVisual *asv )
00866 {
00867 #ifndef X_DISPLAY_MISSING
00868         unsigned long *cmap_lower, *cmap ;
00869 
00870         if( asv == NULL || asv->as_colormap != NULL )
00871                 return ;
00872 
00873         cmap = make_3bpp_colormap( asv );
00874         if( asv->as_colormap_type == ACM_3BPP )
00875         {
00876                 asv->as_colormap = cmap ;
00877                 asv->as_colormap_reverse.xref = make_reverse_colormap( cmap, 8, asv->true_depth, 0x0001, 1 );
00878                 return ;
00879         }
00880         cmap_lower = cmap ;
00881         cmap = make_6bpp_colormap( asv, cmap_lower );
00882         free( cmap_lower );
00883         if( asv->as_colormap_type == ACM_6BPP )
00884         {
00885                 asv->as_colormap = cmap ;
00886                 asv->as_colormap_reverse.xref = make_reverse_colormap( cmap, 64, asv->true_depth, 0x0003, 2 );
00887         }else
00888         {
00889                 cmap_lower = cmap ;
00890                 cmap = make_9bpp_colormap( asv, cmap_lower );
00891                 free( cmap_lower );
00892                 cmap_lower = cmap ;
00893                 cmap = make_12bpp_colormap( asv, cmap_lower );
00894                 free( cmap_lower );
00895 
00896                 asv->as_colormap = cmap ;
00897                 asv->as_colormap_reverse.hash = make_reverse_colorhash( cmap, 4096, asv->true_depth, 0x000F, 4 );
00898         }
00899 #endif /*ifndef X_DISPLAY_MISSING */
00900 }
00901 
00902 /*********************************************************************/
00903 /* handy utility functions for creation of windows/pixmaps/XImages : */
00904 /*********************************************************************/
00905 Window
00906 create_visual_window( ASVisual *asv, Window parent,
00907                                           int x, int y, unsigned int width, unsigned int height,
00908                                           unsigned int border_width, unsigned int wclass,
00909                                           unsigned long mask, XSetWindowAttributes *attributes )
00910 {
00911 #ifndef X_DISPLAY_MISSING
00912         XSetWindowAttributes my_attr ;
00913         int depth = 0;
00914 
00915         if( asv == NULL || parent == None )
00916                 return None ;
00917 LOCAL_DEBUG_OUT( "Colormap %lX, parent %lX, %ux%u%+d%+d, bw = %d, class %d",
00918                                   asv->colormap, parent, width, height, x, y, border_width,
00919                                   wclass );
00920         if( attributes == NULL )
00921         {
00922                 attributes = &my_attr ;
00923                 memset( attributes, 0x00, sizeof(XSetWindowAttributes));
00924                 mask = 0;
00925         }
00926 
00927         if( width < 1 )
00928                 width = 1 ;
00929         if( height < 1 )
00930                 height = 1 ;
00931 
00932         if( wclass == InputOnly )
00933         {
00934                 border_width = 0 ;
00935                 if( (mask&INPUTONLY_LEGAL_MASK) != mask )
00936                         show_warning( " software BUG detected : illegal InputOnly window's mask 0x%lX - overriding", mask );
00937                 mask &= INPUTONLY_LEGAL_MASK ;
00938         }else
00939         {
00940                 depth = asv->visual_info.depth ;
00941                 if( !get_flags(mask, CWColormap ) )
00942                 {
00943                         attributes->colormap = asv->colormap ;
00944                         set_flags(mask, CWColormap );
00945                 }
00946                 if( !get_flags(mask, CWBorderPixmap ) )
00947                 {
00948                         attributes->border_pixmap = None ;
00949                         set_flags(mask, CWBorderPixmap );
00950                 }
00951 
00952                 clear_flags(mask, CWBorderPixmap );
00953                 if( !get_flags(mask, CWBorderPixel ) )
00954                 {
00955                         attributes->border_pixel = asv->black_pixel ;
00956                         set_flags(mask, CWBorderPixel );
00957                 }
00958                 /* If the parent window and the new window have different bit
00959                 ** depths (such as on a Solaris box with 8bpp root window and
00960                 ** 24bpp child windows), ParentRelative will not work. */
00961                 if ( get_flags(mask, CWBackPixmap) && attributes->background_pixmap == ParentRelative &&
00962                          asv->visual_info.visual != DefaultVisual( asv->dpy, DefaultScreen(asv->dpy) ))
00963                 {
00964                         clear_flags(mask, CWBackPixmap);
00965                 }
00966         }
00967         LOCAL_DEBUG_OUT( "parent = %lX, mask = 0x%lX, VisualID = 0x%lX, Border Pixel = %ld, colormap = %lX",
00968                                           parent, mask, asv->visual_info.visual->visualid, attributes->border_pixel, attributes->colormap );
00969         return XCreateWindow (asv->dpy, parent, x, y, width, height, border_width, depth,
00970                                                   wclass, asv->visual_info.visual,
00971                               mask, attributes);
00972 #else
00973         return None ;
00974 #endif /*ifndef X_DISPLAY_MISSING */
00975 
00976 }
00977 
00978 
00979 GC
00980 create_visual_gc( ASVisual *asv, Window root, unsigned long mask, XGCValues *gcvalues )
00981 {
00982         GC gc = NULL ;
00983 
00984 #ifndef X_DISPLAY_MISSING
00985         if( asv )
00986         {
00987                 XGCValues scratch_gcv ;
00988                 if( asv->scratch_window == None ) 
00989                         asv->scratch_window = create_visual_window( asv, root, -20, -20, 10, 10, 0, InputOutput, 0, NULL );
00990                 if( asv->scratch_window != None )
00991                         gc = XCreateGC( asv->dpy, asv->scratch_window, gcvalues?mask:0, gcvalues?gcvalues:&scratch_gcv );
00992         }
00993 #endif
00994         return gc;
00995 }
00996 
00997 Pixmap
00998 create_visual_pixmap( ASVisual *asv, Window root, unsigned int width, unsigned int height, unsigned int depth )
00999 {
01000 #ifndef X_DISPLAY_MISSING
01001         Pixmap p = None ;
01002         if( asv != NULL )
01003         {       
01004                 if( root == None ) 
01005                         root = RootWindow(asv->dpy,DefaultScreen(asv->dpy));
01006                 if( depth==0 )
01007                         depth = asv->true_depth ;
01008                 p = XCreatePixmap( asv->dpy, root, MAX(width,(unsigned)1), MAX(height,(unsigned)1), depth );
01009         }
01010         return p;
01011 #else
01012         return None ;
01013 #endif /*ifndef X_DISPLAY_MISSING */
01014 }
01015 
01016 void
01017 destroy_visual_pixmap( ASVisual *asv, Pixmap *ppmap )
01018 {
01019         if( asv && ppmap )
01020                 if( *ppmap )
01021                 {
01022 #ifndef X_DISPLAY_MISSING
01023                         XFreePixmap( asv->dpy, *ppmap );
01024                         *ppmap = None ;
01025 #endif
01026                 }
01027 }
01028 
01029 #ifndef X_DISPLAY_MISSING
01030 static int
01031 quiet_xerror_handler (Display * dpy, XErrorEvent * error)
01032 {
01033     return 0;
01034 }
01035 
01036 #endif
01037 
01038 int
01039 get_dpy_drawable_size (Display *drawable_dpy, Drawable d, unsigned int *ret_w, unsigned int *ret_h)
01040 {
01041         int result = 0 ;
01042 #ifndef X_DISPLAY_MISSING
01043         if( d != None && drawable_dpy != NULL ) 
01044         {
01045                 Window        root;
01046                 unsigned int  ujunk;
01047                 int           junk;
01048                 int           (*oldXErrorHandler) (Display *, XErrorEvent *) = XSetErrorHandler (quiet_xerror_handler);
01049                 result = XGetGeometry (drawable_dpy, d, &root, &junk, &junk, ret_w, ret_h, &ujunk, &ujunk);
01050                 XSetErrorHandler (oldXErrorHandler);
01051         }
01052 #endif
01053         if ( result == 0)
01054         {
01055                 *ret_w = 0;
01056                 *ret_h = 0;
01057                 return 0;
01058         }
01059         return 1;
01060 }
01061 
01062 Bool
01063 get_dpy_window_position (Display *window_dpy, Window root, Window w, int *px, int *py, int *transparency_x, int *transparency_y)
01064 {
01065         Bool result = False ;
01066         int x = 0, y = 0, transp_x = 0, transp_y = 0 ;
01067 #ifndef X_DISPLAY_MISSING
01068         if( window_dpy != NULL && w != None ) 
01069         {
01070                 Window wdumm;
01071                 int rootHeight = XDisplayHeight(window_dpy, DefaultScreen(window_dpy) );
01072                 int rootWidth = XDisplayWidth(window_dpy, DefaultScreen(window_dpy) );
01073 
01074                 if( root == None ) 
01075                         root = RootWindow(window_dpy,DefaultScreen(window_dpy));
01076                         
01077                 result = XTranslateCoordinates (window_dpy, w, root, 0, 0, &x, &y, &wdumm);
01078                 if( result ) 
01079                 {
01080                         /* taking in to consideration virtual desktopping */
01081                         result = (x < rootWidth && y < rootHeight );
01082                         if( result )
01083                         {
01084                                 unsigned int width = 0, height = 0;
01085                                 get_dpy_drawable_size (window_dpy, w, &width, &height);                         
01086                                 result = (x + width > 0 && y+height > 0) ; 
01087                         }
01088 
01089                         for( transp_x = x ; transp_x < 0 ; transp_x += rootWidth );                     
01090                         for( transp_y = y ; transp_y < 0 ; transp_y += rootHeight );                    
01091                         while( transp_x > rootWidth ) transp_x -= rootWidth ; 
01092                         while( transp_y > rootHeight ) transp_y -= rootHeight ; 
01093                 }
01094         }
01095 #endif
01096         if( px ) 
01097                 *px = x;
01098         if( py ) 
01099                 *py = y;
01100         if( transparency_x ) 
01101                 *transparency_x = transp_x ; 
01102         if( transparency_y ) 
01103                 *transparency_y = transp_y ; 
01104         return result;
01105 }
01106 
01107 
01108 #ifndef X_DISPLAY_MISSING
01109 static unsigned char *scratch_ximage_data = NULL ;
01110 static int scratch_use_count = 0 ;
01111 static size_t scratch_ximage_allocated_size = 0;  
01112 #endif 
01113 static size_t scratch_ximage_max_size = ASSHM_SAVED_MAX*2;  /* maximum of 512 KBytes is default  */  
01114 static size_t scratch_ximage_normal_size = ASSHM_SAVED_MAX;  /* normal usage of scratch pool is 256 KBytes is default  */  
01115 
01116 int
01117 set_scratch_ximage_max_size( int new_max_size )
01118 {
01119         int tmp = scratch_ximage_max_size ;
01120         scratch_ximage_max_size = new_max_size ;
01121         return tmp;
01122 }
01123 
01124 int
01125 set_scratch_ximage_normal_size( int new_normal_size )
01126 {
01127         int tmp = scratch_ximage_normal_size ;
01128         scratch_ximage_normal_size = new_normal_size ;
01129         return tmp;
01130 }
01131 
01132 #ifndef X_DISPLAY_MISSING
01133 static void*
01134 get_scratch_data(size_t size)
01135 {
01136         if( scratch_ximage_max_size < size || scratch_use_count > 0) 
01137                 return NULL;
01138         if( scratch_ximage_allocated_size < size ) 
01139         {
01140                 scratch_ximage_allocated_size = size ;
01141                 scratch_ximage_data = realloc( scratch_ximage_data, size );
01142         }
01143         
01144         ++scratch_use_count;
01145         return scratch_ximage_data ; 
01146 }
01147 
01148 static Bool
01149 release_scratch_data( void *data )
01150 {
01151         if( scratch_use_count == 0 || data != scratch_ximage_data )
01152                 return False;
01153         --scratch_use_count ;
01154         if( scratch_use_count == 0 )
01155         {
01156                 /* want to deallocate if too much is allocated ? */
01157                 
01158         }        
01159         return True;
01160 }        
01161 #endif 
01162 
01163 #ifdef XSHMIMAGE
01164 
01165 int     (*orig_XShmImage_destroy_image)(XImage *ximage) = NULL ;
01166 
01167 typedef struct ASXShmImage
01168 {
01169         XImage                  *ximage ;
01170         XShmSegmentInfo *segment ;
01171         int                      ref_count ;
01172         Bool                     wait_completion_event ;
01173         unsigned int     size ;
01174   ASVisual *asv ;
01175 }ASXShmImage;
01176 
01177 typedef struct ASShmArea
01178 {
01179         unsigned int     size ;
01180         char *shmaddr ;
01181         int shmid ;
01182         struct ASShmArea *next, *prev ;
01183 }ASShmArea;
01184 
01185 static ASHashTable      *xshmimage_segments = NULL ;
01186 static ASHashTable      *xshmimage_images = NULL ;
01187 /* attempt to reuse 256 Kb of shmem - no reason to reuse more than that,
01188  * since most XImages will be in range of 20K-100K */
01189 static ASShmArea  *shm_available_mem_head = NULL ;
01190 static int shm_available_mem_used = 0 ;
01191 
01192 static Bool _as_use_shm_images = False ;
01193 
01194 void really_destroy_shm_area( char *shmaddr, int shmid )
01195 {
01196         shmdt (shmaddr);
01197         shmctl (shmid, IPC_RMID, 0);
01198         LOCAL_DEBUG_OUT("XSHMIMAGE> DESTROY_SHM : freeing shmid = %d, remaining in cache = %d bytes ", shmid, shm_available_mem_used );
01199 }
01200 
01201 void remove_shm_area( ASShmArea *area, Bool free_resources )
01202 {
01203         if( area )
01204         {
01205                 if( area == shm_available_mem_head )
01206                         shm_available_mem_head = area->next ;
01207                 if( area->next )
01208                         area->next->prev = area->prev ;
01209                 if( area->prev )
01210                         area->prev->next = area->next ;
01211                 shm_available_mem_used -= area->size ;
01212                 if( free_resources )
01213                         really_destroy_shm_area( area->shmaddr, area->shmid );
01214                 else
01215                 {
01216                         LOCAL_DEBUG_OUT("XSHMIMAGE> REMOVE_SHM : reusing shmid = %d, size %d, remaining in cache = %d bytes ", area->shmid, area->size, shm_available_mem_used );
01217                 }
01218                 free( area );
01219         }
01220 
01221 }
01222 
01223 void flush_shm_cache( )
01224 {
01225         if( xshmimage_images ) 
01226                 destroy_ashash( &xshmimage_images );
01227         if( xshmimage_segments )
01228                 destroy_ashash( &xshmimage_segments );
01229         while( shm_available_mem_head != NULL )
01230                 remove_shm_area( shm_available_mem_head, True );
01231 }
01232 
01233 void save_shm_area( char *shmaddr, int shmid, int size )
01234 {
01235         ASShmArea *area;
01236 
01237         if( shm_available_mem_used+size >= ASSHM_SAVED_MAX )
01238         {
01239                 really_destroy_shm_area( shmaddr, shmid );
01240                 return ;
01241         }
01242 
01243         shm_available_mem_used+=size ;
01244         area = safecalloc( 1, sizeof(ASShmArea) );
01245 
01246         area->shmaddr = shmaddr ;
01247         area->shmid = shmid ;
01248         area->size = size ;
01249         LOCAL_DEBUG_OUT("XSHMIMAGE> SAVE_SHM : saving shmid = %d, size %d, remaining in cache = %d bytes ", area->shmid, area->size, shm_available_mem_used );
01250 
01251         area->next = shm_available_mem_head ;
01252         if( shm_available_mem_head )
01253                 shm_available_mem_head->prev = area ;
01254         shm_available_mem_head = area ;
01255 }
01256 
01257 char *get_shm_area( int size, int *shmid )
01258 {
01259         ASShmArea *selected = NULL, *curr = shm_available_mem_head;
01260 
01261         while( curr != NULL )
01262         {
01263                 if( curr->size >= size && curr->size < (size * 4)/3 )
01264                 {
01265                         if( selected == NULL )
01266                                 selected = curr ;
01267                         else if( selected->size > curr->size )
01268                                 selected = curr ;
01269                 }
01270                 curr = curr->next ;
01271         }
01272         if( selected != NULL )
01273         {
01274                 char *tmp = selected->shmaddr ;
01275                 *shmid = selected->shmid ;
01276                 remove_shm_area( selected, False );
01277                 return tmp ;
01278         }
01279 
01280         *shmid = shmget (IPC_PRIVATE, size, IPC_CREAT|0666);
01281         return shmat (*shmid, 0, 0);
01282 }
01283 
01284 void
01285 destroy_xshmimage_segment(ASHashableValue value, void *data)
01286 {
01287         ASXShmImage *img_data = (ASXShmImage*)data ;
01288         if( img_data->segment != NULL )
01289         {
01290                 LOCAL_DEBUG_OUT( "XSHMIMAGE> FREE_SEG : img_data = %p : segent to be freed: shminfo = %p ", img_data, img_data->segment );
01291                 XShmDetach (img_data->asv->dpy, img_data->segment);
01292                 save_shm_area( img_data->segment->shmaddr, img_data->segment->shmid, img_data->size );
01293                 free( img_data->segment );
01294                 img_data->segment = NULL ;
01295                 if( img_data->ximage == NULL )
01296                         free( img_data );
01297         }else
01298         {
01299                 LOCAL_DEBUG_OUT( "XSHMIMAGE> FREE_SEG : img_data = %p : segment data is NULL already value = %ld!!", img_data, value );
01300         }
01301 }
01302 
01303 Bool destroy_xshm_segment( ShmSeg shmseg )
01304 {
01305         if( xshmimage_segments )
01306         {
01307                 if(remove_hash_item( xshmimage_segments, AS_HASHABLE(shmseg), NULL, True ) == ASH_Success)
01308                 {
01309                         LOCAL_DEBUG_OUT( "XSHMIMAGE> REMOVE_SEG : segment %ld removed from the hash successfully!", shmseg );
01310                         return True ;
01311                 }
01312                 LOCAL_DEBUG_OUT( "XSHMIMAGE> ERROR : could not find segment %ld(0x%lX) in the hash!", shmseg, shmseg );
01313         }else
01314         {
01315                 LOCAL_DEBUG_OUT( "XSHMIMAGE> ERROR : segments hash is %p!!", xshmimage_segments );
01316         }
01317 
01318         return False ;
01319 }
01320 
01321 
01322 void
01323 destroy_xshmimage_image(ASHashableValue value, void *data)
01324 {
01325         ASXShmImage *img_data = (ASXShmImage*)data ;
01326         if( img_data->ximage != NULL )
01327         {
01328                 if( orig_XShmImage_destroy_image )
01329                         orig_XShmImage_destroy_image( img_data->ximage );
01330                 else
01331                         XFree ((char *)img_data->ximage);
01332                 LOCAL_DEBUG_OUT( "XSHMIMAGE> FREE_XIM : ximage freed: img_data = %p, xim = %p", img_data, img_data->ximage);
01333                 img_data->ximage = NULL ;
01334                 if( img_data->segment != NULL && !img_data->wait_completion_event )
01335                 {
01336                         if( destroy_xshm_segment( img_data->segment->shmseg ) )
01337                                 return ;
01338                         img_data->segment = NULL ;
01339                 }
01340                 if( img_data->segment == NULL )
01341                         free( img_data );
01342         }
01343 }
01344 
01345 Bool enable_shmem_images_for_visual (ASVisual *asv)
01346 {
01347 #ifndef DEBUG_ALLOCS
01348         if( asv && asv->dpy && XShmQueryExtension (asv->dpy) )
01349         {
01350                 _as_use_shm_images = True ;
01351                 if( xshmimage_segments == NULL )
01352                         xshmimage_segments = create_ashash( 0, NULL, NULL, destroy_xshmimage_segment );
01353                 if( xshmimage_images == NULL )
01354                         xshmimage_images = create_ashash( 0, pointer_hash_value, NULL, destroy_xshmimage_image );
01355         }else
01356 #endif
01357                 _as_use_shm_images = False ;
01358         return _as_use_shm_images;
01359 }
01360 
01361 Bool enable_shmem_images ()
01362 {
01363         return enable_shmem_images_for_visual (get_default_asvisual());
01364 }
01365 
01366 
01367 void disable_shmem_images()
01368 {
01369         _as_use_shm_images = False ;
01370 }
01371 
01372 Bool 
01373 check_shmem_images_enabled()
01374 {
01375         return _as_use_shm_images ;
01376 }
01377 
01378 
01379 int destroy_xshm_image( XImage *ximage )
01380 {
01381         if( xshmimage_images )
01382         {
01383                 if( remove_hash_item( xshmimage_images, AS_HASHABLE(ximage), NULL, True ) != ASH_Success )
01384                 {
01385                         if (ximage->data != NULL)
01386                                 free ((char *)ximage->data);
01387                         if (ximage->obdata != NULL)
01388                                 free ((char *)ximage->obdata);
01389                         XFree ((char *)ximage);
01390                         LOCAL_DEBUG_OUT( "XSHMIMAGE> FREE_XIM : ximage freed: xim = %p", ximage);
01391                 }
01392         }
01393         return 1;
01394 }
01395 
01396 unsigned long 
01397 ximage2shmseg( XImage *xim )
01398 {
01399         void *vptr = NULL ;
01400         if( get_hash_item( xshmimage_images, AS_HASHABLE(xim), &vptr ) == ASH_Success )         
01401         {
01402                 ASXShmImage *data = (ASXShmImage *)vptr ;
01403                 if( data->segment ) 
01404                         return data->segment->shmseg;   
01405         }       
01406         return 0; 
01407 }        
01408 
01409 void registerXShmImage( ASVisual *asv, XImage *ximage, XShmSegmentInfo* shminfo )
01410 {
01411         ASXShmImage *data = safecalloc( 1, sizeof(ASXShmImage));
01412         LOCAL_DEBUG_OUT( "XSHMIMAGE> CREATE_XIM : img_data = %p : image created: xiom = %p, shminfo = %p, segment = %d, data = %p", data, ximage, shminfo, shminfo->shmid, ximage->data );
01413   data->asv = asv ;
01414         data->ximage = ximage ;
01415         data->segment = shminfo ;
01416         data->size = ximage->bytes_per_line * ximage->height ;
01417 
01418         orig_XShmImage_destroy_image = ximage->f.destroy_image ;
01419         ximage->f.destroy_image = destroy_xshm_image ;
01420 
01421         add_hash_item( xshmimage_images, AS_HASHABLE(ximage), data );
01422         add_hash_item( xshmimage_segments, AS_HASHABLE(shminfo->shmseg), data );
01423 }
01424 
01425 void *
01426 check_XImage_shared( XImage *xim )
01427 {
01428         ASXShmImage *img_data = NULL ;
01429         if( _as_use_shm_images )
01430         {
01431                 ASHashData hdata ;
01432                 if(get_hash_item( xshmimage_images, AS_HASHABLE(xim), &hdata.vptr ) != ASH_Success)
01433                         img_data = NULL ;
01434                 else
01435                         img_data = hdata.vptr ;
01436         }
01437         return img_data ;
01438 }
01439 
01440 Bool ASPutXImage( ASVisual *asv, Drawable d, GC gc, XImage *xim,
01441                   int src_x, int src_y, int dest_x, int dest_y,
01442                                   unsigned int width, unsigned int height )
01443 {
01444         ASXShmImage *img_data = NULL ;
01445         if( xim == NULL || asv == NULL )
01446                 return False ;
01447 
01448         if( ( img_data = check_XImage_shared( xim )) != NULL )
01449         {
01450 /*              LOCAL_DEBUG_OUT( "XSHMIMAGE> PUT_XIM : using shared memory Put = %p", xim ); */
01451                 if( XShmPutImage( asv->dpy, d, gc, xim, src_x, src_y, dest_x, dest_y,width, height, True ) )
01452                 {
01453                         img_data->wait_completion_event = True ;
01454                         return True ;
01455                 }
01456         }
01457 /*      LOCAL_DEBUG_OUT( "XSHMIMAGE> PUT_XIM : using normal Put = %p", xim ); */
01458         return XPutImage( asv->dpy, d, gc, xim, src_x, src_y, dest_x, dest_y,width, height );
01459 }
01460 
01461 XImage *ASGetXImage( ASVisual *asv, Drawable d,
01462                   int x, int y, unsigned int width, unsigned int height,
01463                                   unsigned long plane_mask )
01464 {
01465         XImage *xim = NULL ;
01466 
01467         if( asv == NULL || d == None )
01468                 return NULL ;
01469         if( _as_use_shm_images && width*height > 4000)
01470         {
01471                 unsigned int depth ;
01472                 Window        root;
01473                 unsigned int  ujunk;
01474                 int           junk;
01475                 if(XGetGeometry (asv->dpy, d, &root, &junk, &junk, &ujunk, &ujunk, &ujunk, &depth) == 0)
01476                         return NULL ;
01477 
01478                 xim = create_visual_ximage(asv,width,height,depth);
01479                 XShmGetImage( asv->dpy, d, xim, x, y, plane_mask );
01480 
01481         }else
01482                 xim = XGetImage( asv->dpy, d, x, y, width, height, plane_mask, ZPixmap );
01483         return xim ;
01484 }
01485 #else
01486 
01487 Bool enable_shmem_images (){return False; }
01488 void disable_shmem_images(){}
01489 void *check_XImage_shared( XImage *xim ) {return NULL ; }
01490 
01491 Bool ASPutXImage( ASVisual *asv, Drawable d, GC gc, XImage *xim,
01492                   int src_x, int src_y, int dest_x, int dest_y,
01493                                   unsigned int width, unsigned int height )
01494 {
01495 #ifndef X_DISPLAY_MISSING
01496         if( xim == NULL || asv == NULL )
01497                 return False ;
01498         return XPutImage( asv->dpy, d, gc, xim, src_x, src_y, dest_x, dest_y,width, height );
01499 #else
01500         return False;
01501 #endif
01502 }
01503 
01504 XImage * ASGetXImage( ASVisual *asv, Drawable d,
01505                   int x, int y, unsigned int width, unsigned int height,
01506                                   unsigned long plane_mask )
01507 {
01508 #ifndef X_DISPLAY_MISSING
01509         if( asv == NULL || d == None )
01510                 return NULL ;
01511         return XGetImage( asv->dpy, d, x, y, width, height, plane_mask, ZPixmap );
01512 #else
01513         return NULL ;
01514 #endif  
01515 }
01516 
01517 #endif                                         /* XSHMIMAGE */
01518 
01519 #ifndef X_DISPLAY_MISSING
01520 int
01521 My_XDestroyImage (XImage *ximage)
01522 {
01523         if( !release_scratch_data(ximage->data) )
01524                 if (ximage->data != NULL)
01525                         free (ximage->data);
01526         if (ximage->obdata != NULL)
01527                 free (ximage->obdata);
01528         XFree (ximage);
01529         return 1;
01530 }
01531 #endif /*ifndef X_DISPLAY_MISSING */
01532 
01533 
01534 XImage*
01535 create_visual_ximage( ASVisual *asv, unsigned int width, unsigned int height, unsigned int depth )
01536 {
01537 #ifndef X_DISPLAY_MISSING
01538         register XImage *ximage = NULL;
01539         unsigned long dsize;
01540         char         *data;
01541         int unit ;
01542 
01543         if( asv == NULL )
01544                 return NULL;
01545 
01546 #if 0
01547         unit = asv->dpy->bitmap_unit;
01548 #else
01549         if( depth == 0 ) 
01550                 unit = (asv->true_depth+7)&0x0038;
01551         else
01552                 unit = (depth+7)&0x0038;
01553         if( unit == 24 )
01554                 unit = 32 ;
01555 #endif
01556 #ifdef XSHMIMAGE
01557         if( _as_use_shm_images && width*height > 4000 )
01558         {
01559                 XShmSegmentInfo *shminfo = safecalloc( 1, sizeof(XShmSegmentInfo));
01560 
01561                 ximage = XShmCreateImage (asv->dpy, asv->visual_info.visual,
01562                                               (depth==0)?asv->visual_info.depth/*true_depth*/:depth,
01563                                                                   ZPixmap, NULL, shminfo,
01564                                                                   MAX(width,(unsigned int)1), MAX(height,(unsigned int)1));
01565                 if( ximage == NULL )
01566                         free( shminfo );
01567                 else
01568                 {
01569                         shminfo->shmaddr = ximage->data = get_shm_area( ximage->bytes_per_line * ximage->height, &(shminfo->shmid) );
01570                         if( shminfo->shmid == -1 )
01571                         {
01572                                 static int shmem_failure_count = 0 ;
01573                             show_warning( "unable to allocate %d bytes of shared image memory", ximage->bytes_per_line * ximage->height ) ;
01574                                 if( ximage->bytes_per_line * ximage->height < 100000 || ++shmem_failure_count > 10 )
01575                                 {
01576                                         show_error( "too many shared memory failures - disabling" ) ;
01577                                         _as_use_shm_images = False ;
01578                                 }
01579                                 free( shminfo );
01580                                 shminfo = NULL ;
01581                                 XFree( ximage );
01582                                 ximage = NULL ;
01583                         }else
01584                         {
01585                                 shminfo->readOnly = False;
01586                                 XShmAttach (asv->dpy, shminfo);
01587                                 registerXShmImage( asv, ximage, shminfo );
01588                         }
01589                 }
01590         }
01591 #endif
01592         if( ximage == NULL )
01593         {
01594                 ximage = XCreateImage (asv->dpy, asv->visual_info.visual, (depth==0)?asv->visual_info.depth/*true_depth*/:depth, ZPixmap, 0, NULL, MAX(width,(unsigned int)1), MAX(height,(unsigned int)1),
01595                                                         unit, 0);
01596                 if (ximage != NULL)
01597                 {
01598                         _XInitImageFuncPtrs (ximage);
01599                         ximage->obdata = NULL;
01600                         ximage->f.destroy_image = My_XDestroyImage;
01601                         dsize = ximage->bytes_per_line*ximage->height;
01602                 if (((data = (char *)safemalloc (dsize)) == NULL) && (dsize > 0))
01603                         {
01604                                 XFree ((char *)ximage);
01605                                 return (XImage *) NULL;
01606                         }
01607                         ximage->data = data;
01608                 }
01609         }
01610         return ximage;
01611 #else
01612         return NULL ;
01613 #endif /*ifndef X_DISPLAY_MISSING */
01614 }
01615 /* this is the vehicle to use static allocated buffer for temporary XImages 
01616  * in order to reduce XImage meory allocation overhead */
01617 XImage*
01618 create_visual_scratch_ximage( ASVisual *asv, unsigned int width, unsigned int height, unsigned int depth )
01619 {
01620 #ifndef X_DISPLAY_MISSING
01621         register XImage *ximage = NULL;
01622         char         *data;
01623         int unit ;
01624 
01625         if( asv == NULL )
01626                 return NULL;
01627 
01628 #if 0
01629         unit = asv->dpy->bitmap_unit;
01630 #else
01631         if( depth == 0 )
01632                 unit = (asv->true_depth+7)&0x0038;
01633         else
01634                 unit = (depth+7)&0x0038;
01635         if( unit == 24 )
01636                 unit = 32 ;
01637 #endif
01638 
01639         /* for shared memory XImage we already do caching - no need for scratch ximage */          
01640 #ifdef XSHMIMAGE
01641         if( _as_use_shm_images )
01642                 return create_visual_ximage( asv, width, height, depth );
01643 #endif
01644                    
01645         if( ximage == NULL )
01646         {
01647                 ximage = XCreateImage (asv->dpy, asv->visual_info.visual, 
01648                                            (depth==0)?asv->visual_info.depth/*true_depth*/:depth, ZPixmap, 
01649                                                            0, NULL, MAX(width,(unsigned int)1), MAX(height,(unsigned int)1),
01650                                                            unit, 0);
01651                 if (ximage != NULL)
01652                 {
01653                         data = get_scratch_data(ximage->bytes_per_line * ximage->height);
01654                         if( data == NULL ) 
01655                         {
01656                                 XFree ((char *)ximage); 
01657                                 return create_visual_ximage( asv, width, height, depth );/* fall back */
01658                         }        
01659                         _XInitImageFuncPtrs (ximage);
01660                         ximage->obdata = NULL;
01661                         ximage->f.destroy_image = My_XDestroyImage;
01662                         ximage->data = data;
01663                 }
01664         }
01665         return ximage;
01666 #else
01667         return NULL ;
01668 #endif /*ifndef X_DISPLAY_MISSING */
01669 }
01670 
01671 
01672 
01673 /****************************************************************************/
01674 /* Color manipulation functions :                                           */
01675 /****************************************************************************/
01676 
01677 
01678 /* misc function to calculate number of bits/shifts */
01679 #ifndef X_DISPLAY_MISSING
01680 static int
01681 get_shifts (unsigned long mask)
01682 {
01683         register int  i = 1;
01684 
01685         while (mask >> i)
01686                 i++;
01687 
01688         return i - 1;                                                      /* can't be negative */
01689 }
01690 
01691 static int
01692 get_bits (unsigned long mask)
01693 {
01694         register int  i;
01695 
01696         for (i = 0; mask; mask >>= 1)
01697                 if (mask & 1)
01698                         i++;
01699 
01700         return i;                                                                  /* can't be negative */
01701 }
01702 #endif
01703 /***************************************************************************/
01704 /* Screen color format -> AS color format conversion ;                                     */
01705 /***************************************************************************/
01706 /***************************************************************************/
01707 /* Screen color format -> AS color format conversion ;                                     */
01708 /***************************************************************************/
01709 /* this functions convert encoded color values into real pixel values, and
01710  * return half of the quantization error so we can do error diffusion : */
01711 /* encoding scheme : 0RRRrrrr rrrrGGgg ggggggBB bbbbbbbb
01712  * where RRR, GG and BB are overflow bits so we can do all kinds of funky
01713  * combined adding, note that we don't use 32'd bit as it is a sign bit */
01714 
01715 #ifndef X_DISPLAY_MISSING
01716 static inline void
01717 query_pixel_color( ASVisual *asv, unsigned long pixel, CARD32 *r, CARD32 *g, CARD32 *b )
01718 {
01719         XColor xcol ;
01720         xcol.flags = DoRed|DoGreen|DoBlue ;
01721         xcol.pixel = pixel ;
01722         if( XQueryColor( asv->dpy, asv->colormap, &xcol ) != 0 )
01723         {
01724                 *r = xcol.red>>8 ;
01725                 *g = xcol.green>>8 ;
01726                 *b = xcol.blue>>8 ;
01727         }
01728 }
01729 #endif /*ifndef X_DISPLAY_MISSING */
01730 
01731 
01732 CARD32 color2pixel32bgr(ASVisual *asv, CARD32 encoded_color, unsigned long *pixel)
01733 {
01734         *pixel = ARGB32_RED8(encoded_color)|(ARGB32_GREEN8(encoded_color)<<8)|(ARGB32_BLUE8(encoded_color)<<16);
01735         return 0;
01736 }
01737 CARD32 color2pixel32rgb(ASVisual *asv, CARD32 encoded_color, unsigned long *pixel)
01738 {
01739         *pixel = encoded_color&0x00FFFFFF;
01740         return 0;
01741 }
01742 CARD32 color2pixel24bgr(ASVisual *asv, CARD32 encoded_color, unsigned long *pixel)
01743 {
01744         *pixel = encoded_color&0x00FFFFFF;
01745         return 0;
01746 }
01747 CARD32 color2pixel24rgb(ASVisual *asv, CARD32 encoded_color, unsigned long *pixel)
01748 {
01749         *pixel = encoded_color&0x00FFFFFF;
01750         return 0;
01751 }
01752 CARD32 color2pixel16bgr(ASVisual *asv, CARD32 encoded_color, unsigned long *pixel)
01753 {
01754         register CARD32 c = encoded_color ;
01755     *pixel = ((c&0x000000F8)<<8)|((c&0x0000FC00)>>5)|((c&0x00F80000)>>19);
01756         return (c>>1)&0x00030103;
01757 }
01758 CARD32 color2pixel16rgb(ASVisual *asv, CARD32 encoded_color, unsigned long *pixel)
01759 {
01760         register CARD32 c = encoded_color ;
01761     *pixel = ((c&0x00F80000)>>8)|((c&0x0000FC00)>>5)|((c&0x000000F8)>>3);
01762         return (c>>1)&0x00030103;
01763 }
01764 CARD32 color2pixel15bgr(ASVisual *asv, CARD32 encoded_color, unsigned long *pixel)
01765 {
01766         register CARD32 c = encoded_color ;
01767     *pixel = ((c&0x000000F8)<<7)|((c&0x0000F800)>>6)|((c&0x00F80000)>>19);
01768         return (c>>1)&0x00030303;
01769 }
01770 CARD32 color2pixel15rgb(ASVisual *asv, CARD32 encoded_color, unsigned long *pixel)
01771 {
01772         register CARD32 c = encoded_color ;
01773     *pixel = ((c&0x00F80000)>>9)|((c&0x0000F800)>>6)|((c&0x000000F8)>>3);
01774         return (c>>1)&0x00030303;
01775 }
01776 
01777 CARD32 color2pixel_pseudo3bpp( ASVisual *asv, CARD32 encoded_color, unsigned long *pixel )
01778 {
01779         register CARD32 c = encoded_color ;
01780         *pixel = asv->as_colormap[((c>>25)&0x0008)|((c>>16)&0x0002)|((c>>7)&0x0001)];
01781         return (c>>1)&0x003F3F3F;
01782 }
01783 
01784 CARD32 color2pixel_pseudo6bpp( ASVisual *asv, CARD32 encoded_color, unsigned long *pixel )
01785 {
01786         register CARD32 c = encoded_color ;
01787         *pixel = asv->as_colormap[((c>>22)&0x0030)|((c>>14)&0x000C)|((c>>6)&0x0003)];
01788         return (c>>1)&0x001F1F1F;
01789 }
01790 
01791 CARD32 color2pixel_pseudo12bpp( ASVisual *asv, CARD32 encoded_color, unsigned long *pixel )
01792 {
01793         register CARD32 c = encoded_color ;
01794         *pixel = asv->as_colormap[((c>>16)&0x0F00)|((c>>10)&0x00F0)|((c>>4)&0x000F)];
01795         return (c>>1)&0x00070707;
01796 }
01797 
01798 void pixel2color32rgb(ASVisual *asv, unsigned long pixel, CARD32 *red, CARD32 *green, CARD32 *blue)
01799 {}
01800 void pixel2color32bgr(ASVisual *asv, unsigned long pixel, CARD32 *red, CARD32 *green, CARD32 *blue)
01801 {}
01802 void pixel2color24rgb(ASVisual *asv, unsigned long pixel, CARD32 *red, CARD32 *green, CARD32 *blue)
01803 {}
01804 void pixel2color24bgr(ASVisual *asv, unsigned long pixel, CARD32 *red, CARD32 *green, CARD32 *blue)
01805 {}
01806 void pixel2color16rgb(ASVisual *asv, unsigned long pixel, CARD32 *red, CARD32 *green, CARD32 *blue)
01807 {}
01808 void pixel2color16bgr(ASVisual *asv, unsigned long pixel, CARD32 *red, CARD32 *green, CARD32 *blue)
01809 {}
01810 void pixel2color15rgb(ASVisual *asv, unsigned long pixel, CARD32 *red, CARD32 *green, CARD32 *blue)
01811 {}
01812 void pixel2color15bgr(ASVisual *asv, unsigned long pixel, CARD32 *red, CARD32 *green, CARD32 *blue)
01813 {}
01814 
01815 void ximage2scanline32(ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
01816 {
01817         register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
01818         register CARD32 *a = sl->alpha+sl->offset_x;
01819         int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x);
01820         register CARD32 *src = (CARD32*)xim_data ;
01821 /*      src += sl->offset_x; */
01822 /*fprintf( stderr, "%d: ", y);*/
01823 
01824 #ifdef WORDS_BIGENDIAN
01825         if( !asv->msb_first )
01826 #else
01827         if( asv->msb_first )
01828 #endif
01829         {
01830                 while (--i >= 0)
01831                 {
01832                         b[i] = (src[i]>>24)&0x0ff;
01833                         g[i] = (src[i]>>16)&0x0ff;
01834                         r[i] = (src[i]>>8)&0x0ff;
01835                         a[i] = src[i]&0x0ff;
01836 /*                      fprintf( stderr, "[%d->%8.8X %8.8X %8.8X %8.8X = %8.8X]", i, r[i], g[i], b[i], a[i], src[i]);*/
01837                 }
01838         }else
01839         {
01840                 while (--i >= 0)
01841                 {
01842                         a[i] = (src[i]>>24)&0x0ff;
01843                         r[i] = (src[i]>>16)&0x0ff;
01844                         g[i] = (src[i]>>8)&0x0ff;
01845                         b[i] =  src[i]&0x0ff;
01846                 }
01847         }
01848 /*fprintf( stderr, "\n");*/
01849 }
01850 
01851 void ximage2scanline16( ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
01852 {
01853         register int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x)-1;
01854         register CARD16 *src = (CARD16*)xim_data ;
01855     register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
01856 #ifdef WORDS_BIGENDIAN
01857         if( !asv->msb_first )
01858 #else
01859         if( asv->msb_first )
01860 #endif
01861                 do
01862                 {
01863 #define ENCODE_MSBF_565(r,gh3,gl3,b)    (((gh3)&0x0007)|((gl3)&0xE000)|((r)&0x00F8)|((b)&0x1F00))
01864                         r[i] =  (src[i]&0x00F8);
01865                         g[i] = ((src[i]&0x0007)<<5)|((src[i]&0xE000)>>11);
01866                         b[i] =  (src[i]&0x1F00)>>5;
01867                 }while( --i >= 0);
01868         else
01869                 do
01870                 {
01871 #define ENCODE_LSBF_565(r,g,b) (((g)&0x07E0)|((r)&0xF800)|((b)&0x001F))
01872                         r[i] =  (src[i]&0xF800)>>8;
01873                         g[i] =  (src[i]&0x07E0)>>3;
01874                         b[i] =  (src[i]&0x001F)<<3;
01875                 }while( --i >= 0);
01876 
01877 }
01878 void ximage2scanline15( ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
01879 {
01880         register int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x)-1;
01881         register CARD16 *src = (CARD16*)xim_data ;
01882     register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
01883 #ifdef WORDS_BIGENDIAN
01884         if( !asv->msb_first )
01885 #else
01886         if( asv->msb_first )
01887 #endif
01888                 do
01889                 {
01890 #define ENCODE_MSBF_555(r,gh2,gl3,b)    (((gh2)&0x0003)|((gl3)&0xE000)|((r)&0x007C)|((b)&0x1F00))
01891                         r[i] =  (src[i]&0x007C)<<1;
01892                         g[i] = ((src[i]&0x0003)<<6)|((src[i]&0xE000)>>10);
01893                         b[i] =  (src[i]&0x1F00)>>5;
01894                 }while( --i >= 0);
01895         else
01896                 do
01897                 {
01898 #define ENCODE_LSBF_555(r,g,b) (((g)&0x03E0)|((r)&0x7C00)|((b)&0x001F))
01899                         r[i] =  (src[i]&0x7C00)>>7;
01900                         g[i] =  (src[i]&0x03E0)>>2;
01901                         b[i] =  (src[i]&0x001F)<<3;
01902                 }while( --i >= 0);
01903 }
01904 
01905 #ifndef X_DISPLAY_MISSING
01906 
01907 void
01908 ximage2scanline_pseudo3bpp( ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
01909 {
01910         register int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x)-1;
01911     register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
01912 
01913         do
01914         {
01915                 unsigned long pixel = XGetPixel( xim, i, y );
01916                 ARGB32 c = asv->as_colormap_reverse.xref[pixel] ;
01917                 if( c == 0 )
01918                         query_pixel_color( asv, pixel, r+i, g+i, b+i );
01919                 else
01920                 {
01921                         r[i] =  ARGB32_RED8(c);
01922                         g[i] =  ARGB32_GREEN8(c);
01923                         b[i] =  ARGB32_BLUE8(c);
01924                 }
01925         }while( --i >= 0);
01926 
01927 }
01928 
01929 void
01930 ximage2scanline_pseudo6bpp( ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
01931 {
01932         register int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x)-1;
01933     register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
01934 
01935         if( xim->bits_per_pixel == 8 )
01936         {
01937                 register CARD8 *src = (CARD8*)xim_data ;
01938                 do
01939                 {
01940                         ARGB32 c = asv->as_colormap_reverse.xref[src[i]] ;
01941                         if( c == 0 )
01942                                 query_pixel_color( asv, src[i], r+i, g+i, b+i );
01943                         else
01944                         {
01945                                 r[i] =  ARGB32_RED8(c);
01946                                 g[i] =  ARGB32_GREEN8(c);
01947                                 b[i] =  ARGB32_BLUE8(c);
01948                         }
01949                 }while( --i >= 0);
01950 
01951         }else
01952                 do
01953                 {
01954                         unsigned long pixel = XGetPixel( xim, i, y );
01955                         ARGB32 c = asv->as_colormap_reverse.xref[pixel] ;
01956                         if( c == 0 )
01957                                 query_pixel_color( asv, pixel, r+i, g+i, b+i );
01958                         else
01959                         {
01960                                 r[i] =  ARGB32_RED8(c);
01961                                 g[i] =  ARGB32_GREEN8(c);
01962                                 b[i] =  ARGB32_BLUE8(c);
01963                         }
01964                 }while( --i >= 0);
01965 }
01966 
01967 void
01968 ximage2scanline_pseudo12bpp( ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
01969 {
01970         register int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x)-1;
01971     register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
01972 
01973         if( xim->bits_per_pixel == 16 )
01974         {
01975                 register CARD16 *src = (CARD16*)xim_data ;
01976                 do
01977                 {
01978             ASHashData hdata ;
01979             ARGB32 c ;
01980             if( get_hash_item( asv->as_colormap_reverse.hash, AS_HASHABLE((unsigned long)src[i]), &hdata.vptr ) != ASH_Success )
01981                                 query_pixel_color( asv, src[i], r+i, g+i, b+i );
01982                         else
01983                         {
01984                 c = hdata.c32;
01985                                 r[i] =  ARGB32_RED8(c);
01986                                 g[i] =  ARGB32_GREEN8(c);
01987                                 b[i] =  ARGB32_BLUE8(c);
01988                         }
01989                 }while( --i >= 0);
01990 
01991         }else
01992                 do
01993                 {
01994                         unsigned long pixel = XGetPixel( xim, i, y );
01995             ASHashData hdata ;
01996                         ARGB32 c ;
01997             if( get_hash_item( asv->as_colormap_reverse.hash, (ASHashableValue)pixel, &hdata.vptr ) != ASH_Success )
01998                                 query_pixel_color( asv, pixel, r+i, g+i, b+i );
01999                         else
02000                         {
02001                 c = hdata.c32;
02002                                 r[i] =  ARGB32_RED8(c);
02003                                 g[i] =  ARGB32_GREEN8(c);
02004                                 b[i] =  ARGB32_BLUE8(c);
02005                         }
02006                 }while( --i >= 0);
02007 }
02008 #endif
02009 
02010 void scanline2ximage32( ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
02011 {
02012         register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
02013         register CARD32 *a = sl->alpha+sl->offset_x;
02014         register int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x);
02015         register CARD32 *src = (CARD32*)xim_data;
02016 /*      src += sl->offset_x ; */
02017 /*fprintf( stderr, "%d: ", y);*/
02018 #ifdef WORDS_BIGENDIAN
02019         if( !asv->msb_first )
02020 #else
02021         if( asv->msb_first )
02022 #endif
02023                 while( --i >= 0)
02024                 { 
02025                         src[i] = (b[i]<<24)|(g[i]<<16)|(r[i]<<8)|a[i];
02026 /*                      fprintf( stderr, "[%d->%8.8X %8.8X %8.8X %8.8X = %8.8X]", i, r[i], g[i], b[i], a[i], src[i]);  */
02027                 }
02028         else
02029                 while( --i >= 0) src[i] = (a[i]<<24)|(r[i]<<16)|(g[i]<<8)|b[i];
02030 /*fprintf( stderr, "\n");*/
02031 #ifdef DEBUG_SL2XIMAGE
02032         i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x);
02033         src = (CARD32*)xim_data;
02034         src += sl->offset_x;
02035         printf( "%d: xim->width = %d, sl->width = %d, sl->offset = %d: ", y, xim->width, sl->width, sl->offset_x );
02036         while(--i>=0 )  printf( "%8.8lX ", src[i] );
02037         printf( "\n" );
02038 #endif
02039 }
02040 
02041 void scanline2ximage16( ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
02042 {
02043         register int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x)-1;
02044         register CARD16 *src = (CARD16*)xim_data ;
02045     register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
02046         register CARD32 c = (r[i]<<20) | (g[i]<<10) | (b[i]);
02047 #ifdef WORDS_BIGENDIAN
02048         if( !asv->msb_first )
02049 #else
02050         if( asv->msb_first )
02051 #endif
02052                 do
02053                 {
02054                         src[i] = ENCODE_MSBF_565((c>>20),(c>>15),(c<<1),(c<<5));
02055                         if( --i < 0 )
02056                                 break;
02057                         /* carry over quantization error allow for error diffusion:*/
02058                         c = ((c>>1)&0x00300403)+((r[i]<<20) | (g[i]<<10) | (b[i]));
02059                         {
02060                                 register CARD32 d = c&0x300C0300 ;
02061                                 if( d )
02062                                 {
02063                                         if( c&0x30000000 )
02064                                                 d |= 0x0FF00000;
02065                                         if( c&0x000C0000 )
02066                                                 d |= 0x0003FC00 ;
02067                                         if( c&0x00000300 )
02068                                                 d |= 0x000000FF ;
02069                                         c ^= d;
02070                                 }
02071 /*fprintf( stderr, "c = 0x%X, d = 0x%X, c^d = 0x%X\n", c, d, c^d );*/
02072                         }
02073                 }while(1);
02074         else
02075                 do
02076                 {
02077                         src[i] = ENCODE_LSBF_565((c>>12),(c>>7),(c>>3));
02078                         if( --i < 0 )
02079                                 break;
02080                         /* carry over quantization error allow for error diffusion:*/
02081                         c = ((c>>1)&0x00300403)+((r[i]<<20) | (g[i]<<10) | (b[i]));
02082                         {
02083                                 register CARD32 d = c&0x300C0300 ;
02084                                 if( d )
02085                                 {
02086                                         if( c&0x30000000 )
02087                                                 d |= 0x0FF00000;
02088                                         if( c&0x000C0000 )
02089                                                 d |= 0x0003FC00 ;
02090                                         if( c&0x00000300 )
02091                                                 d |= 0x000000FF ;
02092                                         c ^= d;
02093                                 }
02094 /*fprintf( stderr, "c = 0x%X, d = 0x%X, c^d = 0x%X\n", c, d, c^d );*/
02095                         }
02096                 }while(1);
02097 }
02098 
02099 void scanline2ximage15( ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
02100 {
02101         register int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x)-1;
02102         register CARD16 *src = (CARD16*)xim_data ;
02103     register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
02104         register CARD32 c = (r[i]<<20) | (g[i]<<10) | (b[i]);
02105 #ifdef WORDS_BIGENDIAN
02106         if( !asv->msb_first )
02107 #else
02108         if( asv->msb_first )
02109 #endif
02110                 do
02111                 {
02112                         src[i] = ENCODE_MSBF_555((c>>21),(c>>16),c/*(c>>2)*/,(c<<5));
02113                         if( --i < 0 )
02114                                 break;
02115                         /* carry over quantization error allow for error diffusion:*/
02116                         c = ((c>>1)&0x00300C03)+((r[i]<<20) | (g[i]<<10) | (b[i]));
02117 /*fprintf( stderr, "%s:%d src[%d] = 0x%4.4X, c = 0x%X, color[%d] = #%2.2X%2.2X%2.2X\n", __FUNCTION__, __LINE__, i+1, src[i+1], c, i, r[i], g[i], b[i]);*/
02118                         {
02119                                 register CARD32 d = c&0x300C0300 ;
02120                                 if( d )
02121                                 {
02122                                         if( c&0x30000000 )
02123                                                 d |= 0x0FF00000;
02124                                         if( c&0x000C0000 )
02125                                                 d |= 0x0003FC00 ;
02126                                         if( c&0x00000300 )
02127                                                 d |= 0x000000FF ;
02128                                         c ^= d;
02129                                 }
02130 /*fprintf( stderr, "%s:%d c = 0x%X, d = 0x%X, c^d = 0x%X\n", __FUNCTION__, __LINE__, c, d, c^d );*/
02131                         }
02132                 }while(1);
02133         else
02134         {
02135                 do
02136                 {
02137                         src[i] = ENCODE_LSBF_555((c>>13),(c>>8),(c>>3));
02138                         if( --i < 0 )
02139                                 break;
02140                         /* carry over quantization error allow for error diffusion:*/
02141                         c = ((c>>1)&0x00300C03)+((r[i]<<20) | (g[i]<<10) | (b[i]));
02142                         {
02143                                 register CARD32 d = c&0x300C0300 ;
02144                                 if( d )
02145                                 {
02146                                         if( c&0x30000000 )
02147                                                 d |= 0x0FF00000;
02148                                         if( c&0x000C0000 )
02149                                                 d |= 0x0003FC00 ;
02150                                         if( c&0x00000300 )
02151                                                 d |= 0x000000FF ;
02152                                         c ^= d;
02153                                 }
02154                         }
02155                 }while(1);
02156         }
02157 }
02158 
02159 #ifndef X_DISPLAY_MISSING
02160 void
02161 scanline2ximage_pseudo3bpp( ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
02162 {
02163         register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
02164         register int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x)-1;
02165         register CARD32 c = (r[i]<<20) | (g[i]<<10) | (b[i]);
02166 
02167         do
02168         {
02169                 XPutPixel( xim, i, y, asv->as_colormap[((c>>25)&0x0008)|((c>>16)&0x0002)|((c>>7)&0x0001)] );
02170                 if( --i < 0 )
02171                         break;
02172                 c = ((c>>1)&0x03F0FC3F)+((r[i]<<20) | (g[i]<<10) | (b[i]));
02173                 {/* handling possible overflow : */
02174                         register CARD32 d = c&0x300C0300 ;
02175                         if( d )
02176                         {
02177                                 if( c&0x30000000 )
02178                                         d |= 0x0FF00000;
02179                                 if( c&0x000C0000 )
02180                                         d |= 0x0003FC00 ;
02181                                 if( c&0x00000300 )
02182                                         d |= 0x000000FF ;
02183                                 c ^= d;
02184                         }
02185                 }
02186         }while(i);
02187 }
02188 
02189 void
02190 scanline2ximage_pseudo6bpp( ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
02191 {
02192         register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
02193         register int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x)-1;
02194         register CARD32 c = (r[i]<<20) | (g[i]<<10) | (b[i]);
02195 
02196         if( xim->bits_per_pixel == 8 )
02197         {
02198                 register CARD8 *dst = (CARD8*)xim_data ;
02199                 do
02200                 {
02201                         dst[i] = asv->as_colormap[((c>>22)&0x0030)|((c>>14)&0x000C)|((c>>6)&0x0003)];
02202                         if( --i < 0 )
02203                                 break;
02204                         c = ((c>>1)&0x01F07C1F)+((r[i]<<20) | (g[i]<<10) | (b[i]));
02205                         {/* handling possible overflow : */
02206                                 register CARD32 d = c&0x300C0300 ;
02207                                 if( d )
02208                                 {
02209                                         if( c&0x30000000 )
02210                                                 d |= 0x0FF00000;
02211                                         if( c&0x000C0000 )
02212                                                 d |= 0x0003FC00 ;
02213                                         if( c&0x00000300 )
02214                                                 d |= 0x000000FF ;
02215                                         c ^= d;
02216                                 }
02217                         }
02218                 }while(i);
02219         }else
02220         {
02221                 do
02222                 {
02223                         XPutPixel( xim, i, y, asv->as_colormap[((c>>22)&0x0030)|((c>>14)&0x000C)|((c>>6)&0x0003)] );
02224                         if( --i < 0 )
02225                                 break;
02226                         c = ((c>>1)&0x01F07C1F)+((r[i]<<20) | (g[i]<<10) | (b[i]));
02227                         {/* handling possible overflow : */
02228                                 register CARD32 d = c&0x300C0300 ;
02229                                 if( d )
02230                                 {
02231                                         if( c&0x30000000 )
02232                                                 d |= 0x0FF00000;
02233                                         if( c&0x000C0000 )
02234                                                 d |= 0x0003FC00 ;
02235                                         if( c&0x00000300 )
02236                                                 d |= 0x000000FF ;
02237                                         c ^= d;
02238                                 }
02239                         }
02240                 }while(i);
02241         }
02242 }
02243 
02244 void
02245 scanline2ximage_pseudo12bpp( ASVisual *asv, XImage *xim, ASScanline *sl, int y,  register unsigned char *xim_data )
02246 {
02247         register CARD32 *r = sl->xc1+sl->offset_x, *g = sl->xc2+sl->offset_x, *b = sl->xc3+sl->offset_x;
02248         register int i = MIN((unsigned int)(xim->width),sl->width-sl->offset_x)-1;
02249         register CARD32 c = (r[i]<<20) | (g[i]<<10) | (b[i]);
02250 
02251         if( xim->bits_per_pixel == 16 )
02252         {
02253                 register CARD16 *dst = (CARD16*)xim_data ;
02254                 do
02255                 {
02256                         dst[i] = asv->as_colormap[((c>>16)&0x0F00)|((c>>10)&0x00F0)|((c>>4)&0x000F)];
02257                         if( --i < 0 )
02258                                 break;
02259                         c = ((c>>1)&0x00701C07)+((r[i]<<20) | (g[i]<<10) | (b[i]));
02260                         {/* handling possible overflow : */
02261                                 register CARD32 d = c&0x300C0300 ;
02262                                 if( d )
02263                                 {
02264                                         if( c&0x30000000 )
02265                                                 d |= 0x0FF00000;
02266                                         if( c&0x000C0000 )
02267                                                 d |= 0x0003FC00 ;
02268                                         if( c&0x00000300 )
02269                                                 d |= 0x000000FF ;
02270                                         c ^= d;
02271                                 }
02272                         }
02273                 }while(i);
02274         }else
02275         {
02276                 do
02277                 {
02278                         XPutPixel( xim, i, y, asv->as_colormap[((c>>16)&0x0F00)|((c>>10)&0x00F0)|((c>>4)&0x000F)] );
02279                         if( --i < 0 )
02280                                 break;
02281                         c = ((c>>1)&0x00701C07)+((r[i]<<20) | (g[i]<<10) | (b[i]));
02282                         {/* handling possible overflow : */
02283                                 register CARD32 d = c&0x300C0300 ;
02284                                 if( d )
02285                                 {
02286                                         if( c&0x30000000 )
02287                                                 d |= 0x0FF00000;
02288                                         if( c&0x000C0000 )
02289                                                 d |= 0x0003FC00 ;
02290                                         if( c&0x00000300 )
02291                                                 d |= 0x000000FF ;
02292                                         c ^= d;
02293                                 }
02294                         }
02295                 }while(i);
02296         }
02297 }
02298 
02299 #endif /* ifndef X_DISPLAY_MISSING */
02300 

Generated on Tue Jul 5 14:13:27 2011 for ROOT_528-00b_version by  doxygen 1.5.1