| Index: ddraw/glDirectDrawClipper.cpp |
| — | — | @@ -123,6 +123,9 @@ |
| 124 | 124 |
|
| 125 | 125 | HRESULT WINAPI glDirectDrawClipper_GetClipList(glDirectDrawClipper *This, LPRECT lpRect, LPRGNDATA lpClipList, LPDWORD lpdwSize)
|
| 126 | 126 | {
|
| | 127 | + int error;
|
| | 128 | + POINT origin;
|
| | 129 | + HDC hdc;
|
| 127 | 130 | HRGN rgnrect;
|
| 128 | 131 | HRGN rgncliplist;
|
| 129 | 132 | RGNDATA *rgn;
|
| — | — | @@ -130,7 +133,86 @@ |
| 131 | 134 | TRACE_ENTER(4,14,This,26,lpRect,14,lpClipList,14,lpdwSize);
|
| 132 | 135 | if(!This) TRACE_RET(HRESULT,23,DDERR_INVALIDOBJECT);
|
| 133 | 136 | if (!lpdwSize) TRACE_RET(HRESULT, 23, DDERR_INVALIDPARAMS);
|
| 134 | | - if (!This->clipsize) TRACE_RET(HRESULT, 23, DDERR_NOCLIPLIST);
|
| | 137 | + if (!This->clipsize)
|
| | 138 | + {
|
| | 139 | + if (!This->hWnd) TRACE_RET(HRESULT, 23, DDERR_NOCLIPLIST);
|
| | 140 | + hdc = GetDC(This->hWnd);
|
| | 141 | + if (!hdc) TRACE_RET(HRESULT, 23, DDERR_GENERIC);
|
| | 142 | + rgncliplist = CreateRectRgn(0, 0, 0, 0);
|
| | 143 | + if (!rgncliplist)
|
| | 144 | + {
|
| | 145 | + ReleaseDC(This->hWnd, hdc);
|
| | 146 | + TRACE_RET(HRESULT, 23, DDERR_GENERIC);
|
| | 147 | + }
|
| | 148 | + error = GetRandomRgn(hdc, rgncliplist, SYSRGN);
|
| | 149 | + if (error == -1)
|
| | 150 | + {
|
| | 151 | + DeleteObject(rgncliplist);
|
| | 152 | + ReleaseDC(This->hWnd, hdc);
|
| | 153 | + TRACE_RET(HRESULT, 23, DDERR_GENERIC);
|
| | 154 | + }
|
| | 155 | + if (GetVersion() & 0x80000000)
|
| | 156 | + {
|
| | 157 | + GetDCOrgEx(hdc, &origin);
|
| | 158 | + OffsetRgn(rgncliplist, origin.x, origin.y);
|
| | 159 | + }
|
| | 160 | + ReleaseDC(This->hWnd, hdc);
|
| | 161 | + if (lpRect)
|
| | 162 | + {
|
| | 163 | + rgnrect = CreateRectRgnIndirect(lpRect);
|
| | 164 | + if (CombineRgn(rgncliplist, rgnrect, rgncliplist, RGN_AND) == ERROR)
|
| | 165 | + {
|
| | 166 | + DeleteObject(rgnrect);
|
| | 167 | + DeleteObject(rgncliplist);
|
| | 168 | + TRACE_RET(HRESULT, 23, DDERR_GENERIC);
|
| | 169 | + }
|
| | 170 | + DeleteObject(rgnrect);
|
| | 171 | + }
|
| | 172 | + rgnsize = GetRegionData(rgncliplist, 0, NULL);
|
| | 173 | + rgn = (RGNDATA*)malloc(rgnsize);
|
| | 174 | + if (!rgn)
|
| | 175 | + {
|
| | 176 | + DeleteObject(rgncliplist);
|
| | 177 | + TRACE_RET(HRESULT, 23, DDERR_OUTOFMEMORY);
|
| | 178 | + }
|
| | 179 | + GetRegionData(rgncliplist, rgnsize, rgn);
|
| | 180 | + if (!lpClipList)
|
| | 181 | + {
|
| | 182 | + *lpdwSize = sizeof(RGNDATAHEADER) + (rgn->rdh.nCount*sizeof(RECT));
|
| | 183 | + free(rgn);
|
| | 184 | + DeleteObject(rgncliplist);
|
| | 185 | + TRACE_EXIT(23, DD_OK);
|
| | 186 | + return DD_OK;
|
| | 187 | + }
|
| | 188 | + else
|
| | 189 | + {
|
| | 190 | + if (*lpdwSize < (sizeof(RGNDATAHEADER) + (rgn->rdh.nCount*sizeof(RECT))))
|
| | 191 | + {
|
| | 192 | + free(rgn);
|
| | 193 | + DeleteObject(rgncliplist);
|
| | 194 | + TRACE_RET(HRESULT, 23, DDERR_REGIONTOOSMALL);
|
| | 195 | + }
|
| | 196 | + *lpdwSize = sizeof(RGNDATAHEADER) + (rgn->rdh.nCount*sizeof(RECT));
|
| | 197 | +#ifdef _MSC_VER
|
| | 198 | + __try
|
| | 199 | + {
|
| | 200 | +#endif
|
| | 201 | + memcpy(lpClipList, rgn, sizeof(RGNDATAHEADER) + (rgn->rdh.nCount*sizeof(RECT)));
|
| | 202 | +#ifdef _MSC_VER
|
| | 203 | + }
|
| | 204 | + __except (GetExceptionCode() == STATUS_ACCESS_VIOLATION)
|
| | 205 | + {
|
| | 206 | + free(rgn);
|
| | 207 | + DeleteObject(rgncliplist);
|
| | 208 | + TRACE_RET(HRESULT, 23, DDERR_INVALIDCLIPLIST);
|
| | 209 | + }
|
| | 210 | +#endif
|
| | 211 | + free(rgn);
|
| | 212 | + DeleteObject(rgncliplist);
|
| | 213 | + TRACE_EXIT(23, DD_OK);
|
| | 214 | + return DD_OK;
|
| | 215 | + }
|
| | 216 | + }
|
| 135 | 217 | if (!lpClipList)
|
| 136 | 218 | {
|
| 137 | 219 | if (lpRect)
|