00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef X11_SKINS
00026
00027 #include <X11/Xlib.h>
00028 #include <X11/Xutil.h>
00029 #include <X11/extensions/shape.h>
00030
00031 #include "x11_display.hpp"
00032 #include "../src/logger.hpp"
00033
00034
00035 #define PUT_PIXEL(value, r, g, b, type) \
00036 value = \
00037 ( ((type)r >> m_redRightShift) << m_redLeftShift ) | \
00038 ( ((type)g >> m_greenRightShift) << m_greenLeftShift ) | \
00039 ( ((type)b >> m_blueRightShift) << m_blueLeftShift );
00040
00041
00042 #define BLEND_PIXEL(value, r, g, b, a, type) \
00043 uint16_t temp; \
00044 temp = ((uint8_t)((value >> m_redLeftShift) << m_redRightShift)); \
00045 uint8_t red = r + ( temp * (255 - a) ) / 255; \
00046 temp = ((uint8_t)((value >> m_greenLeftShift) << m_greenRightShift)); \
00047 uint8_t green = g + ( temp * (255 - a) ) / 255; \
00048 temp = ((uint8_t)((value >> m_blueLeftShift) << m_blueRightShift)); \
00049 uint8_t blue = b + ( temp * (255 - a) ) / 255; \
00050 PUT_PIXEL(value, red, green, blue, type)
00051
00052
00053 X11Display::X11Display( intf_thread_t *pIntf ): SkinObject( pIntf ),
00054 m_mainWindow( 0 ), m_gc( NULL ), m_colormap( 0 )
00055 {
00056
00057 m_pDisplay = XOpenDisplay( NULL );
00058
00059 if( m_pDisplay == NULL )
00060 {
00061 MSG_ERR( "Cannot open display" );
00062 return;
00063 }
00064
00065
00066 int event, error;
00067 XShapeQueryExtension( m_pDisplay, &event, &error );
00068
00069
00070 int screen = DefaultScreen( m_pDisplay );
00071 int depth = DefaultDepth( m_pDisplay, screen );
00072 int order = ImageByteOrder( m_pDisplay );
00073 Window root = DefaultRootWindow( m_pDisplay );
00074
00075
00076 XVisualInfo xVInfoTemplate;
00077 xVInfoTemplate.screen = screen;
00078 xVInfoTemplate.depth = depth;
00079
00080 XVisualInfo *pVInfo = NULL;
00081 int vCount = 0;
00082
00083 switch( depth )
00084 {
00085 case 8:
00086 xVInfoTemplate.c_class = DirectColor;
00087
00088 pVInfo = XGetVisualInfo( m_pDisplay, VisualScreenMask |
00089 VisualClassMask, &xVInfoTemplate,
00090 &vCount );
00091 if( pVInfo == NULL )
00092 {
00093 msg_Err( getIntf(), "no DirectColor visual available" );
00094 m_pDisplay = NULL;
00095 break;
00096 }
00097 m_pVisual = pVInfo->visual;
00098
00099
00100 getShifts( pVInfo->red_mask, m_redLeftShift, m_redRightShift );
00101 getShifts( pVInfo->green_mask, m_greenLeftShift,
00102 m_greenRightShift );
00103 getShifts( pVInfo->blue_mask, m_blueLeftShift, m_blueRightShift );
00104
00105
00106 m_colormap = XCreateColormap( m_pDisplay, root,
00107 DefaultVisual( m_pDisplay, screen ), AllocAll );
00108
00109
00110 XColor pColors[255];
00111 for( uint16_t i = 0; i < 255; i++ )
00112 {
00113
00114
00115 pColors[i].pixel = 254-i;
00116 pColors[i].pad = 0;
00117 pColors[i].flags = DoRed | DoGreen | DoBlue;
00118 pColors[i].red =
00119 (i >> m_redLeftShift) << (m_redRightShift + 8);
00120 pColors[i].green =
00121 (i >> m_greenLeftShift) << (m_greenRightShift + 8);
00122 pColors[i].blue =
00123 (i >> m_blueLeftShift) << (m_blueRightShift + 8);
00124 }
00125 XStoreColors( m_pDisplay, m_colormap, pColors, 255 );
00126 blendPixelImpl = &X11Display::blendPixel8;
00127 putPixelImpl = &X11Display::putPixel8;
00128 m_pixelSize = 1;
00129 break;
00130
00131 case 15:
00132 case 16:
00133 case 24:
00134 case 32:
00135
00136 xVInfoTemplate.c_class = TrueColor;
00137 pVInfo = XGetVisualInfo( m_pDisplay, VisualScreenMask |
00138 VisualDepthMask | VisualClassMask,
00139 &xVInfoTemplate, &vCount );
00140 if( pVInfo == NULL )
00141 {
00142 msg_Err( getIntf(), "No TrueColor visual for depth %d",
00143 depth );
00144 m_pDisplay = NULL;
00145 break;
00146 }
00147 m_pVisual = pVInfo->visual;
00148
00149
00150 getShifts( pVInfo->red_mask, m_redLeftShift, m_redRightShift );
00151 getShifts( pVInfo->green_mask, m_greenLeftShift,
00152 m_greenRightShift );
00153 getShifts( pVInfo->blue_mask, m_blueLeftShift, m_blueRightShift );
00154
00155 if( depth == 15 || depth == 16 )
00156 {
00157 if( order == MSBFirst )
00158 {
00159 blendPixelImpl = &X11Display::blendPixel16MSB;
00160 putPixelImpl = &X11Display::putPixel16MSB;
00161 }
00162 else
00163 {
00164 blendPixelImpl = &X11Display::blendPixel16LSB;
00165 putPixelImpl = &X11Display::putPixel16LSB;
00166 }
00167 m_pixelSize = 2;
00168 }
00169 else
00170 {
00171 if( order == MSBFirst )
00172 {
00173 blendPixelImpl = &X11Display::blendPixel32MSB;
00174 putPixelImpl = &X11Display::putPixel32MSB;
00175 }
00176 else
00177 {
00178 blendPixelImpl = &X11Display::blendPixel32LSB;
00179 putPixelImpl = &X11Display::putPixel32LSB;
00180 }
00181 m_pixelSize = 4;
00182 }
00183 break;
00184
00185 default:
00186 msg_Err( getIntf(), "Unsupported depth: %d bpp\n", depth );
00187 m_pDisplay = NULL;
00188 break;
00189 }
00190
00191
00192 if( pVInfo )
00193 {
00194 XFree( pVInfo );
00195 }
00196
00197
00198 if( m_pDisplay )
00199 {
00200 XGCValues xgcvalues;
00201 xgcvalues.graphics_exposures = False;
00202 m_gc = XCreateGC( m_pDisplay, root, GCGraphicsExposures, &xgcvalues );
00203
00204
00205 XSetWindowAttributes attr;
00206 m_mainWindow = XCreateWindow( m_pDisplay, root, 0, 0, 1, 1, 0, 0,
00207 InputOutput, CopyFromParent, 0, &attr );
00208
00209
00210 struct {
00211 unsigned long flags;
00212 unsigned long functions;
00213 unsigned long decorations;
00214 long input_mode;
00215 unsigned long status;
00216 } motifWmHints;
00217 Atom hints_atom = XInternAtom( m_pDisplay, "_MOTIF_WM_HINTS", False );
00218 motifWmHints.flags = 2;
00219 motifWmHints.decorations = 0;
00220 XChangeProperty( m_pDisplay, m_mainWindow, hints_atom, hints_atom, 32,
00221 PropModeReplace, (unsigned char *)&motifWmHints,
00222 sizeof( motifWmHints ) / sizeof( long ) );
00223
00224
00225 XStoreName( m_pDisplay, m_mainWindow, "VLC Media Player" );
00226
00227
00228 XSelectInput( m_pDisplay, m_mainWindow, StructureNotifyMask );
00229
00230
00231 Region mask = XCreateRegion();
00232 XShapeCombineRegion( m_pDisplay, m_mainWindow, ShapeBounding, 0, 0,
00233 mask, ShapeSet );
00234 XDestroyRegion( mask );
00235
00236
00237 XMapWindow( m_pDisplay, m_mainWindow);
00238
00239
00240 XMoveWindow( m_pDisplay, m_mainWindow, -10, -10 );
00241 }
00242 }
00243
00244
00245 X11Display::~X11Display()
00246 {
00247 if( m_mainWindow )
00248 {
00249 XDestroyWindow( m_pDisplay, m_mainWindow );
00250 }
00251 if( m_gc )
00252 {
00253 XFreeGC( m_pDisplay, m_gc );
00254 }
00255 if( m_colormap )
00256 {
00257 XFreeColormap( m_pDisplay, m_colormap );
00258 }
00259 if( m_pDisplay )
00260 {
00261 XCloseDisplay( m_pDisplay );
00262 }
00263 }
00264
00265
00266 void X11Display::getShifts( uint32_t mask, int &rLeftShift,
00267 int &rRightShift ) const
00268 {
00269 for( rLeftShift = 0; (rLeftShift < 32) && !(mask & 1); rLeftShift++ )
00270 {
00271 mask >>= 1;
00272 }
00273 for( rRightShift = 8; (mask & 1) ; rRightShift--)
00274 {
00275 mask >>= 1;
00276 }
00277 if( rRightShift < 0 )
00278 {
00279 rLeftShift -= rRightShift;
00280 rRightShift = 0;
00281 }
00282 }
00283
00284
00285 void X11Display::blendPixel8( uint8_t *pPixel, uint8_t r, uint8_t g,
00286 uint8_t b, uint8_t a ) const
00287 {
00288 uint8_t value = 255 - *pPixel;
00289
00290 BLEND_PIXEL(value, r, g, b, a, uint8_t)
00291
00292 *pPixel = 255 - value;
00293 }
00294
00295
00296 void X11Display::blendPixel16MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
00297 uint8_t b, uint8_t a ) const
00298 {
00299 uint16_t value = pPixel[1] | pPixel[0] << 8;
00300
00301 BLEND_PIXEL(value, r, g, b, a, uint16_t)
00302
00303 pPixel[1] = value; value >>= 8;
00304 pPixel[0] = value;
00305 }
00306
00307
00308 void X11Display::blendPixel16LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
00309 uint8_t b, uint8_t a ) const
00310 {
00311 uint16_t value = pPixel[0] | pPixel[1] << 8;
00312
00313 BLEND_PIXEL(value, r, g, b, a, uint16_t)
00314
00315 pPixel[0] = value; value >>= 8;
00316 pPixel[1] = value;
00317 }
00318
00319
00320 void X11Display::blendPixel32MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
00321 uint8_t b, uint8_t a ) const
00322 {
00323 uint32_t value = pPixel[3] | pPixel[2] << 8 | pPixel[1] << 16 |
00324 pPixel[0] << 24;
00325
00326 BLEND_PIXEL(value, r, g, b, a, uint32_t)
00327
00328 pPixel[3] = value; value >>= 8;
00329 pPixel[2] = value; value >>= 8;
00330 pPixel[1] = value; value >>= 8;
00331 pPixel[0] = value;
00332 }
00333
00334
00335 void X11Display::blendPixel32LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
00336 uint8_t b, uint8_t a ) const
00337 {
00338 uint32_t value = pPixel[0] | pPixel[1] << 8 | pPixel[2] << 16 |
00339 pPixel[3] << 24;
00340
00341 BLEND_PIXEL(value, r, g, b, a, uint32_t)
00342
00343 pPixel[0] = value; value >>= 8;
00344 pPixel[1] = value; value >>= 8;
00345 pPixel[2] = value; value >>= 8;
00346 pPixel[3] = value;
00347 }
00348
00349
00350 void X11Display::putPixel8( uint8_t *pPixel, uint8_t r, uint8_t g,
00351 uint8_t b, uint8_t a ) const
00352 {
00353 uint8_t value = 255 - *pPixel;
00354
00355 PUT_PIXEL(value, r, g, b, uint8_t)
00356
00357 *pPixel = 255 - value;
00358 }
00359
00360
00361 void X11Display::putPixel16MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
00362 uint8_t b, uint8_t a ) const
00363 {
00364 uint16_t value = pPixel[1] | pPixel[0] << 8;
00365
00366 PUT_PIXEL(value, r, g, b, uint16_t)
00367
00368 pPixel[1] = value; value >>= 8;
00369 pPixel[0] = value;
00370 }
00371
00372
00373 void X11Display::putPixel16LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
00374 uint8_t b, uint8_t a ) const
00375 {
00376 uint16_t value = pPixel[0] | pPixel[1] << 8;
00377
00378 PUT_PIXEL(value, r, g, b, uint16_t)
00379
00380 pPixel[0] = value; value >>= 8;
00381 pPixel[1] = value;
00382 }
00383
00384
00385 void X11Display::putPixel32MSB( uint8_t *pPixel, uint8_t r, uint8_t g,
00386 uint8_t b, uint8_t a ) const
00387 {
00388 uint32_t value = pPixel[3] | pPixel[2] << 8 | pPixel[1] << 16 |
00389 pPixel[0] << 24;
00390
00391 PUT_PIXEL(value, r, g, b, uint32_t)
00392
00393 pPixel[3] = value; value >>= 8;
00394 pPixel[2] = value; value >>= 8;
00395 pPixel[1] = value; value >>= 8;
00396 pPixel[0] = value;
00397 }
00398
00399
00400 void X11Display::putPixel32LSB( uint8_t *pPixel, uint8_t r, uint8_t g,
00401 uint8_t b, uint8_t a ) const
00402 {
00403 uint32_t value = pPixel[0] | pPixel[1] << 8 | pPixel[2] << 16 |
00404 pPixel[3] << 24;
00405
00406 PUT_PIXEL(value, r, g, b, uint32_t)
00407
00408 pPixel[0] = value; value >>= 8;
00409 pPixel[1] = value; value >>= 8;
00410 pPixel[2] = value; value >>= 8;
00411 pPixel[3] = value;
00412 }
00413
00414
00415 unsigned long X11Display::getPixelValue( uint8_t r, uint8_t g, uint8_t b )
00416 const
00417 {
00418 unsigned long value;
00419
00420 PUT_PIXEL(value, r, g, b, uint32_t)
00421
00422 if( m_pixelSize == 1 )
00423 {
00424 return 255 - value;
00425 }
00426 else
00427 {
00428 return value;
00429 }
00430 }
00431
00432
00433 #endif