home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / educatio / xcoral16.zip / SHADOW.C < prev    next >
C/C++ Source or Header  |  1993-01-15  |  8KB  |  295 lines

  1. /*
  2. ** Copyright 1989, 1992 by Lionel Fournigault
  3. **
  4. ** Permission to use, copy, and distribute for non-commercial purposes,
  5. ** is hereby granted without fee, providing that the above copyright
  6. ** notice appear in all copies and that both the copyright notice and this
  7. ** permission notice appear in supporting documentation.
  8. ** The software may be modified for your own purposes, but modified versions
  9. ** may not be distributed.
  10. ** This software is provided "as is" without any expressed or implied warranty.
  11. **
  12. **
  13. */
  14.  
  15. #include <X11/Xlib.h>
  16. #include <stdio.h>
  17.  
  18. static char gray_bits[] = {0x01, 0x02 };
  19.  
  20. #define gray_width         2
  21. #define gray_height         2
  22. #define UP            0       
  23.        
  24. static unsigned long fg_pixel, bg_pixel;       
  25. static GC    relief_gc;
  26. Pixmap        pixmap;
  27.  
  28. /*
  29. **    Function name : CreateRGC
  30. **
  31. **    Description : Creation du contexte graphique pour le relief.
  32. **    Input : Le display.
  33. **    Ouput :
  34. */
  35. void CreateRGC ( display )
  36.     Display *display;
  37. {
  38.     GC         gc;
  39.     XGCValues    gcv;
  40.     unsigned long     mask;
  41.     XColor        tcolor, color;
  42.     int         screen;
  43.     
  44.     screen = DefaultScreen ( display );
  45.  
  46.     mask = GCBackground | GCForeground | GCFunction;
  47.     gcv.function = GXcopy;
  48.  
  49.     if ( DefaultDepth ( display, screen ) == 1 ) {
  50.         /*
  51.          * Monochrome
  52.          */
  53.         pixmap = XCreatePixmapFromBitmapData ( display, 
  54.                  DefaultRootWindow (display),
  55.                 gray_bits, gray_width, gray_height,
  56.                 BlackPixel ( display, screen ),
  57.                 WhitePixel ( display, screen ), 1 );
  58.  
  59.         fg_pixel = WhitePixel ( display, screen );
  60.         bg_pixel = BlackPixel ( display, screen );
  61.     
  62.         gcv.background = bg_pixel;
  63.         gcv.foreground = fg_pixel;
  64.  
  65.         gcv.tile = pixmap;
  66.         gcv.fill_style = FillTiled;
  67.         mask |= GCFillStyle | GCTile;        
  68.     }
  69.     else {
  70.         /*
  71.          * color
  72.          */
  73.     
  74.         XAllocNamedColor ( display, DefaultColormap ( display, screen ),
  75.             "white", &color, &tcolor );
  76.         
  77.         gcv.foreground = color.pixel;
  78.         fg_pixel = color.pixel;
  79.         
  80.         XAllocNamedColor ( display, DefaultColormap ( display, screen ),
  81.             "dim gray", &color, &tcolor );
  82.         
  83.         gcv.background = color.pixel;
  84.         bg_pixel = color.pixel;
  85.  
  86.         gcv.fill_style = FillSolid;
  87.         mask |= GCFillStyle;
  88.     }
  89.     gc = XCreateGC ( display, DefaultRootWindow (display), mask, &gcv );
  90.     XSetLineAttributes ( display, gc, 2, LineSolid, CapButt, JoinMiter );
  91.     relief_gc = gc;
  92. }
  93.  
  94.  
  95.  
  96. /*
  97. **    Function name : Display3D
  98. **
  99. **    Description : Affiche le top et le bottom shadow.
  100. **    Input : Le display, la fenetre.
  101. **    Ouput :
  102. */
  103. void Display3D ( display, window, top, bottom, size, direct )
  104.     Display        *display;
  105.     Window        window;
  106.     unsigned long   top, bottom;
  107.     register        int size, direct;
  108. {
  109.     XWindowAttributes att;
  110.     XGCValues    gcv;
  111.     XRectangle     rec [10];
  112.     XPoint        points [10];
  113.     unsigned long     mask;
  114.  
  115. #ifdef DEBUG
  116.     fprintf ( stderr, "top = %d bot =%d\n", top, bottom );
  117. #endif
  118.  
  119.     if ( size == 0 ) return;
  120.  
  121.     XGetWindowAttributes ( display, window, &att );
  122.  
  123.     if ( size > att.width / 2 ) return;
  124.     
  125.     if ( direct == UP ) {
  126.             /* Les rectangles en haut et a gauche */
  127.         rec [0].x = 0;
  128.         rec [0].y = 0;
  129.         rec [0].width = att.width;
  130.         rec [0].height = size ;
  131.         rec [1].x = 0;
  132.         rec [1].y = size;
  133.         rec [1].width = size ;
  134.         rec [1].height = att.height - size;
  135.     }
  136.     else {
  137.         rec [0].x = 0;
  138.         rec [0].y = att.height - size;
  139.         rec [0].width = att.width;
  140.         rec [0].height = size;
  141.         rec [1].x = att.width - size;
  142.         rec [1].y = 0;
  143.         rec [1].width = size;
  144.         rec [1].height = att.height - size;
  145.     }
  146.     if ( DefaultDepth ( display, DefaultScreen ( display ) ) == 1 ) {
  147.            gcv.fill_style = FillTiled;
  148.            gcv.tile = pixmap;
  149.            gcv.foreground = fg_pixel; gcv.background = bg_pixel;
  150.            mask = GCFillStyle | GCTile | GCBackground | GCForeground;
  151.     }
  152.     else {
  153.            gcv.foreground = top; gcv.background = bottom;
  154.            gcv.fill_style = FillSolid;
  155.            mask = GCForeground | GCBackground | GCFillStyle;
  156.     }
  157.     XChangeGC ( display, relief_gc, mask, &gcv );
  158.  
  159.     XFillRectangles ( display, window, relief_gc, rec, 2 );
  160.     
  161.     if ( direct == UP ) { 
  162.             /* le polygone en bas et a droite */
  163.         points [0].x = att.width; points [0].y = 0;
  164.         points [1].x = att.width - size; points [1].y = size;
  165.         points [2].x = att.width - size; points [2].y = att.height - size;
  166.         points [3].x = size; points [3].y = att.height - size;
  167.         points [4].x = 0; points [4].y = att.height;
  168.         points [5].x = att.width; points [5].y = att.height;
  169.     }
  170.     else {
  171.             /* le polygone en haut et a gauche */
  172.         points [0].x = att.width; points [0].y = 0;
  173.         points [1].x = att.width - size; points [1].y = size;
  174.         points [2].x = size; points [2].y = size;
  175.         points [3].x = size; points [3].y = att.height - size;
  176.         points [4].x = 0; points [4].y = att.height;
  177.         points [5].x = 0; points [5].y = 0;
  178.     }
  179.  
  180.     /*
  181.      * On inverse le foreground et le background.
  182.      */
  183.     if ( DefaultDepth ( display, DefaultScreen ( display ) ) == 1 ) {
  184.            gcv.fill_style = FillSolid;
  185.            gcv.foreground = bg_pixel; gcv.background = fg_pixel;
  186.            mask = GCFillStyle | GCBackground | GCForeground;
  187.     }
  188.     else {
  189.            gcv.foreground = bottom; gcv.background = top;
  190.            gcv.fill_style = FillSolid;
  191.            mask = GCForeground | GCBackground | GCFillStyle;
  192.     }
  193.     XChangeGC ( display, relief_gc, mask, &gcv );
  194.  
  195.     XFillPolygon ( display,
  196.         window, relief_gc, points, 6, Nonconvex, CoordModeOrigin );
  197. }
  198.  
  199.  
  200. /*
  201. **    Function name : GetShadow
  202. **
  203. **    Description : Calcul des couleurs pour le top et le bottom shadow
  204. **        en fonction d'un couleur donnee.
  205. **    Input : Le display, la structure contenant la valeur en pixel
  206. **        de la couleur dont on veut calculer ts et bs.
  207. **        les valeurs de retour pour ts et bs.
  208. **    Ouput : 
  209. */
  210. void GetShadow ( display, xcolor, ts, bs )
  211.     Display *display;
  212.     register XColor *xcolor;
  213.     unsigned long *ts, *bs;    /* RETURN */
  214. {
  215.     register int depth;
  216.     Colormap cmap;
  217.     XColor  top_sh, bot_sh;
  218.     register int brightness;
  219.     float factor;
  220.     extern void exit ();
  221.  
  222.     depth = DisplayPlanes ( display, DefaultScreen ( display ));
  223.     cmap = DefaultColormap ( display, DefaultScreen ( display ));
  224.  
  225.        /* 
  226.         * Monochrome
  227.         */
  228.     if ( depth == 1 ) {  /* Black and White */
  229.         *ts = fg_pixel;
  230.         *bs = bg_pixel;
  231.         return;
  232.     }
  233.  
  234.     /*
  235.      * Couleur.
  236.      * Calcul de l'eclat : L'intensite intervient pour 1/4 et
  237.      * la luminosite pour 3/4
  238.      */
  239.     brightness = (0.25 * ((int) ((xcolor -> red + xcolor -> green + xcolor -> blue) / 3)) ) +
  240.         (0.75 * ((0.3 * xcolor -> red) + (0.59 * xcolor -> green) +(0.11 * xcolor -> blue )));
  241.  
  242.     /*
  243.      * Suivant la valeur de l'eclat par rapport a 2 seuils, on calcul
  244.      * le top et bottom shadow correspondant a la couleur de base.
  245.      */
  246. #define MAX    65535
  247. #define CLAIR    (0.75 * MAX)
  248. #define SOMBRE    (0.15 * MAX)
  249.     
  250.     if ( brightness < SOMBRE ) {
  251.         bot_sh.red = xcolor -> red + ((MAX - xcolor -> red) * 0.2 );
  252.         bot_sh.green= xcolor -> green + ((MAX - xcolor -> green) * 0.2 );
  253.         bot_sh.blue = xcolor -> blue + ((MAX - xcolor -> blue) * 0.2 );
  254.         top_sh.red = xcolor -> red + ((MAX - xcolor -> red) * 0.5);
  255.         top_sh.green= xcolor -> green + ((MAX - xcolor -> green) * 0.5);
  256.         top_sh.blue = xcolor -> blue + ((MAX - xcolor -> blue) * 0.5);
  257.     }
  258.     else if ( brightness > CLAIR ) {
  259.         bot_sh.red = xcolor -> red * 0.2;
  260.         bot_sh.green = xcolor -> green * 0.2;
  261.         bot_sh.blue = xcolor -> blue *  0.2;
  262.         top_sh.red = xcolor -> red * 0.95;
  263.         top_sh.green = xcolor -> green * 0.95;
  264.         top_sh.blue = xcolor -> blue * 0.95;
  265.     }
  266.     else {
  267.         factor =  ((0.60 - (brightness * ( 0.25 ) / MAX))); 
  268.  
  269.         bot_sh.red = xcolor -> red - (xcolor -> red * factor);
  270.         bot_sh.green = xcolor -> green - (xcolor -> green * factor);
  271.         bot_sh.blue = xcolor -> blue -(xcolor -> blue * factor);
  272.  
  273.         factor =  ((0.40 + (brightness * ( 0.30 ) / MAX))); 
  274.  
  275.         top_sh.red = xcolor -> red + ((MAX - xcolor -> red) * factor );
  276.         top_sh.green= xcolor -> green + ((MAX - xcolor -> green) * factor);
  277.         top_sh.blue = xcolor -> blue + ((MAX - xcolor -> blue) * factor );
  278.     }
  279.  
  280.     top_sh.pixel = 0;
  281.        bot_sh.pixel = 0;
  282.  
  283.     if ( XAllocColor ( display, cmap, &top_sh ) == 0 ) {
  284.         (void) fprintf ( stderr, "XAllocColor error\n" );
  285.               (void) exit (1);
  286.     }
  287.     *ts = top_sh.pixel;
  288.  
  289.     if ( XAllocColor ( display, cmap, &bot_sh ) == 0 ) {
  290.         (void) fprintf ( stderr, "XAllocColor error\n" );
  291.               (void) exit (1);      
  292.     }
  293.     *bs = bot_sh.pixel;
  294. }
  295.