1db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca/**************************************************************************
24e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca *
34e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca * Copyright 2008-2009 Vmware, Inc.
4db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * All Rights Reserved.
54e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca *
6db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a
7db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * copy of this software and associated documentation files (the
8db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * "Software"), to deal in the Software without restriction, including
9db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * without limitation the rights to use, copy, modify, merge, publish,
10db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * distribute, sub license, and/or sell copies of the Software, and to
11db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * permit persons to whom the Software is furnished to do so, subject to
12db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * the following conditions:
134e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca *
14db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * The above copyright notice and this permission notice (including the
15db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * next paragraph) shall be included in all copies or substantial portions
16db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * of the Software.
174e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca *
18db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
214e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
254e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca *
26db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca **************************************************************************/
27db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca
28db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca#include <windows.h>
2919641a9295f5d14919480124575c6727a0ad79cfJosé Fonseca
30db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca#include "pipe/p_format.h"
3167b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell#include "pipe/p_screen.h"
32f5bd93fae2e4f46665eb1f09ca64cb39ff2b8a79Michal Krol#include "util/u_format.h"
33192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu#include "util/u_memory.h"
34192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu#include "state_tracker/st_api.h"
35923b4413a63530be37cd44eed29910db21b39ac6José Fonseca
3631f1571d1f6e325c16833afbb6e15b61561e5f1fJosé Fonseca#include "stw_icd.h"
37db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca#include "stw_framebuffer.h"
3867b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell#include "stw_device.h"
3967b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell#include "stw_winsys.h"
404bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca#include "stw_tls.h"
41192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu#include "stw_context.h"
42192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu#include "stw_st.h"
4367b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell
44db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca
451068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca/**
461068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca * Search the framebuffer with the matching HWND while holding the
471068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca * stw_dev::fb_mutex global lock.
481068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca */
49d5ba39ad08f098f377fd258edb904aa7d64ab434José Fonsecastatic INLINE struct stw_framebuffer *
50557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonsecastw_framebuffer_from_hwnd_locked(
51557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   HWND hwnd )
52557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca{
53557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   struct stw_framebuffer *fb;
54557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca
55557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next)
561068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca      if (fb->hWnd == hwnd) {
571068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca         pipe_mutex_lock(fb->mutex);
58557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca         break;
591068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca      }
60557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca
61557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   return fb;
62557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca}
63557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca
64557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca
651068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca/**
661068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca * Destroy this framebuffer. Both stw_dev::fb_mutex and stw_framebuffer::mutex
67192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu * must be held, by this order.  If there are still references to the
68192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu * framebuffer, nothing will happen.
691068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca */
70557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonsecastatic INLINE void
71557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonsecastw_framebuffer_destroy_locked(
72557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   struct stw_framebuffer *fb )
73557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca{
74557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   struct stw_framebuffer **link;
75557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca
76192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   /* check the reference count */
77192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   fb->refcnt--;
78192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   if (fb->refcnt) {
79192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      pipe_mutex_unlock( fb->mutex );
80192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      return;
81192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   }
82192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu
83557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   link = &stw_dev->fb_head;
84557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   while (*link != fb)
85557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca      link = &(*link)->next;
86557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   assert(*link);
87557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   *link = fb->next;
88557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   fb->next = NULL;
89557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca
904e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   if(fb->shared_surface)
914e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      stw_dev->stw_winsys->shared_surface_close(stw_dev->screen, fb->shared_surface);
924e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
93192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   stw_st_destroy_framebuffer_locked(fb->stfb);
94557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca
95c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca   ReleaseDC(fb->hWnd, fb->hDC);
96c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca
971068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   pipe_mutex_unlock( fb->mutex );
981068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca
99557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   pipe_mutex_destroy( fb->mutex );
100557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca
101557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   FREE( fb );
102557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca}
103557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca
104557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca
1051068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonsecavoid
1061068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonsecastw_framebuffer_release(
1071068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   struct stw_framebuffer *fb)
1081068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca{
1091068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   assert(fb);
1101068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   pipe_mutex_unlock( fb->mutex );
1111068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca}
1121068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca
1131068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca
1145470a67335dfd9afffb92ff6521a77519cda40d8José Fonsecastatic INLINE void
1155470a67335dfd9afffb92ff6521a77519cda40d8José Fonsecastw_framebuffer_get_size( struct stw_framebuffer *fb )
1165470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca{
11716d42af618aa6250bedc7e66e0e2c0b061cc6e99José Fonseca   LONG width, height;
1184e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   RECT client_rect;
1194e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   RECT window_rect;
1204e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   POINT client_pos;
1215470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca
122c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   /*
123c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca    * Sanity checking.
124c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca    */
125c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca
1265470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca   assert(fb->hWnd);
127c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   assert(fb->width && fb->height);
128c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   assert(fb->client_rect.right  == fb->client_rect.left + fb->width);
129c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   assert(fb->client_rect.bottom == fb->client_rect.top  + fb->height);
130c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca
131c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   /*
132c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca    * Get the client area size.
133c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca    */
134c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca
135c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   if (!GetClientRect(fb->hWnd, &client_rect)) {
136c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca      return;
137c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   }
138c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca
1394e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   assert(client_rect.left == 0);
1404e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   assert(client_rect.top == 0);
141c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   width  = client_rect.right  - client_rect.left;
1424e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   height = client_rect.bottom - client_rect.top;
1435470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca
14416d42af618aa6250bedc7e66e0e2c0b061cc6e99José Fonseca   if (width <= 0 || height <= 0) {
14516d42af618aa6250bedc7e66e0e2c0b061cc6e99José Fonseca      /*
14616d42af618aa6250bedc7e66e0e2c0b061cc6e99José Fonseca       * When the window is minimized GetClientRect will return zeros.  Simply
14716d42af618aa6250bedc7e66e0e2c0b061cc6e99José Fonseca       * preserve the current window size, until the window is restored or
14816d42af618aa6250bedc7e66e0e2c0b061cc6e99José Fonseca       * maximized again.
14916d42af618aa6250bedc7e66e0e2c0b061cc6e99José Fonseca       */
15016d42af618aa6250bedc7e66e0e2c0b061cc6e99José Fonseca
15116d42af618aa6250bedc7e66e0e2c0b061cc6e99José Fonseca      return;
15216d42af618aa6250bedc7e66e0e2c0b061cc6e99José Fonseca   }
1535470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca
154c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   if (width != fb->width || height != fb->height) {
1555470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca      fb->must_resize = TRUE;
1565470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca      fb->width = width;
1575470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca      fb->height = height;
1585470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca   }
1594e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
1604e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   client_pos.x = 0;
1614e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   client_pos.y = 0;
162c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   if (ClientToScreen(fb->hWnd, &client_pos) &&
163c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca       GetWindowRect(fb->hWnd, &window_rect)) {
164c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca      fb->client_rect.left = client_pos.x - window_rect.left;
165c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca      fb->client_rect.top  = client_pos.y - window_rect.top;
166c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   }
1674e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
168c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   fb->client_rect.right  = fb->client_rect.left + fb->width;
169c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   fb->client_rect.bottom = fb->client_rect.top  + fb->height;
1704e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
1714e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca#if 0
1724e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   debug_printf("\n");
173c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca   debug_printf("%s: hwnd = %p\n", __FUNCTION__, fb->hWnd);
174b5829c0d6444a9eb25738c9b7f0bab8b667c8e0aJosé Fonseca   debug_printf("%s: client_position = (%li, %li)\n",
1754e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca                __FUNCTION__, client_pos.x, client_pos.y);
176b5829c0d6444a9eb25738c9b7f0bab8b667c8e0aJosé Fonseca   debug_printf("%s: window_rect = (%li, %li) - (%li, %li)\n",
1774e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca                __FUNCTION__,
1784e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca                window_rect.left, window_rect.top,
1794e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca                window_rect.right, window_rect.bottom);
180b5829c0d6444a9eb25738c9b7f0bab8b667c8e0aJosé Fonseca   debug_printf("%s: client_rect = (%li, %li) - (%li, %li)\n",
1814e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca                __FUNCTION__,
1824e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca                fb->client_rect.left, fb->client_rect.top,
1834e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca                fb->client_rect.right, fb->client_rect.bottom);
1844e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca#endif
1855470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca}
1865470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca
1875470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca
1884bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca/**
1894bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca * @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx
1904bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca * @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx
1914bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca */
1924b4855c717e839a9ee6353604558543473c020c9José FonsecaLRESULT CALLBACK
1934bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonsecastw_call_window_proc(
1944bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca   int nCode,
195db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca   WPARAM wParam,
196db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca   LPARAM lParam )
197db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca{
1984bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca   struct stw_tls_data *tls_data;
1994bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca   PCWPSTRUCT pParams = (PCWPSTRUCT)lParam;
2005470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca   struct stw_framebuffer *fb;
2014bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca
2024bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca   tls_data = stw_tls_get_data();
2034bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca   if(!tls_data)
2044bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca      return 0;
2054bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca
206e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca   if (nCode < 0 || !stw_dev)
2074bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca       return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
2084bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca
2095470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca   if (pParams->message == WM_WINDOWPOSCHANGED) {
2105470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca      /* We handle WM_WINDOWPOSCHANGED instead of WM_SIZE because according to
2115470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca       * http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx
2125470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca       * WM_SIZE is generated from WM_WINDOWPOSCHANGED by DefWindowProc so it
2135470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca       * can be masked out by the application. */
2145470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca      LPWINDOWPOS lpWindowPos = (LPWINDOWPOS)pParams->lParam;
2155470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca      if((lpWindowPos->flags & SWP_SHOWWINDOW) ||
2164e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca         !(lpWindowPos->flags & SWP_NOMOVE) ||
2175470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca         !(lpWindowPos->flags & SWP_NOSIZE)) {
2181068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca         fb = stw_framebuffer_from_hwnd( pParams->hwnd );
2195470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca         if(fb) {
2205470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca            /* Size in WINDOWPOS includes the window frame, so get the size
2215470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca             * of the client area via GetClientRect.  */
2225470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca            stw_framebuffer_get_size(fb);
2231068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca            stw_framebuffer_release(fb);
2245470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca         }
2254bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca      }
2264bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca   }
2275470a67335dfd9afffb92ff6521a77519cda40d8José Fonseca   else if (pParams->message == WM_DESTROY) {
2281068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca      pipe_mutex_lock( stw_dev->fb_mutex );
229557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca      fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd );
230557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca      if(fb)
231557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca         stw_framebuffer_destroy_locked(fb);
2321068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca      pipe_mutex_unlock( stw_dev->fb_mutex );
233557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca   }
234557d2bb42397bb5511c32b4a2b39c7978e69dc8eJosé Fonseca
2354bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca   return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
236db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca}
237db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca
23878071fe7676adfcab44983505b0f64a31aa823b5José Fonseca
239db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonsecastruct stw_framebuffer *
2401068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonsecastw_framebuffer_create(
241db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca   HDC hdc,
242fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   int iPixelFormat )
243db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca{
2440ea519f931a14e4dff6ef391803baba8bec84160José Fonseca   HWND hWnd;
2456fc244c68d3b3a9f89b6f752725e6c768cb08a84José Fonseca   struct stw_framebuffer *fb;
246fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   const struct stw_pixelformat_info *pfi;
247db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca
2480ea519f931a14e4dff6ef391803baba8bec84160José Fonseca   /* We only support drawing to a window. */
2490ea519f931a14e4dff6ef391803baba8bec84160José Fonseca   hWnd = WindowFromDC( hdc );
2500ea519f931a14e4dff6ef391803baba8bec84160José Fonseca   if(!hWnd)
2510ea519f931a14e4dff6ef391803baba8bec84160José Fonseca      return NULL;
2520ea519f931a14e4dff6ef391803baba8bec84160José Fonseca
253b4c0e1f9e16ba61acd781ed6cbe448460e2b3153José Fonseca   fb = CALLOC_STRUCT( stw_framebuffer );
254b4c0e1f9e16ba61acd781ed6cbe448460e2b3153José Fonseca   if (fb == NULL)
255b4c0e1f9e16ba61acd781ed6cbe448460e2b3153José Fonseca      return NULL;
256b4c0e1f9e16ba61acd781ed6cbe448460e2b3153José Fonseca
257c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca   /* Applications use, create, destroy device contexts, so the hdc passed is.  We create our own DC
258c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca    * because we need one for single buffered visuals.
259c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca    */
260c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca   fb->hDC = GetDC(hWnd);
261c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca
2620ea519f931a14e4dff6ef391803baba8bec84160José Fonseca   fb->hWnd = hWnd;
263fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   fb->iPixelFormat = iPixelFormat;
26411084d582764a916245ae92437421ac0cacdf335José Fonseca
2659646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca   /*
2669646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca    * We often need a displayable pixel format to make GDI happy. Set it here (always 1, i.e.,
2679646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca    * out first pixel format) where appropriat.
2689646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca    */
2699646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca   fb->iDisplayablePixelFormat = iPixelFormat <= stw_dev->pixelformat_count ? iPixelFormat : 1;
2709646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca
2710cf554fa9b31dbac1890f496974392001e2df825José Fonseca   fb->pfi = pfi = stw_pixelformat_get_info( iPixelFormat );
272192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   fb->stfb = stw_st_create_framebuffer( fb );
273192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   if (!fb->stfb) {
274192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      FREE( fb );
275192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      return NULL;
276192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   }
277192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu
278192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   fb->refcnt = 1;
27911084d582764a916245ae92437421ac0cacdf335José Fonseca
280c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   /*
281c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca    * Windows can be sometimes have zero width and or height, but we ensure
282c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca    * a non-zero framebuffer size at all times.
283c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca    */
284c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca
285c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   fb->must_resize = TRUE;
286c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   fb->width  = 1;
287c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   fb->height = 1;
288c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   fb->client_rect.left   = 0;
289c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   fb->client_rect.top    = 0;
290c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   fb->client_rect.right  = fb->client_rect.left + fb->width;
291c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca   fb->client_rect.bottom = fb->client_rect.top  + fb->height;
292c636daa1455121d1db5b98bba09dd8004498c3b8José Fonseca
29342882897c67f6c74e67e120e946a95929e6c2065José Fonseca   stw_framebuffer_get_size(fb);
29442882897c67f6c74e67e120e946a95929e6c2065José Fonseca
295fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   pipe_mutex_init( fb->mutex );
296db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca
2971068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   /* This is the only case where we lock the stw_framebuffer::mutex before
2981068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca    * stw_dev::fb_mutex, since no other thread can know about this framebuffer
2991068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca    * and we must prevent any other thread from destroying it before we return.
3001068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca    */
3011068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   pipe_mutex_lock( fb->mutex );
3021068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca
3031068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   pipe_mutex_lock( stw_dev->fb_mutex );
304858d3da441d3548eae23c91b3bc888c3b0233797José Fonseca   fb->next = stw_dev->fb_head;
305858d3da441d3548eae23c91b3bc888c3b0233797José Fonseca   stw_dev->fb_head = fb;
3061068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   pipe_mutex_unlock( stw_dev->fb_mutex );
307858d3da441d3548eae23c91b3bc888c3b0233797José Fonseca
308db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca   return fb;
309db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca}
310db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca
311192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu/**
312192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu * Have ptr reference fb.  The referenced framebuffer should be locked.
313192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu */
314192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wuvoid
315192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wustw_framebuffer_reference(
316192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   struct stw_framebuffer **ptr,
317fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   struct stw_framebuffer *fb)
318fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca{
319192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   struct stw_framebuffer *old_fb = *ptr;
320fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
321192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   if (old_fb == fb)
322192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      return;
3236fd8b9b550713302566bb4c28e49c219870ccfecMichal Krol
324192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   if (fb)
325192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      fb->refcnt++;
326192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   if (old_fb) {
327192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      pipe_mutex_lock(stw_dev->fb_mutex);
328192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu
329192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      pipe_mutex_lock(old_fb->mutex);
330192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      stw_framebuffer_destroy_locked(old_fb);
331192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu
332192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      pipe_mutex_unlock(stw_dev->fb_mutex);
333fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   }
334192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu
335192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   *ptr = fb;
336fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca}
337fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
338fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
33942882897c67f6c74e67e120e946a95929e6c2065José Fonseca/**
34042882897c67f6c74e67e120e946a95929e6c2065José Fonseca * Update the framebuffer's size if necessary.
34142882897c67f6c74e67e120e946a95929e6c2065José Fonseca */
342db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonsecavoid
34342882897c67f6c74e67e120e946a95929e6c2065José Fonsecastw_framebuffer_update(
344fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   struct stw_framebuffer *fb)
345fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca{
346fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   assert(fb->stfb);
34742882897c67f6c74e67e120e946a95929e6c2065José Fonseca   assert(fb->height);
34842882897c67f6c74e67e120e946a95929e6c2065José Fonseca   assert(fb->width);
34942882897c67f6c74e67e120e946a95929e6c2065José Fonseca
35042882897c67f6c74e67e120e946a95929e6c2065José Fonseca   /* XXX: It would be nice to avoid checking the size again -- in theory
35142882897c67f6c74e67e120e946a95929e6c2065José Fonseca    * stw_call_window_proc would have cought the resize and stored the right
35242882897c67f6c74e67e120e946a95929e6c2065José Fonseca    * size already, but unfortunately threads created before the DllMain is
35342882897c67f6c74e67e120e946a95929e6c2065José Fonseca    * called don't get a DLL_THREAD_ATTACH notification, and there is no way
35442882897c67f6c74e67e120e946a95929e6c2065José Fonseca    * to know of their existing without using the not very portable PSAPI.
35542882897c67f6c74e67e120e946a95929e6c2065José Fonseca    */
35642882897c67f6c74e67e120e946a95929e6c2065José Fonseca   stw_framebuffer_get_size(fb);
357fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca}
358fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
359fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
360fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonsecavoid
361fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonsecastw_framebuffer_cleanup( void )
362fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca{
363fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   struct stw_framebuffer *fb;
364fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   struct stw_framebuffer *next;
365fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
366e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca   if (!stw_dev)
367e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca      return;
368e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca
3691068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   pipe_mutex_lock( stw_dev->fb_mutex );
370fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
371fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   fb = stw_dev->fb_head;
372fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   while (fb) {
373fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca      next = fb->next;
3741068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca
3751068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca      pipe_mutex_lock(fb->mutex);
376ea3ee4791eb8b9eefdd40b6ce9bbfc2dc86542bfJosé Fonseca      stw_framebuffer_destroy_locked(fb);
3771068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca
378fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca      fb = next;
379fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   }
380fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   stw_dev->fb_head = NULL;
381fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
3821068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   pipe_mutex_unlock( stw_dev->fb_mutex );
383fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca}
384fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
385fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
386858d3da441d3548eae23c91b3bc888c3b0233797José Fonseca/**
387858d3da441d3548eae23c91b3bc888c3b0233797José Fonseca * Given an hdc, return the corresponding stw_framebuffer.
388db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca */
3891068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonsecastatic INLINE struct stw_framebuffer *
390fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonsecastw_framebuffer_from_hdc_locked(
391db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca   HDC hdc )
392db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca{
393cffe7c8bd0397f8d54e2da16a21c7db4345766b8José Fonseca   HWND hwnd;
394db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca
395cffe7c8bd0397f8d54e2da16a21c7db4345766b8José Fonseca   hwnd = WindowFromDC(hdc);
396c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca   if (!hwnd) {
397c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca      return NULL;
398c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca   }
399fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
400c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca   return stw_framebuffer_from_hwnd_locked(hwnd);
401fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca}
402fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
403fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
404fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca/**
405fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca * Given an hdc, return the corresponding stw_framebuffer.
406fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca */
407fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonsecastruct stw_framebuffer *
408fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonsecastw_framebuffer_from_hdc(
409fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   HDC hdc )
410fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca{
411fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   struct stw_framebuffer *fb;
412fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
413e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca   if (!stw_dev)
414e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca      return NULL;
415e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca
4161068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   pipe_mutex_lock( stw_dev->fb_mutex );
417fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   fb = stw_framebuffer_from_hdc_locked(hdc);
4181068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   pipe_mutex_unlock( stw_dev->fb_mutex );
4191068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca
4201068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   return fb;
4211068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca}
4221068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca
4231068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca
4241068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca/**
4251068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca * Given an hdc, return the corresponding stw_framebuffer.
4261068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca */
4271068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonsecastruct stw_framebuffer *
4281068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonsecastw_framebuffer_from_hwnd(
4291068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   HWND hwnd )
4301068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca{
4311068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   struct stw_framebuffer *fb;
4321068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca
4331068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   pipe_mutex_lock( stw_dev->fb_mutex );
4341068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   fb = stw_framebuffer_from_hwnd_locked(hwnd);
4351068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   pipe_mutex_unlock( stw_dev->fb_mutex );
436858d3da441d3548eae23c91b3bc888c3b0233797José Fonseca
437858d3da441d3548eae23c91b3bc888c3b0233797José Fonseca   return fb;
438db19578b52e7f3d6209568e2e0fa7a7107f42cd4José Fonseca}
43967b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell
44067b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell
44131f1571d1f6e325c16833afbb6e15b61561e5f1fJosé FonsecaBOOL APIENTRY
44231f1571d1f6e325c16833afbb6e15b61561e5f1fJosé FonsecaDrvSetPixelFormat(
443fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   HDC hdc,
44431f1571d1f6e325c16833afbb6e15b61561e5f1fJosé Fonseca   LONG iPixelFormat )
445fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca{
446fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   uint count;
447fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   uint index;
448fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   struct stw_framebuffer *fb;
449fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
450e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca   if (!stw_dev)
451e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca      return FALSE;
452e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca
453fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   index = (uint) iPixelFormat - 1;
4549646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca   count = stw_pixelformat_get_count();
455fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   if (index >= count)
456fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca      return FALSE;
457fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
458fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   fb = stw_framebuffer_from_hdc_locked(hdc);
459fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   if(fb) {
4609646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca      /*
4619646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca       * SetPixelFormat must be called only once.  However ignore
4629646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca       * pbuffers, for which the framebuffer object is created first.
4639646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca       */
4649646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca      boolean bPbuffer = fb->bPbuffer;
4659646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca
4661068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca      stw_framebuffer_release( fb );
4679646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca
4689646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca      return bPbuffer;
469fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   }
470fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
4711068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   fb = stw_framebuffer_create(hdc, iPixelFormat);
472fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   if(!fb) {
473fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca      return FALSE;
474fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   }
475fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
4761068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   stw_framebuffer_release( fb );
477fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
478fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   /* Some applications mistakenly use the undocumented wglSetPixelFormat
479fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca    * function instead of SetPixelFormat, so we call SetPixelFormat here to
480fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca    * avoid opengl32.dll's wglCreateContext to fail */
481fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   if (GetPixelFormat(hdc) == 0) {
4829646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca      BOOL bRet = SetPixelFormat(hdc, iPixelFormat, NULL);
4839646762261d976d34bee8c8b1dcda9656cec655cJosé Fonseca      assert(bRet);
484fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   }
485fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
486fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   return TRUE;
487fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca}
488fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
489fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
490fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonsecaint
491fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonsecastw_pixelformat_get(
492fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   HDC hdc )
493fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca{
4941068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   int iPixelFormat = 0;
495fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   struct stw_framebuffer *fb;
496fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
497fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca   fb = stw_framebuffer_from_hdc(hdc);
4981068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   if(fb) {
4991068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca      iPixelFormat = fb->iPixelFormat;
5001068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca      stw_framebuffer_release(fb);
5011068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   }
502fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
5031068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   return iPixelFormat;
504fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca}
505fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
506fe69b6bdc7bbde2cefec856ff338788d7be20f4eJosé Fonseca
50731f1571d1f6e325c16833afbb6e15b61561e5f1fJosé FonsecaBOOL APIENTRY
5084e5ed05b025b9b6a1a6dabba72fce3d918e77044José FonsecaDrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
50967b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell{
51067b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell   struct stw_framebuffer *fb;
511923b4413a63530be37cd44eed29910db21b39ac6José Fonseca   struct pipe_screen *screen;
5124c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   struct pipe_resource *res;
51367b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell
514e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca   if (!stw_dev)
515e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca      return FALSE;
516e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca
51719068d93c8f0f1d2b8809248266bf6da3dc6abd7José Fonseca   fb = stw_framebuffer_from_hdc( hdc );
51867b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell   if (fb == NULL)
51967b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell      return FALSE;
52067b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell
521923b4413a63530be37cd44eed29910db21b39ac6José Fonseca   screen = stw_dev->screen;
5224e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5234c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   res = (struct pipe_resource *)data->pPrivateData;
524923b4413a63530be37cd44eed29910db21b39ac6José Fonseca
5254e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   if(data->hSharedSurface != fb->hSharedSurface) {
5264e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      if(fb->shared_surface) {
5274e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca         stw_dev->stw_winsys->shared_surface_close(screen, fb->shared_surface);
5284e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca         fb->shared_surface = NULL;
5294e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      }
5304e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5314e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      fb->hSharedSurface = data->hSharedSurface;
5324e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5334e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      if(data->hSharedSurface &&
5344e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca         stw_dev->stw_winsys->shared_surface_open) {
5354e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca         fb->shared_surface = stw_dev->stw_winsys->shared_surface_open(screen, fb->hSharedSurface);
5364e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      }
5374e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   }
5384e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5394e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   if(fb->shared_surface) {
5404e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      stw_dev->stw_winsys->compose(screen,
5414c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   res,
5424e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca                                   fb->shared_surface,
5434e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca                                   &fb->client_rect,
5444e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca                                   data->PresentHistoryToken);
5454e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   }
5464e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   else {
5474c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      stw_dev->stw_winsys->present( screen, res, hdc );
5484e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   }
5494e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
55042882897c67f6c74e67e120e946a95929e6c2065José Fonseca   stw_framebuffer_update(fb);
551192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   stw_notify_current_locked(fb);
5524e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5531068c15c61a6c76a2da04ed3ca136f0d49abed1dJosé Fonseca   stw_framebuffer_release(fb);
5544e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
555b2581dcab41c142c38f2e065c4348cb892931c48José Fonseca   return TRUE;
5564e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca}
5574e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5584e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5594e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca/**
5604e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca * Queue a composition.
5614e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca *
5624e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca * It will drop the lock on success.
5634e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca */
5644e5ed05b025b9b6a1a6dabba72fce3d918e77044José FonsecaBOOL
5654e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonsecastw_framebuffer_present_locked(HDC hdc,
5664e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca                               struct stw_framebuffer *fb,
5674c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                               struct pipe_resource *res)
5684e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca{
5694e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   if(stw_dev->callbacks.wglCbPresentBuffers &&
5704e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      stw_dev->stw_winsys->compose) {
5714e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      GLCBPRESENTBUFFERSDATA data;
5724e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5734e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      memset(&data, 0, sizeof data);
5744e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      data.magic1 = 2;
5754e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      data.magic2 = 0;
5764e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      data.AdapterLuid = stw_dev->AdapterLuid;
5774e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      data.rect = fb->client_rect;
5784c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      data.pPrivateData = (void *)res;
5794e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
580192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      stw_notify_current_locked(fb);
5814e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      stw_framebuffer_release(fb);
5824e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5834e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      return stw_dev->callbacks.wglCbPresentBuffers(hdc, &data);
5844e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   }
5854e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   else {
5864e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      struct pipe_screen *screen = stw_dev->screen;
5874e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5884c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      stw_dev->stw_winsys->present( screen, res, hdc );
5894e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5904e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      stw_framebuffer_update(fb);
591192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu      stw_notify_current_locked(fb);
5924e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      stw_framebuffer_release(fb);
5934e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5944e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      return TRUE;
5954e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   }
5964e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca}
5974e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5984e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
5994e5ed05b025b9b6a1a6dabba72fce3d918e77044José FonsecaBOOL APIENTRY
6004e5ed05b025b9b6a1a6dabba72fce3d918e77044José FonsecaDrvSwapBuffers(
6014e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   HDC hdc )
6024e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca{
6034e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   struct stw_framebuffer *fb;
6044e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
605e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca   if (!stw_dev)
606e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca      return FALSE;
607e6b66210def2c10f703c2a990b9652ea5419ebbeJosé Fonseca
6084e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   fb = stw_framebuffer_from_hdc( hdc );
6094e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   if (fb == NULL)
6104e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      return FALSE;
6114e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
6124e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   if (!(fb->pfi->pfd.dwFlags & PFD_DOUBLEBUFFER)) {
6134e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      stw_framebuffer_release(fb);
6144e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca      return TRUE;
6154e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca   }
6164e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
617192f06adca5e79b4824d92dc41186592ed57f71eChia-I Wu   stw_flush_current_locked(fb);
6184e5ed05b025b9b6a1a6dabba72fce3d918e77044José Fonseca
619c3c1976f522a67be6a0619e938a90cf186ad42e6José Fonseca   return stw_st_swap_framebuffer_locked(hdc, fb->stfb);
62067b6e5b907096ce9eee32c36c164acd38574cf14Keith Whitwell}
6214bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca
6224bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9dJosé Fonseca
62331f1571d1f6e325c16833afbb6e15b61561e5f1fJosé FonsecaBOOL APIENTRY
62431f1571d1f6e325c16833afbb6e15b61561e5f1fJosé FonsecaDrvSwapLayerBuffers(
6251ed90091be0a79977eb6c055ba1da56114d52f53José Fonseca   HDC hdc,
6261ed90091be0a79977eb6c055ba1da56114d52f53José Fonseca   UINT fuPlanes )
6271ed90091be0a79977eb6c055ba1da56114d52f53José Fonseca{
6281ed90091be0a79977eb6c055ba1da56114d52f53José Fonseca   if(fuPlanes & WGL_SWAP_MAIN_PLANE)
62931f1571d1f6e325c16833afbb6e15b61561e5f1fJosé Fonseca      return DrvSwapBuffers(hdc);
6301ed90091be0a79977eb6c055ba1da56114d52f53José Fonseca
6311ed90091be0a79977eb6c055ba1da56114d52f53José Fonseca   return FALSE;
6321ed90091be0a79977eb6c055ba1da56114d52f53José Fonseca}
633