1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: x11_display.cpp,v 1.1 2004/01/03 23:31:34 asmax Exp $
7 * Authors: Cyril Deguet <asmax@via.ecp.fr>
8 * Olivier Teulière <ipkiss@via.ecp.fr>
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.
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.
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 *****************************************************************************/
27 #include <X11/Xutil.h>
28 #include <X11/extensions/shape.h>
30 #include "x11_display.hpp"
31 #include "../src/logger.hpp"
34 X11Display::X11Display( intf_thread_t *pIntf ): SkinObject( pIntf ),
37 // Open a connection to the X Server
38 m_pDisplay = XOpenDisplay( NULL );
39 if( m_pDisplay == NULL )
41 MSG_ERR( "Cannot open display" );
45 // Load the XShape extension
47 XShapeQueryExtension( m_pDisplay, &event, &error );
49 // Get the display parameters
50 int screen = DefaultScreen( m_pDisplay );
51 int depth = DefaultDepth( m_pDisplay, screen );
52 int order = ImageByteOrder( m_pDisplay );
54 // Create a graphics context that doesn't generate GraphicsExpose events
56 xgcvalues.graphics_exposures = False;
57 m_gc = XCreateGC( m_pDisplay, DefaultRootWindow( m_pDisplay ),
58 GCGraphicsExposures, &xgcvalues );
60 // Template for looking up the XVisualInfo
61 XVisualInfo xVInfoTemplate;
62 xVInfoTemplate.screen = screen;
63 xVInfoTemplate.depth = depth;
65 XVisualInfo *pVInfo = NULL;
73 // Get the TrueColor visual
74 xVInfoTemplate.c_class = TrueColor;
75 pVInfo = XGetVisualInfo( m_pDisplay, VisualScreenMask |
76 VisualDepthMask | VisualClassMask,
77 &xVInfoTemplate, &vCount );
80 msg_Err( getIntf(), "No TrueColor visual for depth %d",
85 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,
91 getShifts( pVInfo->blue_mask, m_blueLeftShift, m_blueRightShift );
95 if( order == MSBFirst )
97 makePixelImpl = &X11Display::makePixel16MSB;
101 makePixelImpl = &X11Display::makePixel16LSB;
107 if( order == MSBFirst )
109 makePixelImpl = &X11Display::makePixel32MSB;
113 makePixelImpl = &X11Display::makePixel32LSB;
120 msg_Err( getIntf(), "Unsupported depth: %d bpp\n", depth );
125 // Free the visual info
133 X11Display::~X11Display()
137 XFreeGC( m_pDisplay, m_gc );
141 XCloseDisplay( m_pDisplay );
146 void X11Display::getShifts( uint32_t mask, int &rLeftShift,
147 int &rRightShift ) const
149 for( rLeftShift = 0; (rLeftShift < 32) && !(mask & 1); rLeftShift++ )
153 for( rRightShift = 8; (mask & 1) ; rRightShift--)
157 if( rRightShift < 0 )
159 rLeftShift -= rRightShift;
165 void X11Display::makePixel16MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
166 uint8_t b, uint8_t a ) const
168 // Get the current pixel value
169 uint16_t value = pPixel[1] | pPixel[0] << 8;
171 // Compute the new color values
173 temp = ((uint8_t)((value >> m_redLeftShift) << m_redRightShift));
174 uint8_t red = ( temp * (255 - a) + r * a ) / 255;
175 temp = ((uint8_t)((value >> m_greenLeftShift) << m_greenRightShift));
176 uint8_t green = ( temp * (255 - a) + g * a ) / 255;
177 temp = ((uint8_t)((value >> m_blueLeftShift) << m_blueRightShift));
178 uint8_t blue = ( temp * (255 - a) + b * a ) / 255;
180 // Set the new pixel value
182 ( ((uint16_t)red >> m_redRightShift) << m_redLeftShift ) |
183 ( ((uint16_t)green >> m_greenRightShift) << m_greenLeftShift ) |
184 ( ((uint16_t)blue >> m_blueRightShift) << m_blueLeftShift );
192 void X11Display::makePixel16LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
193 uint8_t b, uint8_t a ) const
195 // Get the current pixel value
196 uint16_t value = pPixel[0] | pPixel[1] << 8;
198 // Compute the new color values
200 temp = ((uint8_t)((value >> m_redLeftShift) << m_redRightShift));
201 uint8_t red = ( temp * (255 - a) + r * a ) / 255;
202 temp = ((uint8_t)((value >> m_greenLeftShift) << m_greenRightShift));
203 uint8_t green = ( temp * (255 - a) + g * a ) / 255;
204 temp = ((uint8_t)((value >> m_blueLeftShift) << m_blueRightShift));
205 uint8_t blue = ( temp * (255 - a) + b * a ) / 255;
207 // Set the new pixel value
209 ( ((uint16_t)red >> m_redRightShift) << m_redLeftShift ) |
210 ( ((uint16_t)green >> m_greenRightShift) << m_greenLeftShift ) |
211 ( ((uint16_t)blue >> m_blueRightShift) << m_blueLeftShift );
219 void X11Display::makePixel32MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
220 uint8_t b, uint8_t a ) const
222 // Get the current pixel value
223 uint32_t value = pPixel[3] | pPixel[2] << 8 | pPixel[1] << 16 |
226 // Compute the new color values
228 temp = ((uint8_t)((value >> m_redLeftShift) << m_redRightShift));
229 uint8_t red = ( temp * (255 - a) + r * a ) / 255;
230 temp = ((uint8_t)((value >> m_greenLeftShift) << m_greenRightShift));
231 uint8_t green = ( temp * (255 - a) + g * a ) / 255;
232 temp = ((uint8_t)((value >> m_blueLeftShift) << m_blueRightShift));
233 uint8_t blue = ( temp * (255 - a) + b * a ) / 255;
235 // Set the new pixel value
237 ( ((uint32_t)red >> m_redRightShift) << m_redLeftShift ) |
238 ( ((uint32_t)green >> m_greenRightShift) << m_greenLeftShift ) |
239 ( ((uint32_t)blue >> m_blueRightShift) << m_blueLeftShift );
251 void X11Display::makePixel32LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
252 uint8_t b, uint8_t a ) const
254 // Get the current pixel value
255 uint32_t value = pPixel[0] | pPixel[1] << 8 | pPixel[2] << 16 |
258 // Compute the new color values
260 temp = ((uint8_t)((value >> m_redLeftShift) << m_redRightShift));
261 uint8_t red = ( temp * (255 - a) + r * a ) / 255;
262 temp = ((uint8_t)((value >> m_greenLeftShift) << m_greenRightShift));
263 uint8_t green = ( temp * (255 - a) + g * a ) / 255;
264 temp = ((uint8_t)((value >> m_blueLeftShift) << m_blueRightShift));
265 uint8_t blue = ( temp * (255 - a) + b * a ) / 255;
267 // Set the new pixel value
269 ( ((uint32_t)red >> m_redRightShift) << m_redLeftShift ) |
270 ( ((uint32_t)green >> m_greenRightShift) << m_greenLeftShift ) |
271 ( ((uint32_t)blue >> m_blueRightShift) << m_blueLeftShift );