Added RtlAllocateAndInitializeSid entry.
[wine] / graphics / wing.c
1 /*
2  * WinG support
3  *
4  * Started by Robert Pouliot <krynos@clic.net>
5  */
6
7 #include "ts_xlib.h"
8 #include "ts_xshm.h"
9 #include <sys/types.h>
10 #include <sys/ipc.h>
11 #ifndef __EMX__
12 #include <sys/shm.h>
13 #endif
14
15 #include "windows.h"
16 #include "bitmap.h"
17 #include "dc.h"
18 #include "gdi.h"
19 #include "xmalloc.h"
20 #include "debug.h"
21
22 typedef enum WING_DITHER_TYPE
23 {
24   WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4
25 } WING_DITHER_TYPE;
26
27 static int      __WinGOK = -1;
28
29 /* 
30  * WinG DIB bitmaps can be selected into DC and then scribbled upon
31  * by GDI functions. They can also be changed directly. This gives us 
32  * three choices 
33  *      - use original WinG 16-bit DLL
34  *              requires working 16-bit driver interface
35  *      - implement DIB graphics driver from scratch
36  *              see wing.zip size
37  *      - use shared pixmaps
38  *              won't work with some videocards and/or videomodes
39  * 961208 - AK
40  */
41
42 static BITMAPINFOHEADER __bmpiWinG = { 0, 1, -1, 1, 8, BI_RGB, 1, 0, 0, 0, 0 };
43
44 static void __initWinG(void)
45 {
46   if( __WinGOK < 0 )
47   {
48     Status s = TSXShmQueryExtension(display);
49     if( s )
50     {
51       int i = TSXShmPixmapFormat(display);
52       if( i == ZPixmap && screenDepth == 8 ) 
53       {
54         __WinGOK = True;
55         return;
56       }
57     } 
58     FIXME(wing,"WinG: incorrect depth or unsupported card.\n");
59     __WinGOK = False;
60   }
61 }
62
63 /***********************************************************************
64  *          WinGCreateDC16      (WING.1001)
65  */
66 HDC16 WINAPI WinGCreateDC16(void)
67 {
68   __initWinG();
69
70   if( __WinGOK > 0 )
71         return CreateCompatibleDC16(0);
72   return (HDC16)NULL;
73 }
74
75 /***********************************************************************
76  *  WinGRecommendDIBFormat16    (WING.1002)
77  */
78 BOOL16 WINAPI WinGRecommendDIBFormat16(BITMAPINFO *fmt)
79 {
80   FIXME(wing,"(%p): stub\n", fmt);
81
82   if( __WinGOK > 0 && fmt )
83   {
84     memcpy(&fmt->bmiHeader, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
85     return TRUE;
86   }
87   return FALSE;
88 }
89
90 /***********************************************************************
91  *        WinGCreateBitmap16    (WING.1003)
92  */
93 HBITMAP16 WINAPI WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header,
94                                     void **bits)
95 {
96   FIXME(wing,"(%x,%p,%p): empty stub! (expect failure)\n", 
97         winDC, header, bits);
98   if( __WinGOK > 0 && header )
99   {
100     BITMAPINFOHEADER* bmpi = &header->bmiHeader;
101
102      FIXME(wing,"bytes=%i,planes=%i,bpp=%i,x=%i,y=%i,rle=0x%08x,size=%i\n",
103            (int)bmpi->biSize, bmpi->biPlanes, bmpi->biBitCount,
104            (int)bmpi->biWidth, (int)bmpi->biHeight, 
105            (unsigned)bmpi->biCompression, (int)bmpi->biSizeImage);
106
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 )
111     {
112         unsigned bytes = (bmpi->biWidth + bmpi->biWidth % 2)*(-bmpi->biHeight) * bmpi->biBitCount/8;
113         int      key = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0x01FF);
114
115         if( key )
116         {
117             /* Create the BITMAPOBJ 
118              *
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. 
123              */
124
125             HBITMAP16 hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
126             if (hbitmap)
127             {
128               __ShmBitmapCtl* p = (__ShmBitmapCtl*)xmalloc(sizeof(__ShmBitmapCtl));
129                 BITMAPOBJ*       bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap );
130
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;
141
142                 p->si.shmid = key;
143                 p->si.shmaddr = shmat(key, NULL, 0);
144                 p->si.readOnly = False;
145
146                 if( p->si.shmaddr )
147                 {
148                     WORD        sel = 0;
149
150                     TSXShmAttach(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 )
155                     {
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 TSXFreePixmap( display, bmpObjPtr->pixmap );
160                     }
161                     if( !sel )
162                     {
163                       shmdt( p->si.shmaddr );
164                       p->si.shmaddr = NULL;
165                     }
166                 } 
167                 if( !p->si.shmaddr )
168                 {
169                     GDI_FreeObject( hbitmap );
170                     hbitmap = 0;
171                 }
172             }
173             GDI_HEAP_UNLOCK( hbitmap );
174             return hbitmap;
175         }
176     }
177 #endif
178   }
179   return 0;
180 }
181
182 /***********************************************************************
183  *  WinGGetDIBPointer   (WING.1004)
184  */
185 SEGPTR WINAPI WinGGetDIBPointer16(HBITMAP16 hWinGBitmap, BITMAPINFO* bmpi)
186 {
187 #ifdef PRELIMINARY_WING16_SUPPORT
188   BITMAPOBJ*    bmp = (BITMAPOBJ *) GDI_GetObjPtr( hWinGBitmap, BITMAP_MAGIC );
189
190   if( bmp )
191   {
192     __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
193     if( p )
194     {
195       if( bmpi ) memcpy( bmpi, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
196       GDI_HEAP_UNLOCK( hWinGBitmap );
197       return p->bits;
198     }
199   }
200 #endif
201   return (SEGPTR)NULL;
202 }
203
204 /***********************************************************************
205  *  WinGSetDIBColorTable   (WING.1004)
206  */
207 UINT16 WINAPI WinGSetDIBColorTable16(HDC16 hWinGDC, UINT16 start, UINT16 num,
208                                      RGBQUAD* pColor)
209 {
210         FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",hWinGDC,start,num,pColor);
211         return num;
212 }
213
214 /***********************************************************************
215  *  WinGGetDIBColorTable16   (WING.1005)
216  */
217 UINT16 WINAPI WinGGetDIBColorTable16(HDC16 winDC, UINT16 start,
218                                      UINT16 num, RGBQUAD* colors)
219 {
220         FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",winDC,start,num,colors);
221         return 0;
222 }
223
224 /***********************************************************************
225  *  WinGCreateHalfTonePalette16   (WING.1007)
226  */
227 HPALETTE16 WINAPI WinGCreateHalfTonePalette16(void)
228 {
229         FIXME(wing,"(void): empty stub!\n");
230         return 0;
231 }
232
233 /***********************************************************************
234  *  WinGCreateHalfToneBrush16   (WING.1008)
235  */
236 HPALETTE16 WINAPI WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col,
237                                             WING_DITHER_TYPE type)
238 {
239         FIXME(wing,"(...): empty stub!\n");
240         return 0;
241 }
242
243 /***********************************************************************
244  *  WinGStretchBlt16   (WING.1009)
245  */
246 BOOL16 WINAPI WinGStretchBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
247                                INT16 widDest, INT16 heiDest,
248                                HDC16 srcDC, INT16 xSrc, INT16 ySrc,
249                                INT16 widSrc, INT16 heiSrc)
250 {
251
252         return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
253 }
254
255 /***********************************************************************
256  *  WinGBitBlt16   (WING.1010)
257  */
258 BOOL16 WINAPI WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
259                            INT16 widDest, INT16 heiDest, HDC16 srcDC,
260                            INT16 xSrc, INT16 ySrc)
261 {
262     /* destDC is a display DC, srcDC is a memory DC */
263
264     DC *dcDst, *dcSrc;
265
266     if (!(dcDst = (DC *)GDI_GetObjPtr( destDC, DC_MAGIC ))) return FALSE;
267     if (!(dcSrc = (DC *) GDI_GetObjPtr( srcDC, DC_MAGIC ))) return FALSE;
268
269     if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );
270
271     xSrc    = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
272     ySrc    = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
273     xDest   = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
274     yDest   = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
275     widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
276     heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;
277
278     TSXSetFunction( display, dcDst->u.x.gc, GXcopy );
279     TSXCopyArea( display, dcSrc->u.x.drawable,
280                dcDst->u.x.drawable, dcDst->u.x.gc,
281                xSrc, ySrc, widDest, heiDest, xDest, yDest );
282     return TRUE;
283 }
284