00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <windows.h>
00029
00030 #include "main/context.h"
00031 #include "pipe/p_format.h"
00032 #include "state_tracker/st_context.h"
00033 #include "state_tracker/st_public.h"
00034 #include "stw_framebuffer.h"
00035
00036 void
00037 framebuffer_resize(
00038 struct stw_framebuffer *fb,
00039 GLuint width,
00040 GLuint height )
00041 {
00042 if (fb->hbmDIB == NULL || fb->stfb->Base.Width != width || fb->stfb->Base.Height != height) {
00043 if (fb->hbmDIB)
00044 DeleteObject( fb->hbmDIB );
00045
00046 fb->hbmDIB = CreateCompatibleBitmap(
00047 fb->hDC,
00048 width,
00049 height );
00050 }
00051
00052 st_resize_framebuffer( fb->stfb, width, height );
00053 }
00054
00055 static struct stw_framebuffer *fb_head = NULL;
00056
00057 static LRESULT CALLBACK
00058 window_proc(
00059 HWND hWnd,
00060 UINT uMsg,
00061 WPARAM wParam,
00062 LPARAM lParam )
00063 {
00064 struct stw_framebuffer *fb;
00065
00066 for (fb = fb_head; fb != NULL; fb = fb->next)
00067 if (fb->hWnd == hWnd)
00068 break;
00069 assert( fb != NULL );
00070
00071 if (uMsg == WM_SIZE && wParam != SIZE_MINIMIZED)
00072 framebuffer_resize( fb, LOWORD( lParam ), HIWORD( lParam ) );
00073
00074 return CallWindowProc( fb->WndProc, hWnd, uMsg, wParam, lParam );
00075 }
00076
00077
00078
00079 struct stw_framebuffer *
00080 framebuffer_create(
00081 HDC hdc,
00082 GLvisual *visual,
00083 GLuint width,
00084 GLuint height )
00085 {
00086 struct stw_framebuffer *fb;
00087 enum pipe_format colorFormat, depthFormat, stencilFormat;
00088
00089 fb = CALLOC_STRUCT( stw_framebuffer );
00090 if (fb == NULL)
00091 return NULL;
00092
00093
00094
00095 colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
00096
00097 if (visual->depthBits == 0)
00098 depthFormat = PIPE_FORMAT_NONE;
00099 else if (visual->depthBits <= 16)
00100 depthFormat = PIPE_FORMAT_Z16_UNORM;
00101 else if (visual->depthBits <= 24)
00102 depthFormat = PIPE_FORMAT_S8Z24_UNORM;
00103 else
00104 depthFormat = PIPE_FORMAT_Z32_UNORM;
00105
00106 if (visual->stencilBits == 8) {
00107 if (depthFormat == PIPE_FORMAT_S8Z24_UNORM)
00108 stencilFormat = depthFormat;
00109 else
00110 stencilFormat = PIPE_FORMAT_S8_UNORM;
00111 }
00112 else {
00113 stencilFormat = PIPE_FORMAT_NONE;
00114 }
00115
00116 fb->stfb = st_create_framebuffer(
00117 visual,
00118 colorFormat,
00119 depthFormat,
00120 stencilFormat,
00121 width,
00122 height,
00123 (void *) fb );
00124
00125 fb->cColorBits = GetDeviceCaps( hdc, BITSPIXEL );
00126 fb->hDC = hdc;
00127
00128
00129
00130 fb->hWnd = WindowFromDC( hdc );
00131 if (fb->hWnd != NULL) {
00132 fb->WndProc = (WNDPROC) SetWindowLong(
00133 fb->hWnd,
00134 GWL_WNDPROC,
00135 (LONG) window_proc );
00136 }
00137
00138 fb->next = fb_head;
00139 fb_head = fb;
00140 return fb;
00141 }
00142
00143 void
00144 framebuffer_destroy(
00145 struct stw_framebuffer *fb )
00146 {
00147 struct stw_framebuffer **link = &fb_head;
00148 struct stw_framebuffer *pfb = fb_head;
00149
00150 while (pfb != NULL) {
00151 if (pfb == fb) {
00152 if (fb->hWnd != NULL) {
00153 SetWindowLong(
00154 fb->hWnd,
00155 GWL_WNDPROC,
00156 (LONG) fb->WndProc );
00157 }
00158
00159 *link = fb->next;
00160 FREE( fb );
00161 return;
00162 }
00163
00164 link = &pfb->next;
00165 pfb = pfb->next;
00166 }
00167 }
00168
00169
00170
00171 struct stw_framebuffer *
00172 framebuffer_from_hdc(
00173 HDC hdc )
00174 {
00175 struct stw_framebuffer *fb;
00176
00177 for (fb = fb_head; fb != NULL; fb = fb->next)
00178 if (fb->hDC == hdc)
00179 return fb;
00180 return NULL;
00181 }