x11_display.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:13k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * x11_display.cpp
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 the VideoLAN team
  5.  * $Id: 143c45f08db336389482b29178353d518b6c8afa $
  6.  *
  7.  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
  8.  *          Olivier Teulière <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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, 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. // Macro to compute a pixel value
  31. #define PUT_PIXEL(value, r, g, b, type) 
  32.     value = 
  33.         ( ((type)r >> m_redRightShift) << m_redLeftShift ) | 
  34.         ( ((type)g >> m_greenRightShift) << m_greenLeftShift ) | 
  35.         ( ((type)b >> m_blueRightShift) << m_blueLeftShift );
  36. // Macro to blend a pixel with another color
  37. #define BLEND_PIXEL(value, r, g, b, a, type) 
  38.     uint16_t temp; 
  39.     temp = ((uint8_t)((value >> m_redLeftShift) << m_redRightShift)); 
  40.     uint8_t red = r + ( temp * (255 - a) ) / 255; 
  41.     temp = ((uint8_t)((value >> m_greenLeftShift) << m_greenRightShift)); 
  42.     uint8_t green = g + ( temp * (255 - a) ) / 255; 
  43.     temp = ((uint8_t)((value >> m_blueLeftShift) << m_blueRightShift)); 
  44.     uint8_t blue = b + ( temp * (255 - a) ) / 255; 
  45.     PUT_PIXEL(value, red, green, blue, type)
  46. X11Display::X11Display( intf_thread_t *pIntf ): SkinObject( pIntf ),
  47.     m_mainWindow( 0 ), m_gc( NULL ), m_colormap( 0 )
  48. {
  49.     char *psz_display = var_CreateGetNonEmptyString( pIntf, "x11-display" );
  50.     // Open a connection to the X Server
  51.     m_pDisplay = XOpenDisplay( psz_display );
  52.     free( psz_display );
  53.     if( m_pDisplay == NULL )
  54.     {
  55.         MSG_ERR( "Cannot open display" );
  56.         return;
  57.     }
  58.     // Load the XShape extension
  59.     int event, error;
  60.     XShapeQueryExtension( m_pDisplay, &event, &error );
  61.     // Get the display parameters
  62.     int screen = DefaultScreen( m_pDisplay );
  63.     int depth = DefaultDepth( m_pDisplay, screen );
  64.     int order = ImageByteOrder( m_pDisplay );
  65.     Window root = DefaultRootWindow( m_pDisplay );
  66.     // Template for looking up the XVisualInfo
  67.     XVisualInfo xVInfoTemplate;
  68.     xVInfoTemplate.screen = screen;
  69.     xVInfoTemplate.depth = depth;
  70.     XVisualInfo *pVInfo = NULL;
  71.     int vCount = 0;
  72.     switch( depth )
  73.     {
  74.         case 8:
  75.             xVInfoTemplate.c_class = DirectColor;
  76.             // Get the DirectColor visual
  77.             pVInfo = XGetVisualInfo( m_pDisplay, VisualScreenMask |
  78.                                      VisualClassMask, &xVInfoTemplate,
  79.                                      &vCount );
  80.             if( pVInfo == NULL )
  81.             {
  82.                 msg_Err( getIntf(), "no DirectColor visual available" );
  83.                 m_pDisplay = NULL;
  84.                 break;
  85.             }
  86.             m_pVisual = pVInfo->visual;
  87.             // Compute the color shifts
  88.             getShifts( pVInfo->red_mask, m_redLeftShift, m_redRightShift );
  89.             getShifts( pVInfo->green_mask, m_greenLeftShift,
  90.                        m_greenRightShift );
  91.             getShifts( pVInfo->blue_mask, m_blueLeftShift, m_blueRightShift );
  92.             // Create a color map
  93.             m_colormap = XCreateColormap( m_pDisplay, root,
  94.                     DefaultVisual( m_pDisplay, screen ), AllocAll );
  95.             // Create the palette
  96.             XColor pColors[255];
  97.             for( uint16_t i = 0; i < 255; i++ )
  98.             {
  99.                 // kludge: colors are indexed reversely because color 255 seems
  100.                 // to bereserved for black even if we try to set it to white
  101.                 pColors[i].pixel = 254-i;
  102.                 pColors[i].pad   = 0;
  103.                 pColors[i].flags = DoRed | DoGreen | DoBlue;
  104.                 pColors[i].red   =
  105.                     (i >> m_redLeftShift) << (m_redRightShift + 8);
  106.                 pColors[i].green =
  107.                     (i >> m_greenLeftShift) << (m_greenRightShift + 8);
  108.                 pColors[i].blue  =
  109.                     (i >> m_blueLeftShift) << (m_blueRightShift + 8);
  110.             }
  111.             XStoreColors( m_pDisplay, m_colormap, pColors, 255 );
  112.             blendPixelImpl = &X11Display::blendPixel8;
  113.             putPixelImpl = &X11Display::putPixel8;
  114.             m_pixelSize = 1;
  115.             break;
  116.         case 15:
  117.         case 16:
  118.         case 24:
  119.         case 32:
  120.             // Get the TrueColor visual
  121.             xVInfoTemplate.c_class = TrueColor;
  122.             pVInfo = XGetVisualInfo( m_pDisplay, VisualScreenMask |
  123.                                      VisualDepthMask | VisualClassMask,
  124.                                      &xVInfoTemplate, &vCount );
  125.             if( pVInfo == NULL )
  126.             {
  127.                 msg_Err( getIntf(), "No TrueColor visual for depth %d",
  128.                          depth );
  129.                 m_pDisplay = NULL;
  130.                 break;
  131.             }
  132.             m_pVisual = pVInfo->visual;
  133.             // Compute the color shifts
  134.             getShifts( pVInfo->red_mask, m_redLeftShift, m_redRightShift );
  135.             getShifts( pVInfo->green_mask, m_greenLeftShift,
  136.                        m_greenRightShift );
  137.             getShifts( pVInfo->blue_mask, m_blueLeftShift, m_blueRightShift );
  138.             if( depth == 15 || depth == 16 )
  139.             {
  140.                 if( order == MSBFirst )
  141.                 {
  142.                     blendPixelImpl = &X11Display::blendPixel16MSB;
  143.                     putPixelImpl = &X11Display::putPixel16MSB;
  144.                 }
  145.                 else
  146.                 {
  147.                     blendPixelImpl = &X11Display::blendPixel16LSB;
  148.                     putPixelImpl = &X11Display::putPixel16LSB;
  149.                 }
  150.                 m_pixelSize = 2;
  151.             }
  152.             else
  153.             {
  154.                 if( order == MSBFirst )
  155.                 {
  156.                     blendPixelImpl = &X11Display::blendPixel32MSB;
  157.                     putPixelImpl = &X11Display::putPixel32MSB;
  158.                 }
  159.                 else
  160.                 {
  161.                     blendPixelImpl = &X11Display::blendPixel32LSB;
  162.                     putPixelImpl = &X11Display::putPixel32LSB;
  163.                 }
  164.                 m_pixelSize = 4;
  165.             }
  166.             break;
  167.         default:
  168.             msg_Err( getIntf(), "unsupported depth: %d bppn", depth );
  169.             m_pDisplay = NULL;
  170.             break;
  171.     }
  172.     // Free the visual info
  173.     if( pVInfo )
  174.     {
  175.         XFree( pVInfo );
  176.     }
  177.     // Create a graphics context that doesn't generate GraphicsExpose events
  178.     if( m_pDisplay )
  179.     {
  180.         XGCValues xgcvalues;
  181.         xgcvalues.graphics_exposures = False;
  182.         m_gc = XCreateGC( m_pDisplay, root, GCGraphicsExposures, &xgcvalues );
  183.         // Create a parent window to have a single task in the task bar
  184.         XSetWindowAttributes attr;
  185.         m_mainWindow = XCreateWindow( m_pDisplay, root, 0, 0, 1, 1, 0, 0,
  186.                                       InputOutput, CopyFromParent, 0, &attr );
  187.         // Changing decorations
  188.         struct {
  189.             unsigned long flags;
  190.             unsigned long functions;
  191.             unsigned long decorations;
  192.             long input_mode;
  193.             unsigned long status;
  194.         } motifWmHints;
  195.         Atom hints_atom = XInternAtom( m_pDisplay, "_MOTIF_WM_HINTS", False );
  196.         motifWmHints.flags = 2;    // MWM_HINTS_DECORATIONS;
  197.         motifWmHints.decorations = 0;
  198.         XChangeProperty( m_pDisplay, m_mainWindow, hints_atom, hints_atom, 32,
  199.                          PropModeReplace, (unsigned char *)&motifWmHints,
  200.                          sizeof( motifWmHints ) / sizeof( long ) );
  201.         // Change the window title
  202.         XStoreName( m_pDisplay, m_mainWindow, "VLC Media Player" );
  203.         // Receive map notify events
  204.         XSelectInput( m_pDisplay, m_mainWindow, StructureNotifyMask );
  205.         // Set an empty mask for the window
  206.         Region mask = XCreateRegion();
  207.         XShapeCombineRegion( m_pDisplay, m_mainWindow, ShapeBounding, 0, 0,
  208.                              mask, ShapeSet );
  209.         XDestroyRegion( mask );
  210.         // Map the window
  211.         XMapWindow( m_pDisplay, m_mainWindow);
  212.         // Move it outside the screen to avoid seeing it in workspace selector
  213.         XMoveWindow( m_pDisplay, m_mainWindow, -10, -10 );
  214.     }
  215. }
  216. X11Display::~X11Display()
  217. {
  218.     if( m_mainWindow )
  219.     {
  220.         XDestroyWindow( m_pDisplay, m_mainWindow );
  221.     }
  222.     if( m_gc )
  223.     {
  224.         XFreeGC( m_pDisplay, m_gc );
  225.     }
  226.     if( m_colormap )
  227.     {
  228.         XFreeColormap( m_pDisplay, m_colormap );
  229.     }
  230.     if( m_pDisplay )
  231.     {
  232.         XCloseDisplay( m_pDisplay );
  233.     }
  234. }
  235. void X11Display::getShifts( uint32_t mask, int &rLeftShift,
  236.                             int &rRightShift ) const
  237. {
  238.     for( rLeftShift = 0; (rLeftShift < 32) && !(mask & 1); rLeftShift++ )
  239.     {
  240.         mask >>= 1;
  241.     }
  242.     for( rRightShift = 8; (mask & 1) ; rRightShift--)
  243.     {
  244.         mask >>= 1;
  245.     }
  246.     if( rRightShift < 0 )
  247.     {
  248.         rLeftShift -= rRightShift;
  249.         rRightShift = 0;
  250.     }
  251. }
  252. void X11Display::blendPixel8( uint8_t *pPixel, uint8_t r, uint8_t g,
  253.                               uint8_t b, uint8_t a ) const
  254. {
  255.     uint8_t value = 255 - *pPixel;
  256.     BLEND_PIXEL(value, r, g, b, a, uint8_t)
  257.     *pPixel = 255 - value;
  258. }
  259. void X11Display::blendPixel16MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  260.                                   uint8_t b, uint8_t a ) const
  261. {
  262.     uint16_t value = pPixel[1] | pPixel[0] << 8;
  263.     BLEND_PIXEL(value, r, g, b, a, uint16_t)
  264.     pPixel[1] = value; value >>= 8;
  265.     pPixel[0] = value;
  266. }
  267. void X11Display::blendPixel16LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  268.                                   uint8_t b, uint8_t a ) const
  269. {
  270.     uint16_t value = pPixel[0] | pPixel[1] << 8;
  271.     BLEND_PIXEL(value, r, g, b, a, uint16_t)
  272.     pPixel[0] = value; value >>= 8;
  273.     pPixel[1] = value;
  274. }
  275. void X11Display::blendPixel32MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  276.                                   uint8_t b, uint8_t a ) const
  277. {
  278.     uint32_t value = pPixel[3] | pPixel[2] << 8 | pPixel[1] << 16 |
  279.                           pPixel[0] << 24;
  280.     BLEND_PIXEL(value, r, g, b, a, uint32_t)
  281.     pPixel[3] = value; value >>= 8;
  282.     pPixel[2] = value; value >>= 8;
  283.     pPixel[1] = value; value >>= 8;
  284.     pPixel[0] = value;
  285. }
  286. void X11Display::blendPixel32LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  287.                                   uint8_t b, uint8_t a ) const
  288. {
  289.     uint32_t value = pPixel[0] | pPixel[1] << 8 | pPixel[2] << 16 |
  290.                           pPixel[3] << 24;
  291.     BLEND_PIXEL(value, r, g, b, a, uint32_t)
  292.     pPixel[0] = value; value >>= 8;
  293.     pPixel[1] = value; value >>= 8;
  294.     pPixel[2] = value; value >>= 8;
  295.     pPixel[3] = value;
  296. }
  297. void X11Display::putPixel8( uint8_t *pPixel, uint8_t r, uint8_t g,
  298.                             uint8_t b, uint8_t a ) const
  299. {
  300.     uint8_t value = 255 - *pPixel;
  301.     PUT_PIXEL(value, r, g, b, uint8_t)
  302.     *pPixel = 255 - value;
  303. }
  304. void X11Display::putPixel16MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  305.                                 uint8_t b, uint8_t a ) const
  306. {
  307.     uint16_t value = pPixel[1] | pPixel[0] << 8;
  308.     PUT_PIXEL(value, r, g, b, uint16_t)
  309.     pPixel[1] = value; value >>= 8;
  310.     pPixel[0] = value;
  311. }
  312. void X11Display::putPixel16LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  313.                                 uint8_t b, uint8_t a ) const
  314. {
  315.     uint16_t value = pPixel[0] | pPixel[1] << 8;
  316.     PUT_PIXEL(value, r, g, b, uint16_t)
  317.     pPixel[0] = value; value >>= 8;
  318.     pPixel[1] = value;
  319. }
  320. void X11Display::putPixel32MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  321.                                 uint8_t b, uint8_t a ) const
  322. {
  323.     uint32_t value = pPixel[3] | pPixel[2] << 8 | pPixel[1] << 16 |
  324.                           pPixel[0] << 24;
  325.     PUT_PIXEL(value, r, g, b, uint32_t)
  326.     pPixel[3] = value; value >>= 8;
  327.     pPixel[2] = value; value >>= 8;
  328.     pPixel[1] = value; value >>= 8;
  329.     pPixel[0] = value;
  330. }
  331. void X11Display::putPixel32LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
  332.                                 uint8_t b, uint8_t a ) const
  333. {
  334.     uint32_t value = pPixel[0] | pPixel[1] << 8 | pPixel[2] << 16 |
  335.                           pPixel[3] << 24;
  336.     PUT_PIXEL(value, r, g, b, uint32_t)
  337.     pPixel[0] = value; value >>= 8;
  338.     pPixel[1] = value; value >>= 8;
  339.     pPixel[2] = value; value >>= 8;
  340.     pPixel[3] = value;
  341. }
  342. unsigned long X11Display::getPixelValue( uint8_t r, uint8_t g, uint8_t b )
  343.     const
  344. {
  345.     unsigned long value;
  346.     PUT_PIXEL(value, r, g, b, uint32_t)
  347.     if( m_pixelSize == 1 )
  348.     {
  349.         return 255 - value;
  350.     }
  351.     else
  352.     {
  353.         return value;
  354.     }
  355. }
  356. #endif