5d6d37651b53d5ea92041b403ddd83eff9152f1d
[vlc.git] / modules / gui / skins / x11 / x11_bitmap.cpp
1 /*****************************************************************************
2  * x11_bitmap.cpp: X11 implementation of the Bitmap class
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: x11_bitmap.cpp,v 1.5 2003/05/19 21:39:34 asmax Exp $
6  *
7  * Authors: Cyril Deguet     <asmax@videolan.org>
8  *          Emmanuel Puig    <karibu@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,
23  * USA.
24  *****************************************************************************/
25
26 #ifdef X11_SKINS
27
28 //--- X11 -------------------------------------------------------------------
29 #include <X11/Xlib.h>
30 #include <X11/Xutil.h>
31
32 //--- VLC -------------------------------------------------------------------
33 #include <vlc/intf.h>
34
35 //--- SKIN ------------------------------------------------------------------
36 #include "../os_api.h"
37 #include "../src/graphics.h"
38 #include "x11_graphics.h"
39 #include "../src/bitmap.h"
40 #include "x11_bitmap.h"
41 #include "../src/theme.h"
42 #include "../os_theme.h"
43 #include "../src/skin_common.h"
44
45 #include <stdio.h>
46
47 // macros to read little endian numbers
48 #define U16( p ) ( ((uint8_t*)(p))[0] | ((uint8_t*)(p))[1] << 8 )
49 #define U32( p ) ( U16( p ) | ((uint8_t*)(p))[2] << 16 | ((uint8_t*)(p))[3] << 24 )
50
51 //---------------------------------------------------------------------------
52 //   X11Bitmap
53 //---------------------------------------------------------------------------
54 X11Bitmap::X11Bitmap( intf_thread_t *_p_intf, string FileName, int AColor )
55     : Bitmap( p_intf, FileName, AColor )
56 {
57     p_intf = _p_intf;
58     
59     // Find the display
60     display = p_intf->p_sys->display;
61     int screen = DefaultScreen( display );
62     int depth = DefaultDepth( display, screen );
63     Screen *screenptr = DefaultScreenOfDisplay( display );
64     Visual *visual = DefaultVisualOfScreen( screenptr );
65     char *data = NULL;
66     Width = 0;
67     Height = 0;
68
69     // TODO: check for endianness issues
70     AlphaColor = (AColor & 0xff) << 16 | (AColor & 0xff00) | 
71                  (AColor & 0xff0000) >> 16;
72
73     if( FileName != "" )
74     {
75         data = LoadFromFile( FileName, depth, AlphaColor, Width, Height );
76     }
77
78     // Create the image
79     Bmp = XCreateImage( display, visual, depth, ZPixmap, 0, data, Width, 
80                         Height, 32, 4 * Width );
81     XInitImage( Bmp );
82     
83 }
84 //---------------------------------------------------------------------------
85 X11Bitmap::X11Bitmap( intf_thread_t *_p_intf, Graphics *from, int x, int y,
86     int w, int h, int AColor ) : Bitmap( p_intf, from, x, y, w, h, AColor )
87 {
88     p_intf = _p_intf;
89 /*    Width  = w;
90     Height = h;
91     AlphaColor = AColor;
92     HBITMAP HBmp;
93     HDC fromDC = ( (X11Graphics *)from )->GetImageHandle();
94
95     // Create image
96     bmpDC = CreateCompatibleDC( fromDC );
97     HBmp  = CreateCompatibleBitmap( fromDC, Width, Height );
98     SelectObject( bmpDC, HBmp );
99     DeleteObject( HBmp );
100     BitBlt( bmpDC, 0, 0, Width, Height, fromDC, x, y, SRCCOPY );*/
101 }
102 //---------------------------------------------------------------------------
103 X11Bitmap::X11Bitmap( intf_thread_t *_p_intf, Bitmap *c )
104     : Bitmap( p_intf, c )
105 {
106     p_intf = _p_intf;
107 /*    HBITMAP HBuf;
108
109     // Copy attibutes
110     c->GetSize( Width, Height );
111     AlphaColor = c->GetAlphaColor();
112
113     // Copy bmpDC
114     bmpDC = CreateCompatibleDC( NULL );
115     HBuf  = CreateCompatibleBitmap( bmpDC, Width, Height );
116     SelectObject( bmpDC, HBuf );
117
118     BitBlt( bmpDC, 0, 0, Width, Height, ( (X11Bitmap *)c )->GetBmpDC(),
119             0, 0, SRCCOPY );
120     DeleteObject( HBuf );*/
121 }
122 //---------------------------------------------------------------------------
123 X11Bitmap::~X11Bitmap()
124 {
125     XDestroyImage( Bmp );
126 }
127 //---------------------------------------------------------------------------
128 void X11Bitmap::DrawBitmap( int x, int y, int w, int h, int xRef, int yRef,
129                               Graphics *dest )
130 {
131     Drawable destImg = ( (X11Graphics *)dest )->GetImage();
132     GC destGC = ( (X11Graphics *)dest )->GetGC();
133     XPutImage( display, destImg, destGC, Bmp, x, y, xRef, yRef, w, h );
134 }
135 //---------------------------------------------------------------------------
136 bool X11Bitmap::Hit( int x, int y)
137 {
138 //    unsigned int c = (unsigned int)GetBmpPixel( x, y );
139
140 /*    if( c == -1 || c == AlphaColor )
141         return false;
142     else
143         return true;*/
144     return true;
145 }
146 //---------------------------------------------------------------------------
147 int X11Bitmap::GetBmpPixel( int x, int y )
148 {
149     if( !Bmp || x < 0 || x >= Width || y < 0 || y >= Height )
150         return -1;
151
152 /*    guchar *pixels;
153     int rowstride, offset;
154     gboolean has_alpha;
155
156     rowstride = gdk_pixbuf_get_rowstride( Bmp );
157     pixels    = gdk_pixbuf_get_pixels( Bmp ); 
158     has_alpha = gdk_pixbuf_get_has_alpha( Bmp );
159
160     offset = y * rowstride + ( x * (has_alpha ? 4 : 3) );
161
162     int r = pixels [offset];
163     int g = pixels [offset + 1] << 8;
164     int b = pixels [offset + 2] << 16;
165
166     return r + g + b;*/
167 }
168 //---------------------------------------------------------------------------
169 void X11Bitmap::SetBmpPixel( int x, int y, int color )
170 {
171 //    SetPixelV( bmpDC, x, y, color );
172 }
173 //---------------------------------------------------------------------------
174 char *X11Bitmap::LoadFromFile( string fileName, int depth, int AColor,
175                                int &width, int &height )
176 {
177     // BMP header fields
178     uint32_t fileSize;
179     uint32_t dataOffset;
180     uint32_t headerSize;
181         uint16_t planes;
182         uint16_t bpp;
183         uint32_t compression;
184         uint32_t dataSize;
185         uint32_t nColors;
186     
187     FILE *file = fopen( fileName.c_str(), "ro" );
188     if( !file )
189     {
190         msg_Warn( p_intf, "Cannot open %s", fileName.c_str() );
191         return NULL;
192     }
193
194     // Read the headers
195     char headers[54];
196     fread( headers, 54, 1, file );
197     
198     fileSize = U32( headers + 2 );
199     dataOffset = U32( headers + 10 );
200     headerSize = U32( headers + 14 );
201     width = (int32_t) U32( headers + 18 );
202     height = (int32_t) U32( headers + 22 ); 
203     planes = U32( headers + 26 );
204     bpp = U32( headers + 28 );
205     compression = U32( headers + 30 );
206     dataSize = U32( headers + 34 );
207     nColors = U32( headers + 50 );
208
209     switch( bpp )
210     {
211         case 24:
212         // 24 bits per pixel
213         {
214             // Pad to a 32bit boundary
215             int pad = ((3 * width - 1) / 4) * 4 + 4 - 3 * width;
216             uint32_t *data = new uint32_t[height * width];
217             uint32_t *ptr;
218             for( int j = 0; j < height; j++ )
219             {
220                 ptr = data +  width * (height - j - 1);
221                 for( int i = 0; i < width; i++ )
222                 {
223                     // Read a pixel
224                     uint32_t pixel = 0;
225                     fread( &pixel, 3, 1, file );
226                     pixel = U32( &pixel );
227                     // Handle transparency
228                     if( pixel == 0 && AColor != 0 )
229                     {
230                         pixel = 10; // slight blue
231                     }
232                     else if( pixel == AColor )
233                     {
234                         pixel = 0;  // global alpha color is black
235                     }
236                     *(ptr++) = pixel;
237                 }
238                 fseek( file, pad, SEEK_CUR );
239             }
240             return (char*)data;
241         }
242         default:
243             msg_Warn( p_intf, "%s : %d bbp not supported !", fileName.c_str(), 
244                       bpp );
245             return NULL;
246     }
247     
248 }
249 //---------------------------------------------------------------------------
250
251 #endif