Release 981025.
[wine/multimedia.git] / graphics / wing.c
blob021667092065e6e14a61b2d1a89c97cadc2915ed
1 /*
2 * WinG support
4 * Started by Robert Pouliot <krynos@clic.net>
5 */
7 #include "ts_xlib.h"
8 #include "ts_xshm.h"
9 #include <sys/types.h>
10 #include <sys/ipc.h>
11 #ifndef __EMX__
12 #include <sys/shm.h>
13 #endif
15 #include "windows.h"
16 #include "bitmap.h"
17 #include "dc.h"
18 #include "gdi.h"
19 #include "xmalloc.h"
20 #include "debug.h"
22 typedef enum WING_DITHER_TYPE
24 WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4
25 } WING_DITHER_TYPE;
27 static int __WinGOK = -1;
29 /*
30 * WinG DIB bitmaps can be selected into DC and then scribbled upon
31 * by GDI functions. They can also be changed directly. This gives us
32 * three choices
33 * - use original WinG 16-bit DLL
34 * requires working 16-bit driver interface
35 * - implement DIB graphics driver from scratch
36 * see wing.zip size
37 * - use shared pixmaps
38 * won't work with some videocards and/or videomodes
39 * 961208 - AK
42 static BITMAPINFOHEADER __bmpiWinG = { 0, 1, -1, 1, 8, BI_RGB, 1, 0, 0, 0, 0 };
44 static void __initWinG(void)
46 if( __WinGOK < 0 )
48 Status s = TSXShmQueryExtension(display);
49 if( s )
51 int i = TSXShmPixmapFormat(display);
52 if( i == ZPixmap && screenDepth == 8 )
54 __WinGOK = True;
55 return;
58 FIXME(wing,"WinG: incorrect depth or unsupported card.\n");
59 __WinGOK = False;
63 /***********************************************************************
64 * WinGCreateDC16 (WING.1001)
66 HDC16 WINAPI WinGCreateDC16(void)
68 __initWinG();
70 if( __WinGOK > 0 )
71 return CreateCompatibleDC16(0);
72 return (HDC16)NULL;
75 /***********************************************************************
76 * WinGRecommendDIBFormat16 (WING.1002)
78 BOOL16 WINAPI WinGRecommendDIBFormat16(BITMAPINFO *fmt)
80 FIXME(wing,"(%p): stub\n", fmt);
82 if( __WinGOK > 0 && fmt )
84 memcpy(&fmt->bmiHeader, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
85 return TRUE;
87 return FALSE;
90 /***********************************************************************
91 * WinGCreateBitmap16 (WING.1003)
93 HBITMAP16 WINAPI WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header,
94 void **bits)
96 FIXME(wing,"(%x,%p,%p): empty stub! (expect failure)\n",
97 winDC, header, bits);
98 if( __WinGOK > 0 && header )
100 BITMAPINFOHEADER* bmpi = &header->bmiHeader;
102 FIXME(wing,"bytes=%i,planes=%i,bpp=%i,x=%i,y=%i,rle=0x%08x,size=%i\n",
103 (int)bmpi->biSize, bmpi->biPlanes, bmpi->biBitCount,
104 (int)bmpi->biWidth, (int)bmpi->biHeight,
105 (unsigned)bmpi->biCompression, (int)bmpi->biSizeImage);
107 #ifdef PRELIMINARY_WING16_SUPPORT
108 if( bmpi->biPlanes == __bmpiWinG.biPlanes && bmpi->biBitCount == __bmpiWinG.biBitCount &&
109 bmpi->biCompression == __bmpiWinG.biCompression && (int)bmpi->biHeight < 0 &&
110 bmpi->biWidth )
112 unsigned bytes = (bmpi->biWidth + bmpi->biWidth % 2)*(-bmpi->biHeight) * bmpi->biBitCount/8;
113 int key = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0x01FF);
115 if( key )
117 /* Create the BITMAPOBJ
119 * FIXME: A facility to manage shared memory structures
120 * which would clean up when Wine crashes. Perhaps a part of
121 * IPC code can be adapted. Otherwise this code leaves a lot
122 * of junk in shared memory.
125 HBITMAP16 hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
126 if (hbitmap)
128 __ShmBitmapCtl* p = (__ShmBitmapCtl*)xmalloc(sizeof(__ShmBitmapCtl));
129 BITMAPOBJ* bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap );
131 bmpObjPtr->size.cx = 0;
132 bmpObjPtr->size.cy = 0;
133 bmpObjPtr->bitmap.bmType = 0;
134 bmpObjPtr->bitmap.bmWidth = (INT16)abs(bmpi->biWidth);
135 bmpObjPtr->bitmap.bmHeight = -(INT16)bmpi->biHeight;
136 bmpObjPtr->bitmap.bmPlanes = (BYTE)bmpi->biPlanes;
137 bmpObjPtr->bitmap.bmBitsPixel = (BYTE)bmpi->biBitCount;
138 bmpObjPtr->bitmap.bmWidthBytes =
139 (INT16)BITMAP_WIDTH_BYTES( bmpObjPtr->bitmap.bmWidth, bmpi->biBitCount );
140 bmpObjPtr->bitmap.bmBits = (SEGPTR)p;
142 p->si.shmid = key;
143 p->si.shmaddr = shmat(key, NULL, 0);
144 p->si.readOnly = False;
146 if( p->si.shmaddr )
148 WORD sel = 0;
150 TSXShmAttach(display, &p->si);
151 bmpObjPtr->pixmap = XShmCreatePixmap(display, rootWindow,
152 p->si.shmaddr, &p->si, bmpObjPtr->bitmap.bmWidth,
153 bmpObjPtr->bitmap.bmHeight, bmpi->biBitCount );
154 if( bmpObjPtr->pixmap )
156 sel = SELECTOR_AllocBlock( p->si.shmaddr, bytes,
157 SEGMENT_DATA, FALSE, FALSE);
158 if (sel) p->bits = PTR_SEG_OFF_TO_SEGPTR(sel,0);
159 else TSXFreePixmap( display, bmpObjPtr->pixmap );
161 if( !sel )
163 shmdt( p->si.shmaddr );
164 p->si.shmaddr = NULL;
167 if( !p->si.shmaddr )
169 GDI_FreeObject( hbitmap );
170 hbitmap = 0;
173 GDI_HEAP_UNLOCK( hbitmap );
174 return hbitmap;
177 #endif
179 return 0;
182 /***********************************************************************
183 * WinGGetDIBPointer (WING.1004)
185 SEGPTR WINAPI WinGGetDIBPointer16(HBITMAP16 hWinGBitmap, BITMAPINFO* bmpi)
187 #ifdef PRELIMINARY_WING16_SUPPORT
188 BITMAPOBJ* bmp = (BITMAPOBJ *) GDI_GetObjPtr( hWinGBitmap, BITMAP_MAGIC );
190 if( bmp )
192 __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
193 if( p )
195 if( bmpi ) memcpy( bmpi, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
196 GDI_HEAP_UNLOCK( hWinGBitmap );
197 return p->bits;
200 #endif
201 return (SEGPTR)NULL;
204 /***********************************************************************
205 * WinGSetDIBColorTable (WING.1004)
207 UINT16 WINAPI WinGSetDIBColorTable16(HDC16 hWinGDC, UINT16 start, UINT16 num,
208 RGBQUAD* pColor)
210 FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",hWinGDC,start,num,pColor);
211 return num;
214 /***********************************************************************
215 * WinGGetDIBColorTable16 (WING.1005)
217 UINT16 WINAPI WinGGetDIBColorTable16(HDC16 winDC, UINT16 start,
218 UINT16 num, RGBQUAD* colors)
220 FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",winDC,start,num,colors);
221 return 0;
224 /***********************************************************************
225 * WinGCreateHalfTonePalette16 (WING.1007)
227 HPALETTE16 WINAPI WinGCreateHalfTonePalette16(void)
229 FIXME(wing,"(void): empty stub!\n");
230 return 0;
233 /***********************************************************************
234 * WinGCreateHalfToneBrush16 (WING.1008)
236 HPALETTE16 WINAPI WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col,
237 WING_DITHER_TYPE type)
239 FIXME(wing,"(...): empty stub!\n");
240 return 0;
243 /***********************************************************************
244 * WinGStretchBlt16 (WING.1009)
246 BOOL16 WINAPI WinGStretchBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
247 INT16 widDest, INT16 heiDest,
248 HDC16 srcDC, INT16 xSrc, INT16 ySrc,
249 INT16 widSrc, INT16 heiSrc)
252 return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
255 /***********************************************************************
256 * WinGBitBlt16 (WING.1010)
258 BOOL16 WINAPI WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
259 INT16 widDest, INT16 heiDest, HDC16 srcDC,
260 INT16 xSrc, INT16 ySrc)
262 /* destDC is a display DC, srcDC is a memory DC */
264 DC *dcDst, *dcSrc;
266 if (!(dcDst = (DC *)GDI_GetObjPtr( destDC, DC_MAGIC ))) return FALSE;
267 if (!(dcSrc = (DC *) GDI_GetObjPtr( srcDC, DC_MAGIC ))) return FALSE;
269 if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );
271 xSrc = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
272 ySrc = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
273 xDest = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
274 yDest = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
275 widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
276 heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;
278 TSXSetFunction( display, dcDst->u.x.gc, GXcopy );
279 TSXCopyArea( display, dcSrc->u.x.drawable,
280 dcDst->u.x.drawable, dcDst->u.x.gc,
281 xSrc, ySrc, widDest, heiDest, xDest, yDest );
282 return TRUE;