JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsPbufferPeerInfo_nCreate
  (JNIEnv *env, jobject self, jobject peer_info_handle,
  jint width, jint height, jobject pixel_format,
  jobject pixelFormatCaps, jobject pBufferAttribs)
{
	int origin_x = 0; int origin_y = 0;
	HWND dummy_hwnd;
	HDC dummy_hdc;
	HPBUFFERARB Pbuffer;
	HDC Pbuffer_dc;
	WGLExtensions extensions;
	const int *pBufferAttribs_ptr;
	WindowsPeerInfo *peer_info = (WindowsPeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle);
	int pixel_format_id;

	if ( pBufferAttribs != NULL ) {
		pBufferAttribs_ptr = (const int *)(*env)->GetDirectBufferAddress(env, pBufferAttribs);
	} else {
		pBufferAttribs_ptr = NULL;
	}
	if (!getExtensions(env, &extensions, pixel_format, pixelFormatCaps))
		return;
	dummy_hwnd = createDummyWindow(origin_x, origin_y);
	if (dummy_hwnd == NULL) {
		throwException(env, "Could not create dummy window");
		return;
	}
	dummy_hdc = GetDC(dummy_hwnd);
	pixel_format_id = findPixelFormatOnDC(env, dummy_hdc, origin_x, origin_y, pixel_format, pixelFormatCaps, false, false, true, false);
	if (pixel_format_id == -1) {
		closeWindow(&dummy_hwnd, &dummy_hdc);
		return;
	}
	Pbuffer = extensions.wglCreatePbufferARB(dummy_hdc, pixel_format_id, width, height, pBufferAttribs_ptr);
	closeWindow(&dummy_hwnd, &dummy_hdc);
	if (Pbuffer == NULL) {
		throwException(env, "Could not create Pbuffer");
		return;
	}
	Pbuffer_dc = extensions.wglGetPbufferDCARB(Pbuffer);
	if (Pbuffer_dc == NULL) {
		extensions.wglDestroyPbufferARB(Pbuffer);
		throwException(env, "Could not get Pbuffer DC");
		return;
	}
	peer_info->u.pbuffer.extensions = extensions;
	peer_info->u.pbuffer.pbuffer = Pbuffer;
	peer_info->drawable_hdc = Pbuffer_dc;
}
static bool getExtensions(JNIEnv *env, WGLExtensions *extensions, jobject pixel_format, jobject pixelFormatCaps) {
	int origin_x = 0; int origin_y = 0;
	HWND dummy_hwnd;
	HDC dummy_hdc;
	HGLRC dummy_context;
	HDC saved_hdc;
	HGLRC saved_context;
	int pixel_format_id;

	dummy_hwnd = createDummyWindow(origin_x, origin_y);
	if (dummy_hwnd == NULL) {
		throwException(env, "Could not create dummy window");
		return false;
	}
	dummy_hdc = GetDC(dummy_hwnd);
	pixel_format_id = findPixelFormatOnDC(env, dummy_hdc, origin_x, origin_y, pixel_format, pixelFormatCaps, false, true, false, false);
	if (pixel_format_id == -1) {
		closeWindow(&dummy_hwnd, &dummy_hdc);
		return false;
	}
	if (!applyPixelFormat(env, dummy_hdc, pixel_format_id)) {
		closeWindow(&dummy_hwnd, &dummy_hdc);
		return false;
	}
	dummy_context = wglCreateContext(dummy_hdc);
	if (dummy_context == NULL) {
		closeWindow(&dummy_hwnd, &dummy_hdc);
		throwException(env, "Could not create dummy context");
		return false;
	}
	saved_hdc = wglGetCurrentDC();
	saved_context = wglGetCurrentContext();
	if (!wglMakeCurrent(dummy_hdc, dummy_context)) {
		wglMakeCurrent(saved_hdc, saved_context);
		closeWindow(&dummy_hwnd, &dummy_hdc);
		wglDeleteContext(dummy_context);
		throwException(env, "Could not make dummy context current");
		return false;
	}
	extgl_InitWGL(extensions);
	if (!wglMakeCurrent(saved_hdc, saved_context))
		printfDebugJava(env, "ERROR: Could not restore current context");
	closeWindow(&dummy_hwnd, &dummy_hdc);
	wglDeleteContext(dummy_context);
	return true;
}
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsPeerInfo_nChoosePixelFormat
  (JNIEnv *env, jclass clazz, jlong hdc_ptr, jint origin_x, jint origin_y, jobject pixel_format, jobject pixel_format_caps, jboolean use_hdc_bpp, jboolean window, jboolean pbuffer, jboolean double_buffer) {
	HDC hdc = (HDC)(INT_PTR)hdc_ptr;
	return findPixelFormatOnDC(env, hdc, origin_x, origin_y, pixel_format, pixel_format_caps, use_hdc_bpp, window, pbuffer, double_buffer);
}