Release 970120
[wine/multimedia.git] / graphics / wing.c
blobaed0e39b2c796b7d508c589ca7644d0a34d71807
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 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()
47 if( __WinGOK < 0 )
49 Status s = XShmQueryExtension(display);
50 if( s )
52 int i = XShmPixmapFormat(display);
53 if( i == ZPixmap && screenDepth == 8 )
55 __WinGOK = True;
56 return;
59 fprintf(stdnimp,"WinG: no joy.\n");
60 __WinGOK = False;
64 /***********************************************************************
65 * WinGCreateDC16 (WING.1001)
67 HDC16 WinGCreateDC16(void)
69 __initWinG();
71 if( __WinGOK > 0 )
72 return CreateCompatibleDC16(NULL);
73 return (HDC16)NULL;
76 /***********************************************************************
77 * WinGRecommendDIBFormat16 (WING.1002)
79 BOOL16 WinGRecommendDIBFormat16(BITMAPINFO *fmt)
81 fprintf(stdnimp,"WinGRecommendDIBFormat()\n");
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 WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header, void **bits)
96 fprintf(stdnimp,"WinGCreateBitmap: empty stub! (expect failure)\n");
97 if( __WinGOK > 0 && header )
99 BITMAPINFOHEADER* bmpi = &header->bmiHeader;
101 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",
102 (int)bmpi->biSize, bmpi->biPlanes, bmpi->biBitCount,
103 (int)bmpi->biWidth, (int)bmpi->biHeight, (unsigned)bmpi->biCompression, (int)bmpi->biSizeImage);
105 #ifdef PRELIMINARY_WING16_SUPPORT
106 if( bmpi->biPlanes == __bmpiWinG.biPlanes && bmpi->biBitCount == __bmpiWinG.biBitCount &&
107 bmpi->biCompression == __bmpiWinG.biCompression && (int)bmpi->biHeight < 0 &&
108 bmpi->biWidth )
110 unsigned bytes = (bmpi->biWidth + bmpi->biWidth % 2)*(-bmpi->biHeight) * bmpi->biBitCount/8;
111 int key = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0x01FF);
113 if( key )
115 /* Create the BITMAPOBJ
117 * FIXME: A facility to manage shared memory structures
118 * which would clean up when Wine crashes. Perhaps a part of
119 * IPC code can be adapted. Otherwise this code leaves a lot
120 * of junk in shared memory.
123 HBITMAP16 hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
124 if (hbitmap)
126 __ShmBitmapCtl* p = (__ShmBitmapCtl*)xmalloc(sizeof(__ShmBitmapCtl));
127 BITMAPOBJ* bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LIN_ADDR( hbitmap );
129 bmpObjPtr->size.cx = 0;
130 bmpObjPtr->size.cy = 0;
131 bmpObjPtr->bitmap.bmType = 0;
132 bmpObjPtr->bitmap.bmWidth = (INT16)abs(bmpi->biWidth);
133 bmpObjPtr->bitmap.bmHeight = -(INT16)bmpi->biHeight;
134 bmpObjPtr->bitmap.bmPlanes = (BYTE)bmpi->biPlanes;
135 bmpObjPtr->bitmap.bmBitsPixel = (BYTE)bmpi->biBitCount;
136 bmpObjPtr->bitmap.bmWidthBytes =
137 (INT16)BITMAP_WIDTH_BYTES( bmpObjPtr->bitmap.bmWidth, bmpi->biBitCount );
138 bmpObjPtr->bitmap.bmBits = (SEGPTR)p;
140 p->si.shmid = key;
141 p->si.shmaddr = shmat(key, NULL, 0);
142 p->si.readOnly = False;
144 if( p->si.shmaddr )
146 WORD sel = 0;
148 XShmAttach(display, &p->si);
149 bmpObjPtr->pixmap = XShmCreatePixmap(display, rootWindow,
150 p->si.shmaddr, &p->si, bmpObjPtr->bitmap.bmWidth,
151 bmpObjPtr->bitmap.bmHeight, bmpi->biBitCount );
152 if( bmpObjPtr->pixmap )
154 sel = SELECTOR_AllocBlock( p->si.shmaddr, bytes,
155 SEGMENT_DATA, FALSE, FALSE);
156 if (sel) p->bits = PTR_SEG_OFF_TO_SEGPTR(sel,0);
157 else XFreePixmap( display, bmpObjPtr->pixmap );
159 if( !sel )
161 shmdt( p->si.shmaddr );
162 p->si.shmaddr = NULL;
165 if( !p->si.shmaddr )
167 GDI_FreeObject( hbitmap );
168 hbitmap = 0;
171 return hbitmap;
174 #endif
176 return 0;
179 /***********************************************************************
180 * WinGGetDIBPointer (WING.1004)
182 SEGPTR WinGGetDIBPointer16(HBITMAP16 hWinGBitmap, BITMAPINFO* bmpi)
184 #ifdef PRELIMINARY_WING16_SUPPORT
185 BITMAPOBJ* bmp = (BITMAPOBJ *) GDI_GetObjPtr( hWinGBitmap, BITMAP_MAGIC );
187 if( bmp )
189 __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
190 if( p )
192 if( bmpi ) memcpy( bmpi, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
193 return p->bits;
196 #endif
197 return (SEGPTR)NULL;
200 /***********************************************************************
201 * WinGSetDIBColorTable (WING.1004)
203 UINT16 WinGSetDIBColorTable16(HDC16 hWinGDC, UINT16 start, UINT16 num, RGBQUAD* pColor)
205 fprintf(stdnimp,"WinGSetDIBColorTable: empty stub!\n");
206 return num;
209 /***********************************************************************
210 * WinGGetDIBColorTable16 (WING.1005)
212 UINT16 WinGGetDIBColorTable16(HDC16 winDC, UINT16 start, UINT16 numentry,
213 RGBQUAD* colors)
215 fprintf(stdnimp,"WinGGetDIBColorTable: empty stub!\n");
216 return 0;
219 /***********************************************************************
220 * WinGCreateHalfTonePalette16 (WING.1007)
222 HPALETTE16 WinGCreateHalfTonePalette16(void)
224 fprintf(stdnimp,"WinGCreateHalfTonePalette: empty stub!\n");
225 return 0;
228 /***********************************************************************
229 * WinGCreateHalfToneBrush16 (WING.1008)
231 HPALETTE16 WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col, WING_DITHER_TYPE type)
233 fprintf(stdnimp,"WinGCreateHalfToneBrush: empty stub!\n");
234 return 0;
237 /***********************************************************************
238 * WinGStretchBlt16 (WING.1009)
240 BOOL16 WinGStretchBlt16(HDC16 destDC, INT16 xDest, INT16 yDest, INT16 widDest,
241 INT16 heiDest, HDC16 srcDC, INT16 xSrc, INT16 ySrc,
242 INT16 widSrc, INT16 heiSrc)
245 return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
246 /* fprintf(stdnimp,"WinGStretchBlt16: empty stub!\n");*/
247 /* return 0; */
250 /***********************************************************************
251 * WinGBitBlt16 (WING.1010)
253 BOOL16 WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest, INT16 widDest,
254 INT16 heiDest, HDC16 srcDC, INT16 xSrc, INT16 ySrc)
256 /* destDC is a display DC, srcDC is a memory DC */
258 DC *dcDst, *dcSrc;
260 if (!(dcDst = (DC *)GDI_GetObjPtr( destDC, DC_MAGIC ))) return FALSE;
261 if (!(dcSrc = (DC *) GDI_GetObjPtr( srcDC, DC_MAGIC ))) return FALSE;
263 if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );
265 xSrc = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
266 ySrc = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
267 xDest = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
268 yDest = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
269 widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
270 heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;
272 XSetFunction( display, dcDst->u.x.gc, GXcopy );
273 XCopyArea( display, dcSrc->u.x.drawable,
274 dcDst->u.x.drawable, dcDst->u.x.gc,
275 xSrc, ySrc, widDest, heiDest, xDest, yDest );
276 return TRUE;