Release 961222
[wine/multimedia.git] / graphics / wing.c
blob0ed174fc3a77878dc6d6f346c3de558730288085
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 #include <sys/shm.h>
13 #include "windows.h"
14 #include "bitmap.h"
15 #include "dc.h"
16 #include "gdi.h"
17 #include "xmalloc.h"
18 #include "stddebug.h"
19 #include "debug.h"
21 typedef enum WING_DITHER_TYPE
23 WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4
24 } WING_DITHER_TYPE;
26 static int __WinGOK = -1;
28 /*
29 * WinG DIB bitmaps can be selected into DC and then scribbled upon
30 * by GDI functions. They can also be changed directly. This gives us
31 * three choices
32 * - use original WinG 16-bit DLL
33 * requires working 16-bit driver interface
34 * - implement DIB graphics driver from scratch
35 * see wing.zip size
36 * - use shared pixmaps
37 * won't work with some videocards and/or videomodes
38 * 961208 - AK
41 static BITMAPINFOHEADER __bmpiWinG = { 0, 1, -1, 1, 8, BI_RGB, 1, 0, 0, 0, 0 };
43 static void __initWinG()
45 if( __WinGOK < 0 )
47 Status s = XShmQueryExtension(display);
48 if( s )
50 int i = XShmPixmapFormat(display);
51 if( i == ZPixmap && screenDepth == 8 )
53 __WinGOK = True;
54 return;
57 fprintf(stdnimp,"WinG: no joy.\n");
58 __WinGOK = False;
62 /***********************************************************************
63 * WinGCreateDC16 (WING.1001)
65 HDC16 WinGCreateDC16(void)
67 __initWinG();
69 if( __WinGOK > 0 )
70 return CreateCompatibleDC16(NULL);
71 return (HDC16)NULL;
74 /***********************************************************************
75 * WinGRecommendDIBFormat16 (WING.1002)
77 BOOL16 WinGRecommendDIBFormat16(BITMAPINFO *fmt)
79 fprintf(stdnimp,"WinGRecommendDIBFormat()\n");
81 if( __WinGOK > 0 && fmt )
83 memcpy(&fmt->bmiHeader, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
84 return TRUE;
86 return FALSE;
89 /***********************************************************************
90 * WinGCreateBitmap16 (WING.1003)
92 HBITMAP16 WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header, void **bits)
94 fprintf(stdnimp,"WinGCreateBitmap: empty stub! (expect failure)\n");
95 if( __WinGOK > 0 && header )
97 BITMAPINFOHEADER* bmpi = &header->bmiHeader;
99 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",
100 (int)bmpi->biSize, bmpi->biPlanes, bmpi->biBitCount,
101 (int)bmpi->biWidth, (int)bmpi->biHeight, (unsigned)bmpi->biCompression, (int)bmpi->biSizeImage);
103 #ifdef PRELIMINARY_WING16_SUPPORT
104 if( bmpi->biPlanes == __bmpiWinG.biPlanes && bmpi->biBitCount == __bmpiWinG.biBitCount &&
105 bmpi->biCompression == __bmpiWinG.biCompression && (int)bmpi->biHeight < 0 &&
106 bmpi->biWidth )
108 unsigned bytes = (bmpi->biWidth + bmpi->biWidth % 2)*(-bmpi->biHeight) * bmpi->biBitCount/8;
109 int key = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0x01FF);
111 if( key )
113 /* Create the BITMAPOBJ
115 * FIXME: A facility to manage shared memory structures
116 * which would clean up when Wine crashes. Perhaps a part of
117 * IPC code can be adapted. Otherwise this code leaves a lot
118 * of junk in shared memory.
121 HBITMAP16 hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
122 if (hbitmap)
124 __ShmBitmapCtl* p = (__ShmBitmapCtl*)xmalloc(sizeof(__ShmBitmapCtl));
125 BITMAPOBJ* bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LIN_ADDR( hbitmap );
127 bmpObjPtr->size.cx = 0;
128 bmpObjPtr->size.cy = 0;
129 bmpObjPtr->bitmap.bmType = 0;
130 bmpObjPtr->bitmap.bmWidth = (INT16)abs(bmpi->biWidth);
131 bmpObjPtr->bitmap.bmHeight = -(INT16)bmpi->biHeight;
132 bmpObjPtr->bitmap.bmPlanes = (BYTE)bmpi->biPlanes;
133 bmpObjPtr->bitmap.bmBitsPixel = (BYTE)bmpi->biBitCount;
134 bmpObjPtr->bitmap.bmWidthBytes =
135 (INT16)BITMAP_WIDTH_BYTES( bmpObjPtr->bitmap.bmWidth, bmpi->biBitCount );
136 bmpObjPtr->bitmap.bmBits = (SEGPTR)p;
138 p->si.shmid = key;
139 p->si.shmaddr = shmat(key, NULL, 0);
140 p->si.readOnly = False;
142 if( p->si.shmaddr )
144 WORD sel = 0;
146 XShmAttach(display, &p->si);
147 bmpObjPtr->pixmap = XShmCreatePixmap(display, rootWindow,
148 p->si.shmaddr, &p->si, bmpObjPtr->bitmap.bmWidth,
149 bmpObjPtr->bitmap.bmHeight, bmpi->biBitCount );
150 if( bmpObjPtr->pixmap )
152 WORD s;
153 if( (sel = AllocSelectorArray( (bytes + 0xFFFF) >> 16 )) )
155 DWORD base = (DWORD)p->si.shmaddr, l;
157 SetSelectorBase( sel, base );
158 SetSelectorLimit( sel, bytes );
159 s = sel;
160 for( l = 0x10000; l < bytes ; )
162 s += __AHINCR;
163 SetSelectorBase( s, base + l );
164 l += 0x10000;
165 SetSelectorLimit( s, (l < bytes)?0xFFFF:bytes%0x10000);
167 p->bits = MAKELONG(0, sel);
169 else XFreePixmap( display, bmpObjPtr->pixmap );
171 if( !sel )
173 shmdt( p->si.shmaddr );
174 p->si.shmaddr = NULL;
177 if( !p->si.shmaddr )
179 GDI_FreeObject( hbitmap );
180 hbitmap = 0;
183 return hbitmap;
186 #endif
188 return 0;
191 /***********************************************************************
192 * WinGGetDIBPointer (WING.1004)
194 SEGPTR WinGGetDIBPointer16(HBITMAP16 hWinGBitmap, BITMAPINFO* bmpi)
196 #ifdef PRELIMINARY_WING16_SUPPORT
197 BITMAPOBJ* bmp = (BITMAPOBJ *) GDI_GetObjPtr( hWinGBitmap, BITMAP_MAGIC );
199 if( bmp )
201 __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
202 if( p )
204 if( bmpi ) memcpy( bmpi, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
205 return p->bits;
208 #endif
209 return (SEGPTR)NULL;
212 /***********************************************************************
213 * WinGSetDIBColorTable (WING.1004)
215 UINT16 WinGSetDIBColorTable16(HDC16 hWinGDC, UINT16 start, UINT16 num, RGBQUAD* pColor)
217 fprintf(stdnimp,"WinGSetDIBColorTable: empty stub!\n");
218 return num;
221 /***********************************************************************
222 * WinGGetDIBColorTable16 (WING.1005)
224 UINT16 WinGGetDIBColorTable16(HDC16 winDC, UINT16 start, UINT16 numentry,
225 RGBQUAD* colors)
227 fprintf(stdnimp,"WinGGetDIBColorTable: empty stub!\n");
228 return 0;
231 /***********************************************************************
232 * WinGCreateHalfTonePalette16 (WING.1007)
234 HPALETTE16 WinGCreateHalfTonePalette16(void)
236 fprintf(stdnimp,"WinGCreateHalfTonePalette: empty stub!\n");
237 return 0;
240 /***********************************************************************
241 * WinGCreateHalfToneBrush16 (WING.1008)
243 HPALETTE16 WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col, WING_DITHER_TYPE type)
245 fprintf(stdnimp,"WinGCreateHalfToneBrush: empty stub!\n");
246 return 0;
249 /***********************************************************************
250 * WinGStretchBlt16 (WING.1009)
252 BOOL16 WinGStretchBlt16(HDC16 destDC, INT16 xDest, INT16 yDest, INT16 widDest,
253 INT16 heiDest, HDC16 srcDC, INT16 xSrc, INT16 ySrc,
254 INT16 widSrc, INT16 heiSrc)
257 return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
258 /* fprintf(stdnimp,"WinGStretchBlt16: empty stub!\n");*/
259 /* return 0; */
262 /***********************************************************************
263 * WinGBitBlt16 (WING.1010)
265 BOOL16 WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest, INT16 widDest,
266 INT16 heiDest, HDC16 srcDC, INT16 xSrc, INT16 ySrc)
268 /* destDC is a display DC, srcDC is a memory DC */
270 DC *dcDst, *dcSrc;
272 if (!(dcDst = (DC *)GDI_GetObjPtr( destDC, DC_MAGIC ))) return FALSE;
273 if (!(dcSrc = (DC *) GDI_GetObjPtr( srcDC, DC_MAGIC ))) return FALSE;
275 if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );
277 xSrc = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
278 ySrc = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
279 xDest = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
280 yDest = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
281 widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
282 heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;
284 XSetFunction( display, dcDst->u.x.gc, GXcopy );
285 XCopyArea( display, dcSrc->u.x.drawable,
286 dcDst->u.x.drawable, dcDst->u.x.gc,
287 xSrc, ySrc, widDest, heiDest, xDest, yDest );
288 return TRUE;