stw_framebuffer.c revision 0e471ac45771393ea74178eb98f41b904168cf64
1/************************************************************************** 2 * 3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include <windows.h> 29 30#include "main/context.h" 31#include "pipe/p_format.h" 32#include "state_tracker/st_context.h" 33#include "state_tracker/st_public.h" 34#include "stw_framebuffer.h" 35 36void 37framebuffer_resize( 38 struct stw_framebuffer *fb, 39 GLuint width, 40 GLuint height ) 41{ 42 if (fb->hbmDIB == NULL || fb->stfb->Base.Width != width || fb->stfb->Base.Height != height) { 43 if (fb->hbmDIB) 44 DeleteObject( fb->hbmDIB ); 45 46 fb->hbmDIB = CreateCompatibleBitmap( 47 fb->hDC, 48 width, 49 height ); 50 } 51 52 st_resize_framebuffer( fb->stfb, width, height ); 53} 54 55static struct stw_framebuffer *fb_head = NULL; 56 57static LRESULT CALLBACK 58window_proc( 59 HWND hWnd, 60 UINT uMsg, 61 WPARAM wParam, 62 LPARAM lParam ) 63{ 64 struct stw_framebuffer *fb; 65 66 for (fb = fb_head; fb != NULL; fb = fb->next) 67 if (fb->hWnd == hWnd) 68 break; 69 assert( fb != NULL ); 70 71 if (uMsg == WM_SIZE && wParam != SIZE_MINIMIZED) 72 framebuffer_resize( fb, LOWORD( lParam ), HIWORD( lParam ) ); 73 74 return CallWindowProc( fb->WndProc, hWnd, uMsg, wParam, lParam ); 75} 76 77/* Create a new framebuffer object which will correspond to the given HDC. 78 */ 79struct stw_framebuffer * 80framebuffer_create( 81 HDC hdc, 82 GLvisual *visual, 83 GLuint width, 84 GLuint height ) 85{ 86 struct stw_framebuffer *fb; 87 enum pipe_format colorFormat, depthFormat, stencilFormat; 88 89 fb = CALLOC_STRUCT( stw_framebuffer ); 90 if (fb == NULL) 91 return NULL; 92 93 /* Determine PIPE_FORMATs for buffers. 94 */ 95 colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; 96 97 if (visual->depthBits == 0) 98 depthFormat = PIPE_FORMAT_NONE; 99 else if (visual->depthBits <= 16) 100 depthFormat = PIPE_FORMAT_Z16_UNORM; 101 else if (visual->depthBits <= 24) 102 depthFormat = PIPE_FORMAT_S8Z24_UNORM; 103 else 104 depthFormat = PIPE_FORMAT_Z32_UNORM; 105 106 if (visual->stencilBits == 8) { 107 if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) 108 stencilFormat = depthFormat; 109 else 110 stencilFormat = PIPE_FORMAT_S8_UNORM; 111 } 112 else { 113 stencilFormat = PIPE_FORMAT_NONE; 114 } 115 116 fb->stfb = st_create_framebuffer( 117 visual, 118 colorFormat, 119 depthFormat, 120 stencilFormat, 121 width, 122 height, 123 (void *) fb ); 124 125 fb->cColorBits = GetDeviceCaps( hdc, BITSPIXEL ); 126 fb->hDC = hdc; 127 128 /* Subclass a window associated with the device context. 129 */ 130 fb->hWnd = WindowFromDC( hdc ); 131 if (fb->hWnd != NULL) { 132 fb->WndProc = (WNDPROC) SetWindowLong( 133 fb->hWnd, 134 GWL_WNDPROC, 135 (LONG) window_proc ); 136 } 137 138 fb->next = fb_head; 139 fb_head = fb; 140 return fb; 141} 142 143void 144framebuffer_destroy( 145 struct stw_framebuffer *fb ) 146{ 147 struct stw_framebuffer **link = &fb_head; 148 struct stw_framebuffer *pfb = fb_head; 149 150 while (pfb != NULL) { 151 if (pfb == fb) { 152 if (fb->hWnd != NULL) { 153 SetWindowLong( 154 fb->hWnd, 155 GWL_WNDPROC, 156 (LONG) fb->WndProc ); 157 } 158 159 *link = fb->next; 160 FREE( fb ); 161 return; 162 } 163 164 link = &pfb->next; 165 pfb = pfb->next; 166 } 167} 168 169/* Given an hdc, return the corresponding wgl_context. 170 */ 171struct stw_framebuffer * 172framebuffer_from_hdc( 173 HDC hdc ) 174{ 175 struct stw_framebuffer *fb; 176 177 for (fb = fb_head; fb != NULL; fb = fb->next) 178 if (fb->hDC == hdc) 179 return fb; 180 return NULL; 181} 182