source: trunk/src/gdi32/dibsect.cpp@ 1710

Last change on this file since 1710 was 1710, checked in by sandervl, 26 years ago

DIBSection changes, EB's file io additions, Jens Weissner's changes to several dlls

File size: 9.5 KB
Line 
1/* $Id: dibsect.cpp,v 1.8 1999-11-12 11:38:38 sandervl Exp $ */
2
3/*
4 * GDI32 DIB sections
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1998 Patrick Haller
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#define INCL_GPI
13#define INCL_WIN
14#include <os2wrap.h> //Odin32 OS/2 api wrappers
15#include <stdlib.h>
16#include <string.h>
17#include "win32type.h"
18#include "misc.h"
19#define OS2_ONLY
20#include "dibsect.h"
21
22HWND WIN32API WindowFromDC(HDC hdc);
23HWND Win32ToOS2Handle(HWND hwnd);
24
25BOOL APIENTRY _GpiEnableYInversion (HPS hps, LONG lHeight);
26
27inline BOOL APIENTRY GpiEnableYInversion (HPS hps, LONG lHeight)
28{
29 BOOL yyrc;
30 USHORT sel = RestoreOS2FS();
31
32 yyrc = _GpiEnableYInversion(hps, lHeight);
33 SetFS(sel);
34
35 return yyrc;
36}
37
38
39//NOTE:
40//This is not a complete solution for CreateDIBSection, but enough for Quake 2!
41//******************************************************************************
42//******************************************************************************
43DIBSection::DIBSection(WINBITMAPINFOHEADER *pbmi, DWORD handle, int fFlip)
44 : bmpBits(NULL), pOS2bmp(NULL), next(NULL)
45{
46 int os2bmpsize;
47
48 bmpsize = pbmi->biWidth;
49 /* @@@PH 98/06/07 -- high-color bitmaps don't have palette */
50
51
52 this->fFlip = fFlip;
53 os2bmpsize = sizeof(BITMAPINFO2);
54
55 switch(pbmi->biBitCount)
56 {
57 case 1:
58 bmpsize /= 8;
59 os2bmpsize += ((1 << pbmi->biBitCount)-1)*sizeof(RGB2);
60 break;
61 case 4:
62 bmpsize /= 2;
63 os2bmpsize += ((1 << pbmi->biBitCount)-1)*sizeof(RGB2);
64 break;
65 case 8:
66 os2bmpsize += ((1 << pbmi->biBitCount)-1)*sizeof(RGB2);
67 break;
68 case 16:
69 bmpsize *= 2;
70 break;
71 case 24:
72 bmpsize *= 3;
73 break;
74 case 32:
75 bmpsize *= 4;
76 break;
77 }
78 if(bmpsize & 3) {
79 bmpsize = (bmpsize + 3) & ~3;
80 }
81
82 bmpBits = (char *)malloc(bmpsize*pbmi->biHeight);
83
84 pOS2bmp = (BITMAPINFO2 *)malloc(os2bmpsize);
85
86 memset(pOS2bmp, /* set header + palette entries to zero */
87 0,
88 os2bmpsize);
89
90 pOS2bmp->cbFix = sizeof(BITMAPINFO2) - sizeof(RGB2);
91 pOS2bmp->cx = pbmi->biWidth;
92 pOS2bmp->cy = pbmi->biHeight;
93 pOS2bmp->cPlanes = pbmi->biPlanes;
94 pOS2bmp->cBitCount = pbmi->biBitCount;
95 pOS2bmp->ulCompression = pbmi->biCompression;
96 pOS2bmp->cbImage = pbmi->biSizeImage;
97 dprintf(("pOS2bmp->cx %d\n", pOS2bmp->cx));
98 dprintf(("pOS2bmp->cy %d\n", pOS2bmp->cy));
99 dprintf(("pOS2bmp->cPlanes %d\n", pOS2bmp->cPlanes));
100 dprintf(("pOS2bmp->cBitCount %d\n", pOS2bmp->cBitCount));
101 dprintf(("pOS2bmp->ulCompression %d\n", pOS2bmp->ulCompression));
102 dprintf(("pOS2bmp->cbImage %d\n", pOS2bmp->cbImage));
103
104 this->handle = handle;
105
106 if(section == NULL)
107 {
108 dprintf(("section was NULL\n"));
109 section = this;
110 }
111 else
112 {
113 DIBSection *dsect = section;
114 dprintf(("Increment section starting at %08X\n",dsect));
115
116 /* @@@PH 98/07/11 fix for dsect->next == NULL */
117 while ( (dsect->next != this) &&
118 (dsect->next != NULL) )
119 {
120 dprintf(("Increment section to %08X\n",dsect->next));
121 dsect = dsect->next;
122 }
123 dsect->next = this;
124 }
125 dprintf(("Class created"));
126}
127//******************************************************************************
128//******************************************************************************
129DIBSection::~DIBSection()
130{
131 if(bmpBits)
132 free(bmpBits);
133 if(pOS2bmp)
134 free(pOS2bmp);
135
136 if(section == this) {
137 section = this->next;
138 }
139 else {
140 DIBSection *dsect = section;
141
142 while(dsect->next != this) {
143 dsect = dsect->next;
144 }
145 dsect->next = this->next;
146 }
147}
148//******************************************************************************
149//******************************************************************************
150int DIBSection::SetDIBColorTable(int startIdx, int cEntries, RGBQUAD *rgb)
151{
152 int i;
153
154 if(startIdx + cEntries > (1 << pOS2bmp->cBitCount)) {
155 dprintf(("DIBSection::SetDIBColorTable, invalid nr of entries %d %d\n", startIdx, cEntries));
156 return(0);
157 }
158 memcpy(&pOS2bmp->argbColor[startIdx], rgb, cEntries*sizeof(RGB2));
159 for(i=startIdx;i<cEntries;i++) {
160 pOS2bmp->argbColor[i].fcOptions = 0;
161 }
162 return(cEntries);
163}
164//******************************************************************************
165//******************************************************************************
166BOOL DIBSection::BitBlt(HDC hdcDest, int nXdest, int nYdest, int nWidth,
167 int nHeight, int nXsrc, int nYsrc, DWORD Rop)
168{
169 HPS hps = (HPS)hdcDest;
170 POINTL point[4];
171 LONG rc;
172
173 HWND hwndDest = WindowFromDC(hdcDest);
174 hwndDest = Win32ToOS2Handle(hwndDest);
175 if(hwndDest != 0) {
176 hps = WinGetPS(hwndDest);
177 }
178 if(hps == 0) {
179 eprintf(("DIBSection::BitBlt, hps == 0 hwndDest = %X", hwndDest));
180 return(FALSE);
181 }
182
183 dprintf(("DIBSection::BitBlt %X %x (%d,%d) to (%d,%d) (%d,%d) rop %x\n", hdcDest, hwndDest, nXdest, nYdest, nWidth, nHeight, nXsrc, nYsrc, Rop));
184
185 point[0].x = nXdest;
186 point[0].y = nYdest;
187 point[1].x = nXdest + nWidth - 1;
188 point[1].y = nYdest + nHeight - 1;
189 point[2].x = nXsrc;
190 point[2].y = nYsrc;
191 if(nXsrc + nWidth > pOS2bmp->cx) {
192 point[3].x = pOS2bmp->cx;
193 }
194 else point[3].x = nXsrc + nWidth;
195
196 if(nYsrc + nHeight > pOS2bmp->cy) {
197 point[3].y = pOS2bmp->cy;
198 }
199 else point[3].y = nYsrc + nHeight;
200
201#if 1
202 if(fFlip & FLIP_VERT) {
203 GpiEnableYInversion(hps, nHeight);
204 }
205
206 if(fFlip & FLIP_HOR) {
207 ULONG x;
208 x = point[0].x;
209 point[0].x = point[1].x;
210 point[1].x = x;
211 }
212#endif
213
214 rc = GpiDrawBits(hps, bmpBits, pOS2bmp, 4, &point[0], ROP_SRCCOPY, BBO_OR);
215
216 if(hwndDest != 0) {
217 WinReleasePS(hps);
218 }
219 if(rc == GPI_OK)
220 return(TRUE);
221 dprintf(("DIBSection::BitBlt %X (%d,%d) (%d,%d) to (%d,%d) (%d,%d) returned %d\n", hps, point[0].x, point[0].y, point[1].x, point[1].y, point[2].x, point[2].y, point[3].x, point[3].y, rc));
222 dprintf(("WinGetLastError returned %X\n", WinGetLastError(WinQueryAnchorBlock(hwndDest)) & 0xFFFF));
223 return(FALSE);
224}
225//******************************************************************************
226//******************************************************************************
227void DIBSection::SelectDIBObject(HDC hdc)
228{
229 this->hdc = hdc;
230 hwndParent = WinWindowFromDC(hdc);
231}
232//******************************************************************************
233//******************************************************************************
234DIBSection *DIBSection::find(DWORD handle)
235{
236 DIBSection *dsect = section;
237
238 while(dsect) {
239 if(dsect->handle == handle) {
240 return(dsect);
241 }
242 dsect = dsect->next;
243 }
244 return(NULL);
245}
246//******************************************************************************
247//A bitmap can only be selected into one DC, so this works.
248//******************************************************************************
249DIBSection *DIBSection::findHDC(HDC hdc)
250{
251 DIBSection *dsect = section;
252
253 while(dsect) {
254 if(dsect->hdc == hdc) {
255 return(dsect);
256 }
257 dsect = dsect->next;
258 }
259 return(NULL);
260}
261//******************************************************************************
262//******************************************************************************
263void DIBSection::deleteSection(DWORD handle)
264{
265 DIBSection *dsect = find(handle);
266
267 if(dsect)
268 delete dsect;
269
270}
271//******************************************************************************
272//******************************************************************************
273int DIBSection::GetDIBSection(int iSize , DIBSECTION *pDIBSection){
274 if( (sizeof(DIBSECTION)==iSize) &&
275 (pDIBSection !=NULL))
276 {
277 // BITMAP struct
278 pDIBSection->dsBm.bmType = 0; // TODO: put the correct value here
279 pDIBSection->dsBm.bmWidth = pOS2bmp->cx;
280 pDIBSection->dsBm.bmHeight = pOS2bmp->cy;
281 pDIBSection->dsBm.bmWidthBytes = bmpsize;
282 pDIBSection->dsBm.bmPlanes = pOS2bmp->cPlanes;
283 pDIBSection->dsBm.bmBitsPixel = pOS2bmp->cBitCount;
284 pDIBSection->dsBm.bmBits = bmpBits;
285 // BITMAPINFOHEADER data
286 pDIBSection->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
287 pDIBSection->dsBmih.biWidth = pOS2bmp->cx;
288 pDIBSection->dsBmih.biHeight = pOS2bmp->cy;
289 pDIBSection->dsBmih.biPlanes = pOS2bmp->cPlanes;
290 pDIBSection->dsBmih.biBitCount = pOS2bmp->cBitCount;
291 pDIBSection->dsBmih.biCompression = pOS2bmp->ulCompression;
292 pDIBSection->dsBmih.biSizeImage = pOS2bmp->cbImage;
293 pDIBSection->dsBmih.biXPelsPerMeter = 0; // TODO: put the correct value here
294 pDIBSection->dsBmih.biYPelsPerMeter = 0;
295 pDIBSection->dsBmih.biClrUsed = (1<< pOS2bmp->cBitCount);
296 pDIBSection->dsBmih.biClrImportant = 0;
297
298 pDIBSection->dsBitfields[0] = 0; // TODO: put the correct value here
299 pDIBSection->dsBitfields[1] = 0;
300 pDIBSection->dsBitfields[2] = 0;
301
302 pDIBSection->dshSection = this->handle;
303
304 pDIBSection->dsOffset = 0; // TODO: put the correct value here
305
306 return 0; //ERROR_SUCCESS
307 }
308 return 87; //ERROR_INVALID_PARAMETER
309
310}
311//******************************************************************************
312//******************************************************************************
313DIBSection *DIBSection::section = NULL;
314
Note: See TracBrowser for help on using the repository browser.