Release 970525
[wine/multimedia.git] / graphics / wing.c
blob90321e523e0de3c4c804cf0738d3d1d00d1ed7e4
1 /*
2 * WingG support
4 * Started by Robert Pouliot <krynos@clic.net>
5 */
7 #include <X11/Xlib.h>
8 #include <X11/extensions/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 "stddebug.h"
21 #include "debug.h"
23 extern void CLIPPING_UpdateGCRegion(DC* );
25 typedef enum WING_DITHER_TYPE
27 WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4
28 } WING_DITHER_TYPE;
30 static int __WinGOK = -1;
32 /*
33 * WinG DIB bitmaps can be selected into DC and then scribbled upon
34 * by GDI functions. They can also be changed directly. This gives us
35 * three choices
36 * - use original WinG 16-bit DLL
37 * requires working 16-bit driver interface
38 * - implement DIB graphics driver from scratch
39 * see wing.zip size
40 * - use shared pixmaps
41 * won't work with some videocards and/or videomodes
42 * 961208 - AK
45 static BITMAPINFOHEADER __bmpiWinG = { 0, 1, -1, 1, 8, BI_RGB, 1, 0, 0, 0, 0 };
47 static void __initWinG()
49 if( __WinGOK < 0 )
51 Status s = XShmQueryExtension(display);
52 if( s )
54 int i = XShmPixmapFormat(display);
55 if( i == ZPixmap && screenDepth == 8 )
57 __WinGOK = True;
58 return;
61 fprintf(stdnimp,"WinG: no joy.\n");
62 __WinGOK = False;
66 /***********************************************************************
67 * WinGCreateDC16 (WING.1001)
69 HDC16 WinGCreateDC16(void)
71 __initWinG();
73 if( __WinGOK > 0 )
74 return CreateCompatibleDC16(NULL);
75 return (HDC16)NULL;
78 /***********************************************************************
79 * WinGRecommendDIBFormat16 (WING.1002)
81 BOOL16 WinGRecommendDIBFormat16(BITMAPINFO *fmt)
83 fprintf(stdnimp,"WinGRecommendDIBFormat()\n");
85 if( __WinGOK > 0 && fmt )
87 memcpy(&fmt->bmiHeader, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
88 return TRUE;
90 return FALSE;
93 /***********************************************************************
94 * WinGCreateBitmap16 (WING.1003)
96 HBITMAP16 WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header, void **bits)
98 fprintf(stdnimp,"WinGCreateBitmap: empty stub! (expect failure)\n");
99 if( __WinGOK > 0 && header )
101 BITMAPINFOHEADER* bmpi = &header->bmiHeader;
103 fprintf(stdnimp,"bytes\t=%i\nplanes\t=%i\nbpp\t=%i\nx\t=%i\ny\t=%i\nrle\t=0x%08x\nsize\t=%i\n",
104 (int)bmpi->biSize, bmpi->biPlanes, bmpi->biBitCount,
105 (int)bmpi->biWidth, (int)bmpi->biHeight, (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_LIN_ADDR( 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 XShmAttach(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 XFreePixmap( 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 return hbitmap;
176 #endif
178 return 0;
181 /***********************************************************************
182 * WinGGetDIBPointer (WING.1004)
184 SEGPTR WinGGetDIBPointer16(HBITMAP16 hWinGBitmap, BITMAPINFO* bmpi)
186 #ifdef PRELIMINARY_WING16_SUPPORT
187 BITMAPOBJ* bmp = (BITMAPOBJ *) GDI_GetObjPtr( hWinGBitmap, BITMAP_MAGIC );
189 if( bmp )
191 __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
192 if( p )
194 if( bmpi ) memcpy( bmpi, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
195 return p->bits;
198 #endif
199 return (SEGPTR)NULL;
202 /***********************************************************************
203 * WinGSetDIBColorTable (WING.1004)
205 UINT16 WinGSetDIBColorTable16(HDC16 hWinGDC, UINT16 start, UINT16 num, RGBQUAD* pColor)
207 fprintf(stdnimp,"WinGSetDIBColorTable: empty stub!\n");
208 return num;
211 /***********************************************************************
212 * WinGGetDIBColorTable16 (WING.1005)
214 UINT16 WinGGetDIBColorTable16(HDC16 winDC, UINT16 start, UINT16 numentry,
215 RGBQUAD* colors)
217 fprintf(stdnimp,"WinGGetDIBColorTable: empty stub!\n");
218 return 0;
221 /***********************************************************************
222 * WinGCreateHalfTonePalette16 (WING.1007)
224 HPALETTE16 WinGCreateHalfTonePalette16(void)
226 fprintf(stdnimp,"WinGCreateHalfTonePalette: empty stub!\n");
227 return 0;
230 /***********************************************************************
231 * WinGCreateHalfToneBrush16 (WING.1008)
233 HPALETTE16 WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col, WING_DITHER_TYPE type)
235 fprintf(stdnimp,"WinGCreateHalfToneBrush: empty stub!\n");
236 return 0;
239 /***********************************************************************
240 * WinGStretchBlt16 (WING.1009)
242 BOOL16 WinGStretchBlt16(HDC16 destDC, INT16 xDest, INT16 yDest, INT16 widDest,
243 INT16 heiDest, HDC16 srcDC, INT16 xSrc, INT16 ySrc,
244 INT16 widSrc, INT16 heiSrc)
247 return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
248 /* fprintf(stdnimp,"WinGStretchBlt16: empty stub!\n");*/
249 /* return 0; */
252 /***********************************************************************
253 * WinGBitBlt16 (WING.1010)
255 BOOL16 WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest, INT16 widDest,
256 INT16 heiDest, HDC16 srcDC, INT16 xSrc, INT16 ySrc)
258 /* destDC is a display DC, srcDC is a memory DC */
260 DC *dcDst, *dcSrc;
262 if (!(dcDst = (DC *)GDI_GetObjPtr( destDC, DC_MAGIC ))) return FALSE;
263 if (!(dcSrc = (DC *) GDI_GetObjPtr( srcDC, DC_MAGIC ))) return FALSE;
265 if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );
267 xSrc = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
268 ySrc = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
269 xDest = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
270 yDest = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
271 widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
272 heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;
274 XSetFunction( display, dcDst->u.x.gc, GXcopy );
275 XCopyArea( display, dcSrc->u.x.drawable,
276 dcDst->u.x.drawable, dcDst->u.x.gc,
277 xSrc, ySrc, widDest, heiDest, xDest, yDest );
278 return TRUE;