#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
+#include "util/u_debug.h"
+
#include "stw_device.h"
#include "stw_pixelformat.h"
#include "stw_framebuffer.h"
+#define LARGE_WINDOW_SIZE 60000
+
+
+static LRESULT CALLBACK
+WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ MINMAXINFO *pMMI;
+ switch (uMsg) {
+ case WM_GETMINMAXINFO:
+ // Allow to create a window bigger than the desktop
+ pMMI = (MINMAXINFO *)lParam;
+ pMMI->ptMaxSize.x = LARGE_WINDOW_SIZE;
+ pMMI->ptMaxSize.y = LARGE_WINDOW_SIZE;
+ pMMI->ptMaxTrackSize.x = LARGE_WINDOW_SIZE;
+ pMMI->ptMaxTrackSize.y = LARGE_WINDOW_SIZE;
+ break;
+ default:
+ break;
+ }
+
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+
HPBUFFERARB WINAPI
-wglCreatePbufferARB(HDC _hDC,
+wglCreatePbufferARB(HDC hCurrentDC,
int iPixelFormat,
int iWidth,
int iHeight,
RECT rect;
HWND hWnd;
HDC hDC;
-
- info = stw_pixelformat_get_info(iPixelFormat);
+ int iDisplayablePixelFormat;
+ PIXELFORMATDESCRIPTOR pfd;
+ BOOL bRet;
+ int textureFormat = WGL_NO_TEXTURE_ARB;
+ int textureTarget = WGL_NO_TEXTURE_ARB;
+ BOOL textureMipmap = FALSE;
+
+ info = stw_pixelformat_get_info(iPixelFormat - 1);
if (!info) {
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
return 0;
return 0;
}
- for (piAttrib = piAttribList; *piAttrib; piAttrib++) {
- switch (*piAttrib) {
- case WGL_PBUFFER_LARGEST_ARB:
- piAttrib++;
- useLargest = *piAttrib;
- break;
- default:
- SetLastError(ERROR_INVALID_DATA);
- return 0;
+ if (piAttribList) {
+ for (piAttrib = piAttribList; *piAttrib; piAttrib++) {
+ switch (*piAttrib) {
+ case WGL_PBUFFER_LARGEST_ARB:
+ piAttrib++;
+ useLargest = *piAttrib;
+ break;
+ case WGL_TEXTURE_FORMAT_ARB:
+ /* WGL_ARB_render_texture */
+ piAttrib++;
+ textureFormat = *piAttrib;
+ if (textureFormat != WGL_TEXTURE_RGB_ARB &&
+ textureFormat != WGL_TEXTURE_RGBA_ARB &&
+ textureFormat != WGL_NO_TEXTURE_ARB) {
+ SetLastError(ERROR_INVALID_DATA);
+ return 0;
+ }
+ break;
+ case WGL_TEXTURE_TARGET_ARB:
+ /* WGL_ARB_render_texture */
+ piAttrib++;
+ textureTarget = *piAttrib;
+ if (textureTarget != WGL_TEXTURE_CUBE_MAP_ARB &&
+ textureTarget != WGL_TEXTURE_1D_ARB &&
+ textureTarget != WGL_TEXTURE_2D_ARB &&
+ textureTarget != WGL_NO_TEXTURE_ARB) {
+ SetLastError(ERROR_INVALID_DATA);
+ return 0;
+ }
+ break;
+ case WGL_MIPMAP_TEXTURE_ARB:
+ /* WGL_ARB_render_texture */
+ piAttrib++;
+ textureMipmap = !!*piAttrib;
+ break;
+ default:
+ SetLastError(ERROR_INVALID_DATA);
+ debug_printf("wgl: Unsupported attribute 0x%x in %s\n",
+ *piAttrib, __func__);
+ return 0;
+ }
}
}
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wc.lpfnWndProc = DefWindowProc;
+ wc.lpfnWndProc = WndProc;
wc.lpszClassName = "wglpbuffer";
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
return 0;
}
- SetPixelFormat(hDC, iPixelFormat, &info->pfd);
-
+ /*
+ * We can't pass non-displayable pixel formats to GDI, which is why we
+ * create the framebuffer object before calling SetPixelFormat().
+ */
fb = stw_framebuffer_create(hDC, iPixelFormat);
if (!fb) {
SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+ return NULL;
}
+ fb->bPbuffer = TRUE;
+
+ /* WGL_ARB_render_texture fields */
+ fb->textureTarget = textureTarget;
+ fb->textureFormat = textureFormat;
+ fb->textureMipmap = textureMipmap;
+
+ iDisplayablePixelFormat = fb->iDisplayablePixelFormat;
+
+ stw_framebuffer_unlock(fb);
+
+ /*
+ * We need to set a displayable pixel format on the hidden window DC
+ * so that wglCreateContext and wglMakeCurrent are not overruled by GDI.
+ */
+ bRet = SetPixelFormat(hDC, iDisplayablePixelFormat, &pfd);
+ assert(bRet);
+
return (HPBUFFERARB)fb;
}
struct stw_framebuffer *fb;
HDC hDC;
- fb = (struct stw_framebuffer *)hPbuffer;
+ if (!hPbuffer) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return NULL;
+ }
+
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
hDC = GetDC(fb->hWnd);
- SetPixelFormat(hDC, fb->iPixelFormat, &fb->pfi->pfd);
return hDC;
}
{
struct stw_framebuffer *fb;
- fb = (struct stw_framebuffer *)hPbuffer;
+ if (!hPbuffer) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
return ReleaseDC(fb->hWnd, hDC);
}
{
struct stw_framebuffer *fb;
- fb = (struct stw_framebuffer *)hPbuffer;
+ if (!hPbuffer) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
/* This will destroy all our data */
return DestroyWindow(fb->hWnd);
{
struct stw_framebuffer *fb;
- fb = (struct stw_framebuffer *)hPbuffer;
+ if (!hPbuffer) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
switch (iAttribute) {
case WGL_PBUFFER_WIDTH_ARB:
*piValue = fb->width;
return TRUE;
case WGL_PBUFFER_HEIGHT_ARB:
- *piValue = fb->width;
+ *piValue = fb->height;
return TRUE;
case WGL_PBUFFER_LOST_ARB:
/* We assume that no content is ever lost due to display mode change */
*piValue = FALSE;
return TRUE;
+ /* WGL_ARB_render_texture */
+ case WGL_TEXTURE_TARGET_ARB:
+ *piValue = fb->textureTarget;
+ return TRUE;
+ case WGL_TEXTURE_FORMAT_ARB:
+ *piValue = fb->textureFormat;
+ return TRUE;
+ case WGL_MIPMAP_TEXTURE_ARB:
+ *piValue = fb->textureMipmap;
+ return TRUE;
+ case WGL_MIPMAP_LEVEL_ARB:
+ *piValue = fb->textureLevel;
+ return TRUE;
+ case WGL_CUBE_MAP_FACE_ARB:
+ *piValue = fb->textureFace + WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
+ return TRUE;
default:
SetLastError(ERROR_INVALID_DATA);
return FALSE;