Playing a non-existent CD should fail instead of crash.
[wine/multimedia.git] / graphics / wing.c
blob52c9288cd470c3f45298ea37e094ccdd9644289b
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 "x11drv.h"
21 #include "debug.h"
23 typedef enum WING_DITHER_TYPE
25 WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4
26 } WING_DITHER_TYPE;
28 static int __WinGOK = -1;
30 /*
31 * WinG DIB bitmaps can be selected into DC and then scribbled upon
32 * by GDI functions. They can also be changed directly. This gives us
33 * three choices
34 * - use original WinG 16-bit DLL
35 * requires working 16-bit driver interface
36 * - implement DIB graphics driver from scratch
37 * see wing.zip size
38 * - use shared pixmaps
39 * won't work with some videocards and/or videomodes
40 * 961208 - AK
43 static BITMAPINFOHEADER __bmpiWinG = { 0, 1, -1, 1, 8, BI_RGB, 1, 0, 0, 0, 0 };
45 static void __initWinG(void)
47 if( __WinGOK < 0 )
49 Status s = TSXShmQueryExtension(display);
50 if( s )
52 int i = TSXShmPixmapFormat(display);
53 if( i == ZPixmap && screenDepth == 8 )
55 __WinGOK = True;
56 return;
59 FIXME(wing,"WinG: incorrect depth or unsupported card.\n");
60 __WinGOK = False;
64 /***********************************************************************
65 * WinGCreateDC16 (WING.1001)
67 HDC16 WINAPI WinGCreateDC16(void)
69 __initWinG();
71 if( __WinGOK > 0 )
72 return CreateCompatibleDC16(0);
73 return (HDC16)NULL;
76 /***********************************************************************
77 * WinGRecommendDIBFormat16 (WING.1002)
79 BOOL16 WINAPI WinGRecommendDIBFormat16(BITMAPINFO *fmt)
81 FIXME(wing,"(%p): stub\n", fmt);
83 if( __WinGOK > 0 && fmt )
85 memcpy(&fmt->bmiHeader, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
86 return TRUE;
88 return FALSE;
91 /***********************************************************************
92 * WinGCreateBitmap16 (WING.1003)
94 HBITMAP16 WINAPI WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header,
95 void **bits)
97 FIXME(wing,"(%x,%p,%p): empty stub! (expect failure)\n",
98 winDC, header, bits);
99 if( __WinGOK > 0 && header )
101 BITMAPINFOHEADER* bmpi = &header->bmiHeader;
103 FIXME(wing,"bytes=%i,planes=%i,bpp=%i,x=%i,y=%i,rle=0x%08x,size=%i\n",
104 (int)bmpi->biSize, bmpi->biPlanes, bmpi->biBitCount,
105 (int)bmpi->biWidth, (int)bmpi->biHeight,
106 (unsigned)bmpi->biCompression, (int)bmpi->biSizeImage);
108 #ifdef PRELIMINARY_WING16_SUPPORT
109 if( bmpi->biPlanes == __bmpiWinG.biPlanes && bmpi->biBitCount == __bmpiWinG.biBitCount &&
110 bmpi->biCompression == __bmpiWinG.biCompression && (int)bmpi->biHeight < 0 &&
111 bmpi->biWidth )
113 unsigned bytes = (bmpi->biWidth + bmpi->biWidth % 2)*(-bmpi->biHeight) * bmpi->biBitCount/8;
114 int key = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0x01FF);
116 if( key )
118 /* Create the BITMAPOBJ
120 * FIXME: A facility to manage shared memory structures
121 * which would clean up when Wine crashes. Perhaps a part of
122 * IPC code can be adapted. Otherwise this code leaves a lot
123 * of junk in shared memory.
126 HBITMAP16 hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
127 if (hbitmap)
129 __ShmBitmapCtl* p = (__ShmBitmapCtl*)xmalloc(sizeof(__ShmBitmapCtl));
130 BITMAPOBJ* bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap );
132 bmpObjPtr->size.cx = 0;
133 bmpObjPtr->size.cy = 0;
134 bmpObjPtr->bitmap.bmType = 0;
135 bmpObjPtr->bitmap.bmWidth = (INT16)abs(bmpi->biWidth);
136 bmpObjPtr->bitmap.bmHeight = -(INT16)bmpi->biHeight;
137 bmpObjPtr->bitmap.bmPlanes = (BYTE)bmpi->biPlanes;
138 bmpObjPtr->bitmap.bmBitsPixel = (BYTE)bmpi->biBitCount;
139 bmpObjPtr->bitmap.bmWidthBytes =
140 (INT16)BITMAP_WIDTH_BYTES( bmpObjPtr->bitmap.bmWidth, bmpi->biBitCount );
141 bmpObjPtr->bitmap.bmBits = (SEGPTR)p;
143 p->si.shmid = key;
144 p->si.shmaddr = shmat(key, NULL, 0);
145 p->si.readOnly = False;
147 if( p->si.shmaddr )
149 WORD sel = 0;
151 TSXShmAttach(display, &p->si);
152 bmpObjPtr->pixmap = TSXShmCreatePixmap(display, rootWindow,
153 p->si.shmaddr, &p->si, bmpObjPtr->bitmap.bmWidth,
154 bmpObjPtr->bitmap.bmHeight, bmpi->biBitCount );
155 if( bmpObjPtr->pixmap )
157 sel = SELECTOR_AllocBlock( p->si.shmaddr, bytes,
158 SEGMENT_DATA, FALSE, FALSE);
159 if (sel) p->bits = PTR_SEG_OFF_TO_SEGPTR(sel,0);
160 else TSXFreePixmap( display, bmpObjPtr->pixmap );
162 if( !sel )
164 shmdt( p->si.shmaddr );
165 p->si.shmaddr = NULL;
168 if( !p->si.shmaddr )
170 GDI_FreeObject( hbitmap );
171 hbitmap = 0;
174 GDI_HEAP_UNLOCK( hbitmap );
175 return hbitmap;
178 #endif
180 return 0;
183 /***********************************************************************
184 * WinGGetDIBPointer (WING.1004)
186 SEGPTR WINAPI WinGGetDIBPointer16(HBITMAP16 hWinGBitmap, BITMAPINFO* bmpi)
188 #ifdef PRELIMINARY_WING16_SUPPORT
189 BITMAPOBJ* bmp = (BITMAPOBJ *) GDI_GetObjPtr( hWinGBitmap, BITMAP_MAGIC );
191 if( bmp )
193 __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
194 if( p )
196 if( bmpi ) memcpy( bmpi, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
197 GDI_HEAP_UNLOCK( hWinGBitmap );
198 return p->bits;
201 #endif
202 return (SEGPTR)NULL;
205 /***********************************************************************
206 * WinGSetDIBColorTable (WING.1004)
208 UINT16 WINAPI WinGSetDIBColorTable16(HDC16 hWinGDC, UINT16 start, UINT16 num,
209 RGBQUAD* pColor)
211 FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",hWinGDC,start,num,pColor);
212 return num;
215 /***********************************************************************
216 * WinGGetDIBColorTable16 (WING.1005)
218 UINT16 WINAPI WinGGetDIBColorTable16(HDC16 winDC, UINT16 start,
219 UINT16 num, RGBQUAD* colors)
221 FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",winDC,start,num,colors);
222 return 0;
225 /***********************************************************************
226 * WinGCreateHalfTonePalette16 (WING.1007)
228 HPALETTE16 WINAPI WinGCreateHalfTonePalette16(void)
230 FIXME(wing,"(void): empty stub!\n");
231 return 0;
234 /***********************************************************************
235 * WinGCreateHalfToneBrush16 (WING.1008)
237 HPALETTE16 WINAPI WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col,
238 WING_DITHER_TYPE type)
240 FIXME(wing,"(...): empty stub!\n");
241 return 0;
244 /***********************************************************************
245 * WinGStretchBlt16 (WING.1009)
247 BOOL16 WINAPI WinGStretchBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
248 INT16 widDest, INT16 heiDest,
249 HDC16 srcDC, INT16 xSrc, INT16 ySrc,
250 INT16 widSrc, INT16 heiSrc)
253 return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
256 /***********************************************************************
257 * WinGBitBlt16 (WING.1010)
259 BOOL16 WINAPI WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
260 INT16 widDest, INT16 heiDest, HDC16 srcDC,
261 INT16 xSrc, INT16 ySrc)
263 /* destDC is a display DC, srcDC is a memory DC */
265 DC *dcDst, *dcSrc;
266 X11DRV_PDEVICE *physDevDst, *physDevSrc;
268 if (!(dcDst = (DC *)GDI_GetObjPtr( destDC, DC_MAGIC ))) return FALSE;
269 if (!(dcSrc = (DC *) GDI_GetObjPtr( srcDC, DC_MAGIC ))) return FALSE;
270 physDevDst = (X11DRV_PDEVICE *)dcDst->physDev;
271 physDevSrc = (X11DRV_PDEVICE *)dcSrc->physDev;
273 if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );
275 xSrc = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
276 ySrc = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
277 xDest = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
278 yDest = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
279 widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
280 heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;
282 TSXSetFunction( display, physDevDst->gc, GXcopy );
283 TSXCopyArea( display, physDevSrc->drawable,
284 physDevDst->drawable, physDevDst->gc,
285 xSrc, ySrc, widDest, heiDest, xDest, yDest );
286 return TRUE;