blob: 52c9288cd470c3f45298ea37e094ccdd9644289b [file] [log] [blame]
Alexandre Julliardda0cfb31996-12-01 17:17:47 +00001/*
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002 * WinG support
Alexandre Julliardda0cfb31996-12-01 17:17:47 +00003 *
4 * Started by Robert Pouliot <krynos@clic.net>
5 */
6
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00007#include "ts_xlib.h"
8#include "ts_xshm.h"
Alexandre Julliardb1bac321996-12-15 19:45:59 +00009#include <sys/types.h>
10#include <sys/ipc.h>
Alexandre Julliard01d63461997-01-20 19:43:45 +000011#ifndef __EMX__
Alexandre Julliardb1bac321996-12-15 19:45:59 +000012#include <sys/shm.h>
Alexandre Julliard01d63461997-01-20 19:43:45 +000013#endif
Alexandre Julliardb1bac321996-12-15 19:45:59 +000014
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +000015#include "windows.h"
Alexandre Julliardb1bac321996-12-15 19:45:59 +000016#include "bitmap.h"
17#include "dc.h"
18#include "gdi.h"
19#include "xmalloc.h"
Huw D M Davies9c68faa1998-11-25 12:36:03 +000020#include "x11drv.h"
Alexandre Julliardda0cfb31996-12-01 17:17:47 +000021#include "debug.h"
22
Alexandre Julliardb1bac321996-12-15 19:45:59 +000023typedef enum WING_DITHER_TYPE
24{
25 WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4
26} WING_DITHER_TYPE;
27
28static int __WinGOK = -1;
29
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
41 */
42
43static BITMAPINFOHEADER __bmpiWinG = { 0, 1, -1, 1, 8, BI_RGB, 1, 0, 0, 0, 0 };
44
Alexandre Julliard44ed71f1997-12-21 19:17:50 +000045static void __initWinG(void)
Alexandre Julliardb1bac321996-12-15 19:45:59 +000046{
47 if( __WinGOK < 0 )
48 {
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000049 Status s = TSXShmQueryExtension(display);
Alexandre Julliardb1bac321996-12-15 19:45:59 +000050 if( s )
51 {
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000052 int i = TSXShmPixmapFormat(display);
Alexandre Julliardb1bac321996-12-15 19:45:59 +000053 if( i == ZPixmap && screenDepth == 8 )
54 {
55 __WinGOK = True;
56 return;
57 }
58 }
Alexandre Julliarda0d77311998-09-13 16:32:00 +000059 FIXME(wing,"WinG: incorrect depth or unsupported card.\n");
Alexandre Julliardb1bac321996-12-15 19:45:59 +000060 __WinGOK = False;
61 }
62}
63
Alexandre Julliardda0cfb31996-12-01 17:17:47 +000064/***********************************************************************
Alexandre Julliardb1bac321996-12-15 19:45:59 +000065 * WinGCreateDC16 (WING.1001)
Alexandre Julliardda0cfb31996-12-01 17:17:47 +000066 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +000067HDC16 WINAPI WinGCreateDC16(void)
Alexandre Julliardda0cfb31996-12-01 17:17:47 +000068{
Alexandre Julliardb1bac321996-12-15 19:45:59 +000069 __initWinG();
Alexandre Julliardda0cfb31996-12-01 17:17:47 +000070
Alexandre Julliardb1bac321996-12-15 19:45:59 +000071 if( __WinGOK > 0 )
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000072 return CreateCompatibleDC16(0);
Alexandre Julliardb1bac321996-12-15 19:45:59 +000073 return (HDC16)NULL;
74}
Alexandre Julliardda0cfb31996-12-01 17:17:47 +000075
76/***********************************************************************
77 * WinGRecommendDIBFormat16 (WING.1002)
78 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +000079BOOL16 WINAPI WinGRecommendDIBFormat16(BITMAPINFO *fmt)
Alexandre Julliardda0cfb31996-12-01 17:17:47 +000080{
Alexandre Julliard54c27111998-03-29 19:44:57 +000081 FIXME(wing,"(%p): stub\n", fmt);
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +000082
Alexandre Julliardb1bac321996-12-15 19:45:59 +000083 if( __WinGOK > 0 && fmt )
84 {
85 memcpy(&fmt->bmiHeader, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
86 return TRUE;
87 }
88 return FALSE;
Alexandre Julliardda0cfb31996-12-01 17:17:47 +000089}
90
91/***********************************************************************
92 * WinGCreateBitmap16 (WING.1003)
93 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +000094HBITMAP16 WINAPI WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header,
95 void **bits)
Alexandre Julliardda0cfb31996-12-01 17:17:47 +000096{
Alexandre Julliard54c27111998-03-29 19:44:57 +000097 FIXME(wing,"(%x,%p,%p): empty stub! (expect failure)\n",
98 winDC, header, bits);
Alexandre Julliardb1bac321996-12-15 19:45:59 +000099 if( __WinGOK > 0 && header )
100 {
101 BITMAPINFOHEADER* bmpi = &header->bmiHeader;
102
Alexandre Julliard54c27111998-03-29 19:44:57 +0000103 FIXME(wing,"bytes=%i,planes=%i,bpp=%i,x=%i,y=%i,rle=0x%08x,size=%i\n",
104 (int)bmpi->biSize, bmpi->biPlanes, bmpi->biBitCount,
105 (int)bmpi->biWidth, (int)bmpi->biHeight,
106 (unsigned)bmpi->biCompression, (int)bmpi->biSizeImage);
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000107
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 )
112 {
113 unsigned bytes = (bmpi->biWidth + bmpi->biWidth % 2)*(-bmpi->biHeight) * bmpi->biBitCount/8;
114 int key = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0x01FF);
115
116 if( key )
117 {
118 /* Create the BITMAPOBJ
119 *
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.
124 */
125
126 HBITMAP16 hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
127 if (hbitmap)
128 {
129 __ShmBitmapCtl* p = (__ShmBitmapCtl*)xmalloc(sizeof(__ShmBitmapCtl));
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000130 BITMAPOBJ* bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap );
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000131
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;
142
143 p->si.shmid = key;
144 p->si.shmaddr = shmat(key, NULL, 0);
145 p->si.readOnly = False;
146
147 if( p->si.shmaddr )
148 {
149 WORD sel = 0;
150
Alexandre Julliard829fe321998-07-26 14:27:39 +0000151 TSXShmAttach(display, &p->si);
Marcus Meissner1cd70561998-11-22 12:33:29 +0000152 bmpObjPtr->pixmap = TSXShmCreatePixmap(display, rootWindow,
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000153 p->si.shmaddr, &p->si, bmpObjPtr->bitmap.bmWidth,
154 bmpObjPtr->bitmap.bmHeight, bmpi->biBitCount );
155 if( bmpObjPtr->pixmap )
156 {
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000157 sel = SELECTOR_AllocBlock( p->si.shmaddr, bytes,
158 SEGMENT_DATA, FALSE, FALSE);
159 if (sel) p->bits = PTR_SEG_OFF_TO_SEGPTR(sel,0);
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000160 else TSXFreePixmap( display, bmpObjPtr->pixmap );
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000161 }
162 if( !sel )
163 {
164 shmdt( p->si.shmaddr );
165 p->si.shmaddr = NULL;
166 }
167 }
168 if( !p->si.shmaddr )
169 {
170 GDI_FreeObject( hbitmap );
171 hbitmap = 0;
172 }
173 }
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000174 GDI_HEAP_UNLOCK( hbitmap );
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000175 return hbitmap;
176 }
177 }
178#endif
179 }
180 return 0;
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000181}
182
183/***********************************************************************
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000184 * WinGGetDIBPointer (WING.1004)
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000185 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000186SEGPTR WINAPI WinGGetDIBPointer16(HBITMAP16 hWinGBitmap, BITMAPINFO* bmpi)
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000187{
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000188#ifdef PRELIMINARY_WING16_SUPPORT
189 BITMAPOBJ* bmp = (BITMAPOBJ *) GDI_GetObjPtr( hWinGBitmap, BITMAP_MAGIC );
190
191 if( bmp )
192 {
193 __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
194 if( p )
195 {
196 if( bmpi ) memcpy( bmpi, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000197 GDI_HEAP_UNLOCK( hWinGBitmap );
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000198 return p->bits;
199 }
200 }
201#endif
202 return (SEGPTR)NULL;
203}
204
205/***********************************************************************
206 * WinGSetDIBColorTable (WING.1004)
207 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000208UINT16 WINAPI WinGSetDIBColorTable16(HDC16 hWinGDC, UINT16 start, UINT16 num,
209 RGBQUAD* pColor)
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000210{
Alexandre Julliard54c27111998-03-29 19:44:57 +0000211 FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",hWinGDC,start,num,pColor);
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000212 return num;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000213}
214
215/***********************************************************************
216 * WinGGetDIBColorTable16 (WING.1005)
217 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000218UINT16 WINAPI WinGGetDIBColorTable16(HDC16 winDC, UINT16 start,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000219 UINT16 num, RGBQUAD* colors)
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000220{
Alexandre Julliard54c27111998-03-29 19:44:57 +0000221 FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",winDC,start,num,colors);
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000222 return 0;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000223}
224
225/***********************************************************************
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000226 * WinGCreateHalfTonePalette16 (WING.1007)
227 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000228HPALETTE16 WINAPI WinGCreateHalfTonePalette16(void)
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000229{
Alexandre Julliard54c27111998-03-29 19:44:57 +0000230 FIXME(wing,"(void): empty stub!\n");
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000231 return 0;
232}
233
234/***********************************************************************
235 * WinGCreateHalfToneBrush16 (WING.1008)
236 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000237HPALETTE16 WINAPI WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col,
238 WING_DITHER_TYPE type)
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000239{
Alexandre Julliard54c27111998-03-29 19:44:57 +0000240 FIXME(wing,"(...): empty stub!\n");
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000241 return 0;
242}
243
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000244/***********************************************************************
245 * WinGStretchBlt16 (WING.1009)
246 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000247BOOL16 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)
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000251{
252
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000253 return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000254}
255
256/***********************************************************************
257 * WinGBitBlt16 (WING.1010)
258 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000259BOOL16 WINAPI WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
260 INT16 widDest, INT16 heiDest, HDC16 srcDC,
261 INT16 xSrc, INT16 ySrc)
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000262{
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000263 /* destDC is a display DC, srcDC is a memory DC */
264
265 DC *dcDst, *dcSrc;
Huw D M Davies9c68faa1998-11-25 12:36:03 +0000266 X11DRV_PDEVICE *physDevDst, *physDevSrc;
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000267
268 if (!(dcDst = (DC *)GDI_GetObjPtr( destDC, DC_MAGIC ))) return FALSE;
269 if (!(dcSrc = (DC *) GDI_GetObjPtr( srcDC, DC_MAGIC ))) return FALSE;
Huw D M Davies9c68faa1998-11-25 12:36:03 +0000270 physDevDst = (X11DRV_PDEVICE *)dcDst->physDev;
271 physDevSrc = (X11DRV_PDEVICE *)dcSrc->physDev;
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000272
273 if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );
274
275 xSrc = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
276 ySrc = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
277 xDest = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
278 yDest = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000279 widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
280 heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000281
Huw D M Davies9c68faa1998-11-25 12:36:03 +0000282 TSXSetFunction( display, physDevDst->gc, GXcopy );
283 TSXCopyArea( display, physDevSrc->drawable,
284 physDevDst->drawable, physDevDst->gc,
285 xSrc, ySrc, widDest, heiDest, xDest, yDest );
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000286 return TRUE;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000287}
288