Release 970824
[wine/multimedia.git] / graphics / wing.c
blob58be55439bc81795209a832f3bd1afc5ec9d6a25
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 WINAPI WinGCreateDC16(void)
71 __initWinG();
73 if( __WinGOK > 0 )
74 return CreateCompatibleDC16(NULL);
75 return (HDC16)NULL;
78 /***********************************************************************
79 * WinGRecommendDIBFormat16 (WING.1002)
81 BOOL16 WINAPI 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 WINAPI WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header,
97 void **bits)
99 fprintf(stdnimp,"WinGCreateBitmap: empty stub! (expect failure)\n");
100 if( __WinGOK > 0 && header )
102 BITMAPINFOHEADER* bmpi = &header->bmiHeader;
104 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",
105 (int)bmpi->biSize, bmpi->biPlanes, bmpi->biBitCount,
106 (int)bmpi->biWidth, (int)bmpi->biHeight, (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 XShmAttach(display, &p->si);
152 bmpObjPtr->pixmap = XShmCreatePixmap(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 XFreePixmap( 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 fprintf(stdnimp,"WinGSetDIBColorTable: empty stub!\n");
212 return num;
215 /***********************************************************************
216 * WinGGetDIBColorTable16 (WING.1005)
218 UINT16 WINAPI WinGGetDIBColorTable16(HDC16 winDC, UINT16 start,
219 UINT16 numentry, RGBQUAD* colors)
221 fprintf(stdnimp,"WinGGetDIBColorTable: empty stub!\n");
222 return 0;
225 /***********************************************************************
226 * WinGCreateHalfTonePalette16 (WING.1007)
228 HPALETTE16 WINAPI WinGCreateHalfTonePalette16(void)
230 fprintf(stdnimp,"WinGCreateHalfTonePalette: 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 fprintf(stdnimp,"WinGCreateHalfToneBrush: 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);
254 /* fprintf(stdnimp,"WinGStretchBlt16: empty stub!\n");*/
255 /* return 0; */
258 /***********************************************************************
259 * WinGBitBlt16 (WING.1010)
261 BOOL16 WINAPI WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
262 INT16 widDest, INT16 heiDest, HDC16 srcDC,
263 INT16 xSrc, INT16 ySrc)
265 /* destDC is a display DC, srcDC is a memory DC */
267 DC *dcDst, *dcSrc;
269 if (!(dcDst = (DC *)GDI_GetObjPtr( destDC, DC_MAGIC ))) return FALSE;
270 if (!(dcSrc = (DC *) GDI_GetObjPtr( srcDC, DC_MAGIC ))) return FALSE;
272 if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );
274 xSrc = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
275 ySrc = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
276 xDest = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
277 yDest = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
278 widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
279 heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;
281 XSetFunction( display, dcDst->u.x.gc, GXcopy );
282 XCopyArea( display, dcSrc->u.x.drawable,
283 dcDst->u.x.drawable, dcDst->u.x.gc,
284 xSrc, ySrc, widDest, heiDest, xDest, yDest );
285 return TRUE;