Release 980329
[wine/multimedia.git] / graphics / wing.c
blobda9c315d203d67b93724f63baec51a6cb9c078f3
1 /*
2 * WingG 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 extern void CLIPPING_UpdateGCRegion(DC* );
24 typedef enum WING_DITHER_TYPE
26 WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4
27 } WING_DITHER_TYPE;
29 static int __WinGOK = -1;
31 /*
32 * WinG DIB bitmaps can be selected into DC and then scribbled upon
33 * by GDI functions. They can also be changed directly. This gives us
34 * three choices
35 * - use original WinG 16-bit DLL
36 * requires working 16-bit driver interface
37 * - implement DIB graphics driver from scratch
38 * see wing.zip size
39 * - use shared pixmaps
40 * won't work with some videocards and/or videomodes
41 * 961208 - AK
44 static BITMAPINFOHEADER __bmpiWinG = { 0, 1, -1, 1, 8, BI_RGB, 1, 0, 0, 0, 0 };
46 static void __initWinG(void)
48 if( __WinGOK < 0 )
50 Status s = TSXShmQueryExtension(display);
51 if( s )
53 int i = TSXShmPixmapFormat(display);
54 if( i == ZPixmap && screenDepth == 8 )
56 __WinGOK = True;
57 return;
60 FIXME(wing,"WinG: no joy.\n");
61 __WinGOK = False;
65 /***********************************************************************
66 * WinGCreateDC16 (WING.1001)
68 HDC16 WINAPI WinGCreateDC16(void)
70 __initWinG();
72 if( __WinGOK > 0 )
73 return CreateCompatibleDC16(NULL);
74 return (HDC16)NULL;
77 /***********************************************************************
78 * WinGRecommendDIBFormat16 (WING.1002)
80 BOOL16 WINAPI WinGRecommendDIBFormat16(BITMAPINFO *fmt)
82 FIXME(wing,"(%p): stub\n", fmt);
84 if( __WinGOK > 0 && fmt )
86 memcpy(&fmt->bmiHeader, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
87 return TRUE;
89 return FALSE;
92 /***********************************************************************
93 * WinGCreateBitmap16 (WING.1003)
95 HBITMAP16 WINAPI WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header,
96 void **bits)
98 FIXME(wing,"(%x,%p,%p): empty stub! (expect failure)\n",
99 winDC, header, bits);
100 if( __WinGOK > 0 && header )
102 BITMAPINFOHEADER* bmpi = &header->bmiHeader;
104 FIXME(wing,"bytes=%i,planes=%i,bpp=%i,x=%i,y=%i,rle=0x%08x,size=%i\n",
105 (int)bmpi->biSize, bmpi->biPlanes, bmpi->biBitCount,
106 (int)bmpi->biWidth, (int)bmpi->biHeight,
107 (unsigned)bmpi->biCompression, (int)bmpi->biSizeImage);
109 #ifdef PRELIMINARY_WING16_SUPPORT
110 if( bmpi->biPlanes == __bmpiWinG.biPlanes && bmpi->biBitCount == __bmpiWinG.biBitCount &&
111 bmpi->biCompression == __bmpiWinG.biCompression && (int)bmpi->biHeight < 0 &&
112 bmpi->biWidth )
114 unsigned bytes = (bmpi->biWidth + bmpi->biWidth % 2)*(-bmpi->biHeight) * bmpi->biBitCount/8;
115 int key = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0x01FF);
117 if( key )
119 /* Create the BITMAPOBJ
121 * FIXME: A facility to manage shared memory structures
122 * which would clean up when Wine crashes. Perhaps a part of
123 * IPC code can be adapted. Otherwise this code leaves a lot
124 * of junk in shared memory.
127 HBITMAP16 hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
128 if (hbitmap)
130 __ShmBitmapCtl* p = (__ShmBitmapCtl*)xmalloc(sizeof(__ShmBitmapCtl));
131 BITMAPOBJ* bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap );
133 bmpObjPtr->size.cx = 0;
134 bmpObjPtr->size.cy = 0;
135 bmpObjPtr->bitmap.bmType = 0;
136 bmpObjPtr->bitmap.bmWidth = (INT16)abs(bmpi->biWidth);
137 bmpObjPtr->bitmap.bmHeight = -(INT16)bmpi->biHeight;
138 bmpObjPtr->bitmap.bmPlanes = (BYTE)bmpi->biPlanes;
139 bmpObjPtr->bitmap.bmBitsPixel = (BYTE)bmpi->biBitCount;
140 bmpObjPtr->bitmap.bmWidthBytes =
141 (INT16)BITMAP_WIDTH_BYTES( bmpObjPtr->bitmap.bmWidth, bmpi->biBitCount );
142 bmpObjPtr->bitmap.bmBits = (SEGPTR)p;
144 p->si.shmid = key;
145 p->si.shmaddr = shmat(key, NULL, 0);
146 p->si.readOnly = False;
148 if( p->si.shmaddr )
150 WORD sel = 0;
152 XShmAttach(display, &p->si);
153 bmpObjPtr->pixmap = XShmCreatePixmap(display, rootWindow,
154 p->si.shmaddr, &p->si, bmpObjPtr->bitmap.bmWidth,
155 bmpObjPtr->bitmap.bmHeight, bmpi->biBitCount );
156 if( bmpObjPtr->pixmap )
158 sel = SELECTOR_AllocBlock( p->si.shmaddr, bytes,
159 SEGMENT_DATA, FALSE, FALSE);
160 if (sel) p->bits = PTR_SEG_OFF_TO_SEGPTR(sel,0);
161 else TSXFreePixmap( display, bmpObjPtr->pixmap );
163 if( !sel )
165 shmdt( p->si.shmaddr );
166 p->si.shmaddr = NULL;
169 if( !p->si.shmaddr )
171 GDI_FreeObject( hbitmap );
172 hbitmap = 0;
175 GDI_HEAP_UNLOCK( hbitmap );
176 return hbitmap;
179 #endif
181 return 0;
184 /***********************************************************************
185 * WinGGetDIBPointer (WING.1004)
187 SEGPTR WINAPI WinGGetDIBPointer16(HBITMAP16 hWinGBitmap, BITMAPINFO* bmpi)
189 #ifdef PRELIMINARY_WING16_SUPPORT
190 BITMAPOBJ* bmp = (BITMAPOBJ *) GDI_GetObjPtr( hWinGBitmap, BITMAP_MAGIC );
192 if( bmp )
194 __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
195 if( p )
197 if( bmpi ) memcpy( bmpi, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
198 GDI_HEAP_UNLOCK( hWinGBitmap );
199 return p->bits;
202 #endif
203 return (SEGPTR)NULL;
206 /***********************************************************************
207 * WinGSetDIBColorTable (WING.1004)
209 UINT16 WINAPI WinGSetDIBColorTable16(HDC16 hWinGDC, UINT16 start, UINT16 num,
210 RGBQUAD* pColor)
212 FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",hWinGDC,start,num,pColor);
213 return num;
216 /***********************************************************************
217 * WinGGetDIBColorTable16 (WING.1005)
219 UINT16 WINAPI WinGGetDIBColorTable16(HDC16 winDC, UINT16 start,
220 UINT16 num, RGBQUAD* colors)
222 FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",winDC,start,num,colors);
223 return 0;
226 /***********************************************************************
227 * WinGCreateHalfTonePalette16 (WING.1007)
229 HPALETTE16 WINAPI WinGCreateHalfTonePalette16(void)
231 FIXME(wing,"(void): empty stub!\n");
232 return 0;
235 /***********************************************************************
236 * WinGCreateHalfToneBrush16 (WING.1008)
238 HPALETTE16 WINAPI WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col,
239 WING_DITHER_TYPE type)
241 FIXME(wing,"(...): empty stub!\n");
242 return 0;
245 /***********************************************************************
246 * WinGStretchBlt16 (WING.1009)
248 BOOL16 WINAPI WinGStretchBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
249 INT16 widDest, INT16 heiDest,
250 HDC16 srcDC, INT16 xSrc, INT16 ySrc,
251 INT16 widSrc, INT16 heiSrc)
254 return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
257 /***********************************************************************
258 * WinGBitBlt16 (WING.1010)
260 BOOL16 WINAPI WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
261 INT16 widDest, INT16 heiDest, HDC16 srcDC,
262 INT16 xSrc, INT16 ySrc)
264 /* destDC is a display DC, srcDC is a memory DC */
266 DC *dcDst, *dcSrc;
268 if (!(dcDst = (DC *)GDI_GetObjPtr( destDC, DC_MAGIC ))) return FALSE;
269 if (!(dcSrc = (DC *) GDI_GetObjPtr( srcDC, DC_MAGIC ))) return FALSE;
271 if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );
273 xSrc = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
274 ySrc = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
275 xDest = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
276 yDest = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
277 widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
278 heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;
280 TSXSetFunction( display, dcDst->u.x.gc, GXcopy );
281 TSXCopyArea( display, dcSrc->u.x.drawable,
282 dcDst->u.x.drawable, dcDst->u.x.gc,
283 xSrc, ySrc, widDest, heiDest, xDest, yDest );
284 return TRUE;