+ }
+
+ /* Bind the new framebuffer */
+ ctx->hDrawDC = hDrawDC;
+ ctx->hReadDC = hReadDC;
+
+ struct stw_framebuffer *old_fb = ctx->current_framebuffer;
+ if (old_fb != fb) {
+ stw_framebuffer_reference_locked(fb);
+ ctx->current_framebuffer = fb;
+ }
+ stw_framebuffer_unlock(fb);
+
+ if (hReadDC) {
+ if (hReadDC == hDrawDC) {
+ fbRead = fb;
+ }
+ else {
+ fbRead = stw_framebuffer_from_hdc( hReadDC );
+
+ if (fbRead) {
+ stw_framebuffer_update(fbRead);
+ }
+ else {
+ /* Applications should call SetPixelFormat before creating a
+ * context, but not all do, and the opengl32 runtime seems to
+ * use a default pixel format in some cases, so we must create
+ * a framebuffer for those here.
+ */
+ int iPixelFormat = GetPixelFormat(hReadDC);
+ if (iPixelFormat)
+ fbRead = stw_framebuffer_create( hReadDC, iPixelFormat );
+ if (!fbRead)
+ goto fail;
+ }
+
+ if (fbRead->iPixelFormat != ctx->iPixelFormat) {
+ stw_framebuffer_unlock(fbRead);
+ SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+ goto fail;
+ }
+ stw_framebuffer_unlock(fbRead);
+ }
+ ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
+ fb->stfb, fbRead->stfb);
+ }
+ else {
+ /* Note: when we call this function we will wind up in the
+ * stw_st_framebuffer_validate_locked() function which will incur
+ * a recursive fb->mutex lock.
+ */
+ ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
+ fb->stfb, fb->stfb);
+ }
+
+ if (old_fb && old_fb != fb) {
+ stw_lock_framebuffers(stw_dev);
+ stw_framebuffer_lock(old_fb);
+ stw_framebuffer_release_locked(old_fb);
+ stw_unlock_framebuffers(stw_dev);
+ }
+
+fail:
+ if (fb) {
+ /* fb must be unlocked at this point. */
+ assert(!stw_own_mutex(&fb->mutex));
+ }
+
+ /* On failure, make the thread's current rendering context not current
+ * before returning.
+ */
+ if (!ret) {
+ stw_make_current(NULL, NULL, 0);
+ }
+ } else {
+ ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);