x11_display.cpp
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:14k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * x11_display.cpp
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 VideoLAN
  5.  * $Id: x11_display.cpp 7858 2004-06-01 22:08:14Z asmax $
  6.  *
  7.  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
  8.  *          Olivier Teuli鑢e <ipkiss@via.ecp.fr>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. #ifdef X11_SKINS
  25. #include <X11/Xlib.h>
  26. #include <X11/Xutil.h>
  27. #include <X11/extensions/shape.h>
  28. #include "x11_display.hpp"
  29. #include "../src/logger.hpp"
  30. X11Display::X11Display( intf_thread_t *pIntf ): SkinObject( pIntf ),
  31.     m_mainWindow( 0 ), m_gc( NULL ), m_colormap( 0 )
  32. {
  33.     // Open a connection to the X Server
  34.     m_pDisplay = XOpenDisplay( NULL );
  35.     if( m_pDisplay == NULL )
  36.     {
  37.         MSG_ERR( "Cannot open display" );
  38.         return;
  39.     }
  40.     // Load the XShape extension
  41.     int event, error;
  42.     XShapeQueryExtension( m_pDisplay, &event, &error );
  43.     // Get the display parameters
  44.     int screen = DefaultScreen( m_pDisplay );
  45.     int depth = DefaultDepth( m_pDisplay, screen );
  46.     int order = ImageByteOrder( m_pDisplay );
  47.     // Template for looking up the XVisualInfo
  48.     XVisualInfo xVInfoTemplate;
  49.     xVInfoTemplate.screen = screen;
  50.     xVInfoTemplate.depth = depth;
  51.     XVisualInfo *pVInfo = NULL;
  52.     int vCount = 0;
  53.     switch( depth )
  54.     {
  55.         case 8:
  56.             xVInfoTemplate.c_class = DirectColor;
  57.             // Get the DirectColor visual
  58.             pVInfo = XGetVisualInfo( m_pDisplay, VisualScreenMask |
  59.                                      VisualClassMask, &xVInfoTemplate,
  60.                                      &vCount );
  61.             if( pVInfo == NULL )
  62.             {
  63.                 msg_Err( getIntf(), "no DirectColor visual available" );
  64.                 m_pDisplay = NULL;
  65.                 break;
  66.             }
  67.             m_pVisual = pVInfo->visual;
  68.             // Compute the color shifts
  69.             getShifts( pVInfo->red_mask, m_redLeftShift, m_redRightShift );
  70.             getShifts( pVInfo->green_mask, m_greenLeftShift,
  71.                        m_greenRightShift );
  72.             getShifts( pVInfo->blue_mask, m_blueLeftShift, m_blueRightShift );
  73.             // Create a color map
  74.             m_colormap = XCreateColormap( m_pDisplay,
  75.                     DefaultRootWindow( m_pDisplay ),
  76.                     DefaultVisual( m_pDisplay, screen ), AllocAll );
  77.             // Create the palette
  78.             XColor pColors[255];
  79.             for( uint16_t i = 0; i < 255; i++ )
  80.             {
  81.                 // kludge: colors are indexed reversely because color 255 seems
  82.                 // to bereserved for black even if we try to set it to white
  83.                 pColors[i].pixel = 254-i;
  84.                 pColors[i].pad   = 0;
  85.                 pColors[i].flags = DoRed | DoGreen | DoBlue;
  86.                 pColors[i].red   = (i >> m_redLeftShift) << (m_redRightShift + 8);
  87.                 pColors[i].green = (i >> m_greenLeftShift) << (m_greenRightShift + 8);
  88.                 pColors[i].blue  = (i >> m_blueLeftShift) << (m_blueRightShift + 8);
  89.             }
  90.             XStoreColors( m_pDisplay, m_colormap, pColors, 255 );
  91.             makePixelImpl = &X11Display::makePixel8;
  92.             m_pixelSize = 1;
  93.             break;
  94.         case 15:
  95.         case 16:
  96.         case 24:
  97.         case 32:
  98.             // Get the TrueColor visual
  99.             xVInfoTemplate.c_class = TrueColor;
  100.             pVInfo = XGetVisualInfo( m_pDisplay, VisualScreenMask |
  101.                                      VisualDepthMask | VisualClassMask,
  102.                                      &xVInfoTemplate, &vCount );
  103.             if( pVInfo == NULL )
  104.             {
  105.                 msg_Err( getIntf(), "No TrueColor visual for depth %d",
  106.                          depth );
  107.                 m_pDisplay = NULL;
  108.                 break;
  109.             }
  110.             m_pVisual = pVInfo->visual;
  111.             // Compute the color shifts
  112.             getShifts( pVInfo->red_mask, m_redLeftShift, m_redRightShift );
  113.             getShifts( pVInfo->green_mask, m_greenLeftShift,
  114.                        m_greenRightShift );
  115.             getShifts( pVInfo->blue_mask, m_blueLeftShift, m_blueRightShift );
  116.             if( depth == 8 )
  117.             {
  118.                 makePixelImpl = &X11Display::makePixel8;
  119.                 m_pixelSize = 1;
  120.             }
  121.             if( depth == 15 || depth == 16 )
  122.             {
  123.                 if( order == MSBFirst )
  124.                 {
  125.                     makePixelImpl = &X11Display::makePixel16MSB;
  126.                 }
  127.                 else
  128.                 {
  129.                     makePixelImpl = &X11Display::makePixel16LSB;
  130.                 }
  131.                 m_pixelSize = 2;
  132.             }
  133.             else
  134.             {
  135.                 if( order == MSBFirst )
  136.                 {
  137.                     makePixelImpl = &X11Display::makePixel32MSB;
  138.                 }
  139.                 else
  140.                 {
  141.                     makePixelImpl = &X11Display::makePixel32LSB;
  142.                 }
  143.                 m_pixelSize = 4;
  144.             }
  145.             break;
  146.         default:
  147.             msg_Err( getIntf(), "Unsupported depth: %d bppn", depth );
  148.             m_pDisplay = NULL;
  149.             break;
  150.     }
  151.     // Free the visual info
  152.     if( pVInfo )
  153.     {
  154.         XFree( pVInfo );
  155.     }
  156.     // Create a graphics context that doesn't generate GraphicsExpose events
  157.     if( m_pDisplay )
  158.     {
  159.         XGCValues xgcvalues;
  160.         xgcvalues.graphics_exposures = False;
  161.         m_gc = XCreateGC( m_pDisplay, DefaultRootWindow( m_pDisplay ),
  162.                           GCGraphicsExposures, &xgcvalues );
  163.         // Create a parent window to have a single task in the task bar
  164.         XSetWindowAttributes attr;
  165.         m_mainWindow = XCreateWindow( m_pDisplay, DefaultRootWindow( m_pDisplay),
  166.                                       0, 0, 1, 1, 0, 0, InputOutput,
  167.                                       CopyFromParent, 0, &attr );
  168.         // Changing decorations
  169.         struct {
  170.             unsigned long flags;
  171.             unsigned long functions;
  172.             unsigned long decorations;
  173.             long input_mode;
  174.             unsigned long status;
  175.         } motifWmHints;
  176.         Atom hints_atom = XInternAtom( m_pDisplay, "_MOTIF_WM_HINTS", False );
  177.         motifWmHints.flags = 2;    // MWM_HINTS_DECORATIONS;
  178.         motifWmHints.decorations = 0;
  179.         XChangeProperty( m_pDisplay, m_mainWindow, hints_atom, hints_atom, 32,
  180.                          PropModeReplace, (unsigned char *)&motifWmHints,
  181.                          sizeof( motifWmHints ) / sizeof( long ) );
  182.         // Change the window title
  183.         XStoreName( m_pDisplay, m_mainWindow, "VLC Media Player" );
  184.         // Receive map notify events
  185.         XSelectInput( m_pDisplay, m_mainWindow, StructureNotifyMask );
  186.         // Set an empty mask for the window
  187.         Region mask = XCreateRegion();
  188.         XShapeCombineRegion( m_pDisplay, m_mainWindow, ShapeBounding, 0, 0, mask,
  189.                              ShapeSet );
  190.         // Map the window
  191.         XMapWindow( m_pDisplay, m_mainWindow);
  192.         // Move it outside the screen to avoid seeing it in workspace selector
  193.         XMoveWindow( m_pDisplay, m_mainWindow, -10, -10 );
  194.     }
  195. }
  196. X11Display::~X11Display()
  197. {
  198.     if( m_mainWindow )
  199.     {
  200.         XDestroyWindow( m_pDisplay, m_mainWindow );
  201.     }
  202.     if( m_gc )
  203.     {
  204.         XFreeGC( m_pDisplay, m_gc );
  205.     }
  206.     if( m_colormap )
  207.     {
  208.         XFreeColormap( m_pDisplay, m_colormap );
  209.     }
  210.     if( m_pDisplay )
  211.     {
  212.         XCloseDisplay( m_pDisplay );
  213.     }
  214. }
  215. void X11Display::getShifts( uint32_t mask, int &rLeftShift,
  216.                             int &rRightShift ) const
  217. {
  218.     for( rLeftShift = 0; (rLeftShift < 32) && !(mask & 1); rLeftShift++ )
  219.     {
  220.         mask >>= 1;
  221.     }
  222.     for( rRightShift = 8; (mask & 1) ; rRightShift--)
  223.     {
  224.         mask >>= 1;
  225.     }
  226.     if( rRightShift < 0 )
  227.     {
  228.         rLeftShift -= rRightShift;
  229.         rRightShift = 0;
  230.     }
  231. }
  232. void X11Display::makePixel8( uint8_t *pPixel, uint8_t r, uint8_t g, uint8_t b,
  233.                              uint8_t a ) const
  234. {
  235.     // Get the current pixel value
  236.     uint8_t value = 255 - *pPixel;
  237.     // Compute the new color values
  238.     uint16_t temp;
  239.     temp = ((uint8_t)((value >> m_redLeftShift) << m_redRightShift));
  240.     uint8_t red = ( temp * (255 - a) + r * a ) / 255;
  241.     temp = ((uint8_t)((value >> m_greenLeftShift) << m_greenRightShift));
  242.     uint8_t green = ( temp * (255 - a) + g * a ) / 255;
  243.     temp = ((uint8_t)((value >> m_blueLeftShift) << m_blueRightShift));
  244.     uint8_t blue = ( temp * (255 - a) + b * a ) / 255;
  245.     // Set the new pixel value
  246.     value =
  247.         ( ((uint8_t)red >> m_redRightShift) << m_redLeftShift ) |
  248.         ( ((uint8_t)green >> m_greenRightShift) << m_greenLeftShift ) |
  249.         ( ((uint8_t)blue >> m_blueRightShift) << m_blueLeftShift );
  250.     *pPixel = 255 - value;
  251. }
  252. void X11Display::makePixel16MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  253.                                  uint8_t b, uint8_t a ) const
  254. {
  255.     // Get the current pixel value
  256.     uint16_t value = pPixel[1] | pPixel[0] << 8;
  257.     // Compute the new color values
  258.     uint16_t temp;
  259.     temp = ((uint8_t)((value >> m_redLeftShift) << m_redRightShift));
  260.     uint8_t red = ( temp * (255 - a) + r * a ) / 255;
  261.     temp = ((uint8_t)((value >> m_greenLeftShift) << m_greenRightShift));
  262.     uint8_t green = ( temp * (255 - a) + g * a ) / 255;
  263.     temp = ((uint8_t)((value >> m_blueLeftShift) << m_blueRightShift));
  264.     uint8_t blue = ( temp * (255 - a) + b * a ) / 255;
  265.     // Set the new pixel value
  266.     value =
  267.         ( ((uint16_t)red >> m_redRightShift) << m_redLeftShift ) |
  268.         ( ((uint16_t)green >> m_greenRightShift) << m_greenLeftShift ) |
  269.         ( ((uint16_t)blue >> m_blueRightShift) << m_blueLeftShift );
  270.     pPixel[1] = value;
  271.     value >>= 8;
  272.     pPixel[0] = value;
  273. }
  274. void X11Display::makePixel16LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  275.                                  uint8_t b, uint8_t a ) const
  276. {
  277.     // Get the current pixel value
  278.     uint16_t value = pPixel[0] | pPixel[1] << 8;
  279.     // Compute the new color values
  280.     uint16_t temp;
  281.     temp = ((uint8_t)((value >> m_redLeftShift) << m_redRightShift));
  282.     uint8_t red = ( temp * (255 - a) + r * a ) / 255;
  283.     temp = ((uint8_t)((value >> m_greenLeftShift) << m_greenRightShift));
  284.     uint8_t green = ( temp * (255 - a) + g * a ) / 255;
  285.     temp = ((uint8_t)((value >> m_blueLeftShift) << m_blueRightShift));
  286.     uint8_t blue = ( temp * (255 - a) + b * a ) / 255;
  287.     // Set the new pixel value
  288.     value =
  289.         ( ((uint16_t)red >> m_redRightShift) << m_redLeftShift ) |
  290.         ( ((uint16_t)green >> m_greenRightShift) << m_greenLeftShift ) |
  291.         ( ((uint16_t)blue >> m_blueRightShift) << m_blueLeftShift );
  292.     pPixel[0] = value;
  293.     value >>= 8;
  294.     pPixel[1] = value;
  295. }
  296. void X11Display::makePixel32MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  297.                                  uint8_t b, uint8_t a ) const
  298. {
  299.     // Get the current pixel value
  300.     uint32_t value = pPixel[3] | pPixel[2] << 8 | pPixel[1] << 16 |
  301.                           pPixel[0] << 24;
  302.     // Compute the new color values
  303.     uint16_t temp;
  304.     temp = ((uint8_t)((value >> m_redLeftShift) << m_redRightShift));
  305.     uint8_t red = ( temp * (255 - a) + r * a ) / 255;
  306.     temp = ((uint8_t)((value >> m_greenLeftShift) << m_greenRightShift));
  307.     uint8_t green = ( temp * (255 - a) + g * a ) / 255;
  308.     temp = ((uint8_t)((value >> m_blueLeftShift) << m_blueRightShift));
  309.     uint8_t blue = ( temp * (255 - a) + b * a ) / 255;
  310.     // Set the new pixel value
  311.     value =
  312.         ( ((uint32_t)red >> m_redRightShift) << m_redLeftShift ) |
  313.         ( ((uint32_t)green >> m_greenRightShift) << m_greenLeftShift ) |
  314.         ( ((uint32_t)blue >> m_blueRightShift) << m_blueLeftShift );
  315.     pPixel[3] = value;
  316.     value >>= 8;
  317.     pPixel[2] = value;
  318.     value >>= 8;
  319.     pPixel[1] = value;
  320.     value >>= 8;
  321.     pPixel[0] = value;
  322. }
  323. void X11Display::makePixel32LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  324.                                  uint8_t b, uint8_t a ) const
  325. {
  326.     // Get the current pixel value
  327.     uint32_t value = pPixel[0] | pPixel[1] << 8 | pPixel[2] << 16 |
  328.                           pPixel[3] << 24;
  329.     // Compute the new color values
  330.     uint16_t temp;
  331.     temp = ((uint8_t)((value >> m_redLeftShift) << m_redRightShift));
  332.     uint8_t red = ( temp * (255 - a) + r * a ) / 255;
  333.     temp = ((uint8_t)((value >> m_greenLeftShift) << m_greenRightShift));
  334.     uint8_t green = ( temp * (255 - a) + g * a ) / 255;
  335.     temp = ((uint8_t)((value >> m_blueLeftShift) << m_blueRightShift));
  336.     uint8_t blue = ( temp * (255 - a) + b * a ) / 255;
  337.     // Set the new pixel value
  338.     value =
  339.         ( ((uint32_t)red >> m_redRightShift) << m_redLeftShift ) |
  340.         ( ((uint32_t)green >> m_greenRightShift) << m_greenLeftShift ) |
  341.         ( ((uint32_t)blue >> m_blueRightShift) << m_blueLeftShift );
  342.     pPixel[0] = value;
  343.     value >>= 8;
  344.     pPixel[1] = value;
  345.     value >>= 8;
  346.     pPixel[2] = value;
  347.     value >>= 8;
  348.     pPixel[3] = value;
  349. }
  350. unsigned long X11Display::getPixelValue( uint8_t r, uint8_t g, uint8_t b ) const
  351. {
  352.     unsigned long value;
  353.     value = ( ((uint32_t)r >> m_redRightShift) << m_redLeftShift ) |
  354.             ( ((uint32_t)g >> m_greenRightShift) << m_greenLeftShift ) |
  355.             ( ((uint32_t)b >> m_blueRightShift) << m_blueLeftShift );
  356.     if( m_pixelSize == 1 )
  357.     {
  358.         return 255 - value;
  359.     }
  360.     else
  361.     {
  362.         return value;
  363.     }
  364. }
  365. #endif