Release 940602
[wine] / objects / bitmap.c
1 /*
2  * GDI bitmap objects
3  *
4  * Copyright 1993 Alexandre Julliard
5  */
6
7 static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
8
9 #include <stdlib.h>
10 #include <X11/Xlib.h>
11 #include <X11/Xutil.h>
12 #include "gdi.h"
13 #include "bitmap.h"
14
15
16   /* Handle of the bitmap selected by default in a memory DC */
17 HBITMAP BITMAP_hbitmapMemDC = 0;
18
19   /* GCs used for B&W and color bitmap operations */
20 GC BITMAP_monoGC = 0, BITMAP_colorGC = 0;
21
22
23 /***********************************************************************
24  *           BITMAP_Init
25  */
26 BOOL BITMAP_Init()
27 {
28     Pixmap tmpPixmap;
29     
30       /* Create the necessary GCs */
31     
32     if ((tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 )))
33     {
34         BITMAP_monoGC = XCreateGC( display, tmpPixmap, 0, NULL );
35         XSetGraphicsExposures( display, BITMAP_monoGC, False );
36         XFreePixmap( display, tmpPixmap );
37     }
38
39     if (screenDepth != 1)
40     {
41         if ((tmpPixmap = XCreatePixmap(display, rootWindow, 1,1,screenDepth)))
42         {
43             BITMAP_colorGC = XCreateGC( display, tmpPixmap, 0, NULL );
44             XSetGraphicsExposures( display, BITMAP_colorGC, False );
45             XFreePixmap( display, tmpPixmap );
46         }
47     }
48
49     BITMAP_hbitmapMemDC = CreateBitmap( 1, 1, 1, 1, NULL );
50     return (BITMAP_hbitmapMemDC != 0);
51 }
52
53
54 /***********************************************************************
55  *           BITMAP_BmpToImage
56  *
57  * Create an XImage pointing to the bitmap data.
58  */
59 static XImage *BITMAP_BmpToImage( BITMAP * bmp, void * bmpData )
60 {
61     extern void _XInitImageFuncPtrs( XImage* );
62     XImage * image;
63
64     image = XCreateImage( XT_display, DefaultVisualOfScreen(screen),
65                           bmp->bmBitsPixel, ZPixmap, 0, bmpData,
66                           bmp->bmWidth, bmp->bmHeight, 16, bmp->bmWidthBytes );
67     if (!image) return 0;
68     image->byte_order = MSBFirst;
69     image->bitmap_bit_order = MSBFirst;
70     image->bitmap_unit = 16;
71     _XInitImageFuncPtrs(image);
72     return image;
73 }
74
75
76 /***********************************************************************
77  *           CreateBitmap    (GDI.48)
78  */
79 HBITMAP CreateBitmap( short width, short height, 
80                       BYTE planes, BYTE bpp, LPSTR bits )
81 {
82     BITMAP bitmap = { 0, width, height, 0, planes, bpp, bits };
83 #ifdef DEBUG_GDI
84     printf( "CreateBitmap: %dx%d, %d colors\n", 
85              width, height, 1 << (planes*bpp) );
86 #endif
87     return CreateBitmapIndirect( &bitmap );
88 }
89
90
91 /***********************************************************************
92  *           CreateCompatibleBitmap    (GDI.51)
93  */
94 HBITMAP CreateCompatibleBitmap( HDC hdc, short width, short height )
95 {
96     DC * dc;
97 #ifdef DEBUG_GDI
98     printf( "CreateCompatibleBitmap: %d %dx%d\n", hdc, width, height );
99 #endif
100     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
101     return CreateBitmap( width, height, 1, dc->w.bitsPerPixel, NULL );
102 }
103
104
105 /***********************************************************************
106  *           CreateBitmapIndirect    (GDI.49)
107  */
108 HBITMAP CreateBitmapIndirect( BITMAP * bmp )
109 {
110     BITMAPOBJ * bmpObjPtr;
111     HBITMAP hbitmap;
112
113       /* Check parameters */
114     if (!bmp->bmHeight || !bmp->bmWidth) return 0;
115     if (bmp->bmPlanes != 1) return 0;
116     if ((bmp->bmBitsPixel != 1) && (bmp->bmBitsPixel != screenDepth)) return 0;
117
118       /* Create the BITMAPOBJ */
119     hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
120     if (!hbitmap) return 0;
121     bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_ADDR( hbitmap );
122
123     bmpObjPtr->size.cx = 0;
124     bmpObjPtr->size.cy = 0;
125     bmpObjPtr->bitmap  = *bmp;
126     bmpObjPtr->bitmap.bmBits = NULL;
127     bmpObjPtr->bitmap.bmWidthBytes = (bmp->bmWidth*bmp->bmBitsPixel+15)/16 * 2;
128
129       /* Create the pixmap */
130     bmpObjPtr->pixmap = XCreatePixmap( display, rootWindow, bmp->bmWidth,
131                                        bmp->bmHeight, bmp->bmBitsPixel );
132     if (!bmpObjPtr->pixmap)
133     {
134         GDI_HEAP_FREE( hbitmap );
135         hbitmap = 0;
136     }
137     else if (bmp->bmBits)  /* Set bitmap bits */
138         SetBitmapBits( hbitmap, bmp->bmHeight*bmp->bmWidthBytes, bmp->bmBits );
139     return hbitmap;
140 }
141
142
143 /***********************************************************************
144  *           GetBitmapBits    (GDI.74)
145  */
146 LONG GetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer )
147 {
148     BITMAPOBJ * bmp;
149     LONG height;
150     XImage * image;
151     
152     bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
153     if (!bmp) return 0;
154
155 #ifdef DEBUG_BITMAP
156     printf( "GetBitmapBits: %dx%d %d colors %p\n",
157             bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
158             1 << bmp->bitmap.bmBitsPixel, buffer );
159 #endif
160       /* Only get entire lines */
161     height = count / bmp->bitmap.bmWidthBytes;
162     if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
163     if (!height) return 0;
164     
165     if (!(image = BITMAP_BmpToImage( &bmp->bitmap, buffer ))) return 0;
166     XGetSubImage( display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth, height,
167                   AllPlanes, ZPixmap, image, 0, 0 );
168     image->data = NULL;
169     XDestroyImage( image );
170     return height * bmp->bitmap.bmWidthBytes;
171 }
172
173
174 /***********************************************************************
175  *           SetBitmapBits    (GDI.106)
176  */
177 LONG SetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer )
178 {
179     BITMAPOBJ * bmp;
180     LONG height;
181     XImage * image;
182     
183     bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
184     if (!bmp) return 0;
185
186 #ifdef DEBUG_BITMAP
187     printf( "SetBitmapBits: %dx%d %d colors %p\n",
188             bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
189             1 << bmp->bitmap.bmBitsPixel, buffer );
190 #endif
191       /* Only set entire lines */
192     height = count / bmp->bitmap.bmWidthBytes;
193     if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
194     if (!height) return 0;
195         
196     if (!(image = BITMAP_BmpToImage( &bmp->bitmap, buffer ))) return 0;
197     XPutImage( display, bmp->pixmap, BITMAP_GC(bmp), image, 0, 0,
198                0, 0, bmp->bitmap.bmWidth, height );
199     image->data = NULL;
200     XDestroyImage( image );
201     return height * bmp->bitmap.bmWidthBytes;
202 }
203
204
205 /***********************************************************************
206  *           BMP_DeleteObject
207  */
208 BOOL BMP_DeleteObject( HBITMAP hbitmap, BITMAPOBJ * bitmap )
209 {
210     XFreePixmap( display, bitmap->pixmap );
211     return GDI_FreeObject( hbitmap );
212 }
213
214         
215 /***********************************************************************
216  *           BMP_GetObject
217  */
218 int BMP_GetObject( BITMAPOBJ * bmp, int count, LPSTR buffer )
219 {
220     if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
221     memcpy( buffer, &bmp->bitmap, count );
222     return count;
223 }
224     
225
226 /***********************************************************************
227  *           BITMAP_SelectObject
228  */
229 HBITMAP BITMAP_SelectObject( HDC hdc, DC * dc, HBITMAP hbitmap,
230                              BITMAPOBJ * bmp )
231 {
232     HBITMAP prevHandle = dc->w.hBitmap;
233     
234     if (!(dc->w.flags & DC_MEMORY)) return 0;
235     dc->u.x.drawable = bmp->pixmap;
236     dc->w.DCSizeX    = bmp->bitmap.bmWidth;
237     dc->w.DCSizeY    = bmp->bitmap.bmHeight;
238     dc->w.hBitmap    = hbitmap;
239
240       /* Change GC depth if needed */
241
242     if (dc->w.bitsPerPixel != bmp->bitmap.bmBitsPixel)
243     {
244         XFreeGC( display, dc->u.x.gc );
245         dc->u.x.gc = XCreateGC( display, dc->u.x.drawable, 0, NULL );
246         dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel;
247           /* Re-select objects with changed depth */
248         SelectObject( hdc, dc->w.hPen );
249         SelectObject( hdc, dc->w.hBrush );
250     }
251     return prevHandle;
252 }
253
254 /***********************************************************************
255  *           CreateDiscardableBitmap    (GDI.156)
256  */
257 HBITMAP CreateDiscardableBitmap(HDC hdc, short width, short height)
258 {
259     printf("CreateDiscardableBitmap(%04X, %d, %d); "
260            "// call CreateCompatibleBitmap() for now!\n",
261            hdc, width, height);
262     return CreateCompatibleBitmap(hdc, width, height);
263 }
264
265 /***********************************************************************
266  *           GetBitmapDimensionEx    (GDI.468)
267  */
268 BOOL GetBitmapDimensionEx( HBITMAP hbitmap, LPSIZE size )
269 {
270     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
271     if (!bmp) return FALSE;
272     *size = bmp->size;
273     return TRUE;
274 }
275
276
277 /***********************************************************************
278  *           GetBitmapDimension    (GDI.162)
279  */
280 DWORD GetBitmapDimension( HBITMAP hbitmap )
281 {
282     SIZE size;
283     if (!GetBitmapDimensionEx( hbitmap, &size )) return 0;
284     return size.cx | (size.cy << 16);
285 }
286
287 /***********************************************************************
288  *           SetBitmapDimensionEx    (GDI.478)
289  */
290 BOOL SetBitmapDimensionEx( HBITMAP hbitmap, short x, short y, LPSIZE prevSize )
291 {
292     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
293     if (!bmp) return FALSE;
294     if (prevSize) *prevSize = bmp->size;
295     bmp->size.cx = x;
296     bmp->size.cy = y;
297     return TRUE;
298 }
299
300
301 /***********************************************************************
302  *           SetBitmapDimension    (GDI.163)
303  */
304 DWORD SetBitmapDimension( HBITMAP hbitmap, short x, short y )
305 {
306     SIZE size;
307     if (!SetBitmapDimensionEx( hbitmap, x, y, &size )) return 0;
308     return size.cx | (size.cy << 16);    
309 }