xref: /reactos/dll/opengl/opengl32/swimpl.c (revision 84344399)
1 /*
2  * COPYRIGHT:            See COPYING in the top level directory
3  * PROJECT:              ReactOS
4  * FILE:                 dll/opengl/opengl32/swimpl.c
5  * PURPOSE:              OpenGL32 DLL, opengl software implementation
6  */
7 
8 #include "opengl32.h"
9 
10 /* MESA includes */
11 #include <context.h>
12 #include <matrix.h>
13 
14 WINE_DEFAULT_DEBUG_CHANNEL(opengl32);
15 
16 #define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3)
17 #define WIDTH_BYTES_ALIGN16(cx, bpp) ((((cx) * (bpp) + 15) & ~15) >> 3)
18 
19 /* Flags for our pixel formats */
20 #define SB_FLAGS            (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT)
21 #define SB_FLAGS_WINDOW     (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT)
22 #define SB_FLAGS_PALETTE    (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT | PFD_NEED_PALETTE)
23 #define DB_FLAGS            (PFD_DOUBLEBUFFER   | PFD_SWAP_COPY   | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT)
24 #define DB_FLAGS_PALETTE    (PFD_DOUBLEBUFFER   | PFD_SWAP_COPY   | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT | PFD_NEED_PALETTE)
25 
26 
27 struct pixel_format
28 {
29     DWORD dwFlags;
30     BYTE iPixelType;
31     BYTE cColorBits;
32     BYTE cRedBits; BYTE cRedShift;
33     BYTE cGreenBits; BYTE cGreenShift;
34     BYTE cBlueBits; BYTE cBlueShift;
35     BYTE cAlphaBits; BYTE cAlphaShift;
36     BYTE cAccumBits;
37     BYTE cAccumRedBits; BYTE cAccumGreenBits; BYTE cAccumBlueBits; BYTE cAccumAlphaBits;
38     BYTE cDepthBits;
39 };
40 
41 static const struct pixel_format pixel_formats_32[] =
42 {
43     /* 32bpp */
44     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  32},
45     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  16},
46     {DB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  32},
47     {DB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  16},
48     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32},
49     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16},
50     {DB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32},
51     {DB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16},
52     {SB_FLAGS_WINDOW,  PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  32},
53     {SB_FLAGS_WINDOW,  PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  16},
54     {DB_FLAGS,         PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  32},
55     {DB_FLAGS,         PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  16},
56     /* 24bpp */
57     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  32},
58     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  16},
59     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32},
60     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16},
61     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  32},
62     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  16},
63     /* 16 bpp */
64     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0,  32},
65     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0,  16},
66     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8,  8,  8,  8,  32},
67     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8,  8,  8,  8,  16},
68     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0,  0,  0,  0,  0,  32},
69     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0,  0,  0,  0,  0,  16},
70     /* 8bpp */
71     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0,  32},
72     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0,  16},
73     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 8, 0, 32, 8,  8,  8,  8,  32},
74     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 8, 0, 32, 8,  8,  8,  8,  16},
75     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 8,  3, 0,  3, 3, 2, 6, 0, 0, 0,  0,  0,  0,  0,  32},
76     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 8,  3, 0,  3, 3, 2, 6, 0, 0, 0,  0,  0,  0,  0,  16},
77     /* 4bpp */
78     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 0, 0, 16, 5,  6,  5,  0,  32},
79     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 0, 0, 16, 5,  6,  5,  0,  16},
80     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 8, 0, 16, 4,  4,  4,  4,  32},
81     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 8, 0, 16, 4,  4,  4,  4,  16},
82     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 4,  1, 0,  1, 1, 1, 2, 0, 0, 0,  0,  0,  0,  0,  32},
83     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 4,  1, 0,  1, 1, 1, 2, 0, 0, 0,  0,  0,  0,  0,  16},
84 };
85 
86 static const struct pixel_format pixel_formats_24[] =
87 {
88     /* 24bpp */
89     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  32},
90     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  16},
91     {DB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  32},
92     {DB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  16},
93     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32},
94     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16},
95     {DB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32},
96     {DB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16},
97     {SB_FLAGS_WINDOW,  PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  32},
98     {SB_FLAGS_WINDOW,  PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  16},
99     {DB_FLAGS,         PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  32},
100     {DB_FLAGS,         PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  16},
101     /* 32bpp */
102     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  32},
103     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  16},
104     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32},
105     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16},
106     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  32},
107     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  16},
108     /* 16 bpp */
109     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0,  32},
110     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0,  16},
111     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8,  8,  8,  8,  32},
112     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8,  8,  8,  8,  16},
113     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0,  0,  0,  0,  0,  32},
114     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0,  0,  0,  0,  0,  16},
115     /* 8bpp */
116     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0,  32},
117     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0,  16},
118     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 8, 0, 32, 8,  8,  8,  8,  32},
119     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 8, 0, 32, 8,  8,  8,  8,  16},
120     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 8,  3, 0,  3, 3, 2, 6, 0, 0, 0,  0,  0,  0,  0,  32},
121     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 8,  3, 0,  3, 3, 2, 6, 0, 0, 0,  0,  0,  0,  0,  16},
122     /* 4bpp */
123     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 0, 0, 16, 5,  6,  5,  0,  32},
124     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 0, 0, 16, 5,  6,  5,  0,  16},
125     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 8, 0, 16, 4,  4,  4,  4,  32},
126     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 8, 0, 16, 4,  4,  4,  4,  16},
127     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 4,  1, 0,  1, 1, 1, 2, 0, 0, 0,  0,  0,  0,  0,  32},
128     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 4,  1, 0,  1, 1, 1, 2, 0, 0, 0,  0,  0,  0,  0,  16},
129 };
130 
131 static const struct pixel_format pixel_formats_16[] =
132 {
133     /* 16 bpp - 565 */
134     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       16, 5, 11, 6, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0,  32},
135     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       16, 5, 11, 6, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0,  16},
136     {DB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 11, 6, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0,  32},
137     {DB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 11, 6, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0,  16},
138     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       16, 5, 11, 6, 5, 5, 0, 8, 0, 32, 8,  8,  8,  8,  32},
139     {SB_FLAGS_WINDOW,  PFD_TYPE_RGBA,       16, 5, 11, 6, 5, 5, 0, 8, 0, 32, 8,  8,  8,  8,  16},
140     {DB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 11, 6, 5, 5, 0, 8, 0, 32, 8,  8,  8,  8,  32},
141     {DB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 11, 6, 5, 5, 0, 8, 0, 32, 8,  8,  8,  8,  16},
142     {SB_FLAGS_WINDOW,  PFD_TYPE_COLORINDEX, 16, 5, 11, 6, 5, 5, 0, 0, 0, 0,  0,  0,  0,  0,  32},
143     {SB_FLAGS_WINDOW,  PFD_TYPE_COLORINDEX, 16, 5, 11, 6, 5, 5, 0, 0, 0, 0,  0,  0,  0,  0,  16},
144     {DB_FLAGS,         PFD_TYPE_COLORINDEX, 16, 5, 11, 6, 5, 5, 0, 0, 0, 0,  0,  0,  0,  0,  32},
145     {DB_FLAGS,         PFD_TYPE_COLORINDEX, 16, 5, 11, 6, 5, 5, 0, 0, 0, 0,  0,  0,  0,  0,  16},
146     /* 24bpp */
147     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  32},
148     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  16},
149     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32},
150     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16},
151     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  32},
152     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  16},
153     /* 32bpp */
154     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  32},
155     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  16},
156     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32},
157     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16},
158     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  32},
159     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  16},
160     /* 8bpp */
161     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0,  32},
162     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0,  16},
163     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 8, 0, 32, 8,  8,  8,  8,  32},
164     {SB_FLAGS,         PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 8, 0, 32, 8,  8,  8,  8,  16},
165     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 8,  3, 0,  3, 3, 2, 6, 0, 0, 0,  0,  0,  0,  0,  32},
166     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 8,  3, 0,  3, 3, 2, 6, 0, 0, 0,  0,  0,  0,  0,  16},
167     /* 4bpp */
168     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 0, 0, 16, 5,  6,  5,  0,  32},
169     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 0, 0, 16, 5,  6,  5,  0,  16},
170     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 8, 0, 16, 4,  4,  4,  4,  32},
171     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 8, 0, 16, 4,  4,  4,  4,  16},
172     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 4,  1, 0,  1, 1, 1, 2, 0, 0, 0,  0,  0,  0,  0,  32},
173     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 4,  1, 0,  1, 1, 1, 2, 0, 0, 0,  0,  0,  0,  0,  16},
174 };
175 
176 static const struct pixel_format pixel_formats_8[] =
177 {
178     /* 8bpp */
179     {SB_FLAGS_PALETTE, PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0,  32},
180     {SB_FLAGS_PALETTE, PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0,  16},
181     {DB_FLAGS_PALETTE, PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0,  32},
182     {DB_FLAGS_PALETTE, PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0,  16},
183     {SB_FLAGS_PALETTE, PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 8, 0, 32, 8,  8,  8,  8,  32},
184     {SB_FLAGS_PALETTE, PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 8, 0, 32, 8,  8,  8,  8,  16},
185     {DB_FLAGS_PALETTE, PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 8, 0, 32, 8,  8,  8,  8,  32},
186     {DB_FLAGS_PALETTE, PFD_TYPE_RGBA,       8,  3, 0,  3, 3, 2, 6, 8, 0, 32, 8,  8,  8,  8,  16},
187     {SB_FLAGS_WINDOW,  PFD_TYPE_COLORINDEX, 8,  3, 0,  3, 3, 2, 6, 0, 0, 0,  0,  0,  0,  0,  32},
188     {SB_FLAGS_WINDOW,  PFD_TYPE_COLORINDEX, 8,  3, 0,  3, 3, 2, 6, 0, 0, 0,  0,  0,  0,  0,  16},
189     {DB_FLAGS,         PFD_TYPE_COLORINDEX, 8,  3, 0,  3, 3, 2, 6, 0, 0, 0,  0,  0,  0,  0,  32},
190     {DB_FLAGS,         PFD_TYPE_COLORINDEX, 8,  3, 0,  3, 3, 2, 6, 0, 0, 0,  0,  0,  0,  0,  16},
191     /* 24bpp */
192     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  32},
193     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  16},
194     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32},
195     {SB_FLAGS,         PFD_TYPE_RGBA,       24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16},
196     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  32},
197     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  16},
198     /* 32bpp */
199     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  32},
200     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0,  16},
201     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32},
202     {SB_FLAGS,         PFD_TYPE_RGBA,       32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16},
203     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  32},
204     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0,  0,  0,  0,  0,  16},
205     /* 16 bpp */
206     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0,  32},
207     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0,  16},
208     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8,  8,  8,  8,  32},
209     {SB_FLAGS,         PFD_TYPE_RGBA,       16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8,  8,  8,  8,  16},
210     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0,  0,  0,  0,  0,  32},
211     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0,  0,  0,  0,  0,  16},
212     /* 4bpp */
213     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 0, 0, 16, 5,  6,  5,  0,  32},
214     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 0, 0, 16, 5,  6,  5,  0,  16},
215     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 8, 0, 16, 4,  4,  4,  4,  32},
216     {SB_FLAGS,         PFD_TYPE_RGBA,       4,  1, 0,  1, 1, 1, 2, 8, 0, 16, 4,  4,  4,  4,  16},
217     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 4,  1, 0,  1, 1, 1, 2, 0, 0, 0,  0,  0,  0,  0,  32},
218     {SB_FLAGS,         PFD_TYPE_COLORINDEX, 4,  1, 0,  1, 1, 1, 2, 0, 0, 0,  0,  0,  0,  0,  16},
219 };
220 
221 struct sw_framebuffer
222 {
223     GLvisual *gl_visual;        /* Describes the buffers */
224     GLframebuffer *gl_buffer;   /* Depth, stencil, accum, etc buffers */
225 
226     const struct pixel_format* pixel_format;
227     HDC Hdc;
228 
229     /* Current width/height */
230     GLuint width; GLuint height;
231 
232     /* BackBuffer, if any */
233     BYTE* BackBuffer;
234 };
235 
236 struct sw_context
237 {
238     GLcontext *gl_ctx;          /* The core GL/Mesa context */
239 
240     /* This is to keep track of the size of the front buffer */
241     HHOOK hook;
242 
243     /* Our frame buffer*/
244     struct sw_framebuffer* fb;
245 
246     /* State variables */
247     union
248     {
249         struct
250         {
251             BYTE ClearColor;
252             BYTE CurrentColor;
253         } u8;
254         struct
255         {
256             USHORT ClearColor;
257             USHORT CurrentColor;
258         } u16;
259         struct
260         {
261             ULONG ClearColor;
262             ULONG CurrentColor;
263         } u24;
264         struct
265         {
266             ULONG ClearColor;
267             ULONG CurrentColor;
268         } u32;
269     };
270     GLenum Mode;
271 };
272 
273 /* WGL <-> mesa glue */
274 static const struct pixel_format* get_format(INT pf_index, INT* pf_count)
275 {
276     HDC hdc;
277     INT bpp, nb_format;
278     const struct pixel_format* ret;
279 
280     hdc = GetDC(NULL);
281     bpp = GetDeviceCaps(hdc, BITSPIXEL);
282     ReleaseDC(NULL, hdc);
283 
284     switch (bpp)
285     {
286 #define HANDLE_BPP(__x__)                               \
287     case __x__:                                         \
288         nb_format = ARRAYSIZE(pixel_formats_##__x__);   \
289         if ((pf_index > nb_format) || (pf_index <= 0))  \
290             ret = NULL;                                 \
291         else                                            \
292             ret = &pixel_formats_##__x__[pf_index - 1]; \
293     break
294 
295     HANDLE_BPP(32);
296     HANDLE_BPP(24);
297     HANDLE_BPP(16);
298     HANDLE_BPP(8);
299 #undef HANDLE_BPP
300     default:
301         FIXME("Unhandled bit depth %u, defaulting to 32bpp\n", bpp);
302         nb_format = ARRAYSIZE(pixel_formats_32);
303         if ((pf_index > nb_format) || (pf_index == 0))
304             ret = NULL;
305         else
306             ret = &pixel_formats_32[pf_index - 1];
307     }
308 
309     if (pf_count)
310         *pf_count = nb_format;
311 
312     return ret;
313 }
314 
315 INT sw_DescribePixelFormat(HDC hdc, INT format, UINT size, PIXELFORMATDESCRIPTOR* descr)
316 {
317     INT ret;
318     const struct pixel_format *pixel_format;
319 
320     TRACE("Describing format %i.\n", format);
321 
322     pixel_format = get_format(format, &ret);
323     if(!descr)
324         return ret;
325     if((format > ret) || (size != sizeof(*descr)))
326         return 0;
327 
328     /* Fill the structure */
329     descr->nSize            = sizeof(*descr);
330     descr->nVersion         = 1;
331     descr->dwFlags          = pixel_format->dwFlags;
332     descr->iPixelType       = pixel_format->iPixelType;
333     descr->cColorBits       = pixel_format->cColorBits;
334     descr->cRedBits         = pixel_format->cRedBits;
335     descr->cRedShift        = pixel_format->cRedShift;
336     descr->cGreenBits       = pixel_format->cGreenBits;
337     descr->cGreenShift      = pixel_format->cGreenShift;
338     descr->cBlueBits        = pixel_format->cBlueBits;
339     descr->cBlueShift       = pixel_format->cBlueShift;
340     descr->cAlphaBits       = pixel_format->cAlphaBits;
341     descr->cAlphaShift      = pixel_format->cAlphaShift;
342     descr->cAccumBits       = pixel_format->cAccumBits;
343     descr->cAccumRedBits    = pixel_format->cAccumRedBits;
344     descr->cAccumGreenBits  = pixel_format->cAccumGreenBits;
345     descr->cAccumBlueBits   = pixel_format->cAccumBlueBits;
346     descr->cAccumAlphaBits  = pixel_format->cAccumAlphaBits;
347     descr->cDepthBits       = pixel_format->cDepthBits;
348     descr->cStencilBits     = STENCIL_BITS;
349     descr->cAuxBuffers      = 0;
350     descr->iLayerType       = PFD_MAIN_PLANE;
351     descr->bReserved        = 0;
352     descr->dwLayerMask      = 0;
353     descr->dwVisibleMask    = 0;
354     descr->dwDamageMask     = 0;
355 
356     return ret;
357 }
358 
359 BOOL sw_SetPixelFormat(HDC hdc, struct wgl_dc_data* dc_data, INT format)
360 {
361     struct sw_framebuffer* fb;
362     const struct pixel_format *pixel_format;
363 
364     /* So, someone is crazy enough to ask for sw implementation. Announce it. */
365     TRACE("OpenGL software implementation START for hdc %p, format %i!\n", hdc, format);
366 
367     pixel_format = get_format(format, NULL);
368     if (!pixel_format)
369         return FALSE;
370 
371     /* allocate our structure */
372     fb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*fb));
373     if(!fb)
374     {
375         ERR("HeapAlloc FAILED!\n");
376         return FALSE;
377     }
378     /* Set the format */
379     fb->pixel_format = pixel_format;
380 
381     fb->gl_visual = gl_create_visual(
382             pixel_format->iPixelType == PFD_TYPE_RGBA,
383             pixel_format->cAlphaBits != 0,
384             (pixel_format->dwFlags & PFD_DOUBLEBUFFER) != 0,
385             pixel_format->cDepthBits,
386             STENCIL_BITS,
387             max(max(max(pixel_format->cAccumRedBits, pixel_format->cAccumGreenBits), pixel_format->cAccumBlueBits), pixel_format->cAccumAlphaBits),
388             pixel_format->iPixelType == PFD_TYPE_COLORINDEX ? pixel_format->cColorBits : 0,
389             ((1ul << pixel_format->cRedBits) - 1),
390             ((1ul << pixel_format->cGreenBits) - 1),
391             ((1ul << pixel_format->cBlueBits) - 1),
392             pixel_format->cAlphaBits != 0 ? ((1ul << pixel_format->cAlphaBits) - 1) : 255.0f,
393             pixel_format->cRedBits,
394             pixel_format->cGreenBits,
395             pixel_format->cBlueBits,
396             pixel_format->cAlphaBits);
397 
398     if(!fb->gl_visual)
399     {
400         ERR("Failed to allocate a GL visual.\n");
401         HeapFree(GetProcessHeap(), 0, fb);
402         return FALSE;
403     }
404 
405     /* Allocate the framebuffer structure */
406     fb->gl_buffer = gl_create_framebuffer(fb->gl_visual);
407     if (!fb->gl_buffer) {
408         ERR("Failed to allocate the mesa framebuffer structure.\n");
409         gl_destroy_visual( fb->gl_visual );
410         HeapFree(GetProcessHeap(), 0, fb);
411         return FALSE;
412     }
413 
414     /* Save our DC */
415     fb->Hdc = hdc;
416 
417     /* Everything went fine */
418     dc_data->sw_data = fb;
419     return TRUE;
420 }
421 
422 DHGLRC sw_CreateContext(struct wgl_dc_data* dc_data)
423 {
424     struct sw_context* sw_ctx;
425     struct sw_framebuffer* fb = dc_data->sw_data;
426 
427     sw_ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sw_ctx));
428     if(!sw_ctx)
429         return NULL;
430 
431     /* Initialize the context */
432     sw_ctx->gl_ctx = gl_create_context(fb->gl_visual, NULL, sw_ctx);
433     if(!sw_ctx->gl_ctx)
434     {
435         ERR("Failed to initialize the mesa context.\n");
436         HeapFree(GetProcessHeap(), 0, sw_ctx);
437         return NULL;
438     }
439 
440     sw_ctx->fb = fb;
441 
442     /* Choose relevant default */
443     sw_ctx->Mode = fb->gl_visual->DBflag ? GL_BACK : GL_FRONT;
444 
445     return (DHGLRC)sw_ctx;
446 }
447 
448 BOOL sw_DeleteContext(DHGLRC dhglrc)
449 {
450     struct sw_context* sw_ctx = (struct sw_context*)dhglrc;
451     /* Those get clobbered by _mesa_free_context_data via _glapi_set{context,dispath_table} */
452     void* icd_save = IntGetCurrentICDPrivate();
453     const GLDISPATCHTABLE* table_save = IntGetCurrentDispatchTable();
454 
455     /* Destroy everything */
456     gl_destroy_context(sw_ctx->gl_ctx);
457 
458     HeapFree(GetProcessHeap(), 0, sw_ctx);
459 
460     /* Restore this */
461     IntSetCurrentDispatchTable(table_save);
462     IntSetCurrentICDPrivate(icd_save);
463 
464     return TRUE;
465 }
466 
467 extern void APIENTRY _mesa_ColorTableEXT(GLenum, GLenum, GLsizei, GLenum, GLenum, const void*);
468 extern void APIENTRY _mesa_ColorSubTableEXT(GLenum, GLsizei, GLsizei, GLenum, GLenum, const void*);
469 extern void APIENTRY _mesa_GetColorTableEXT(GLenum, GLenum, GLenum, void*);
470 extern void APIENTRY _mesa_GetColorTableParameterivEXT(GLenum, GLenum, GLfloat*);
471 extern void APIENTRY _mesa_GetColorTableParameterfvEXT(GLenum, GLenum, GLint*);
472 
473 static void APIENTRY _swimpl_AddSwapHintRectWIN(GLint x, GLint y, GLsizei width, GLsizei height)
474 {
475     UNIMPLEMENTED;
476 }
477 
478 PROC sw_GetProcAddress(LPCSTR name)
479 {
480     /* GL_EXT_paletted_texture */
481     if (strcmp(name, "glColorTableEXT") == 0)
482         return (PROC)_mesa_ColorTableEXT;
483     if (strcmp(name, "glColorSubTableEXT") == 0)
484         return (PROC)_mesa_ColorSubTableEXT;
485     if (strcmp(name, "glColorGetTableEXT") == 0)
486         return (PROC)_mesa_GetColorTableEXT;
487     if (strcmp(name, "glGetColorTableParameterivEXT") == 0)
488         return (PROC)_mesa_GetColorTableParameterivEXT;
489     if (strcmp(name, "glGetColorTableParameterfvEXT") == 0)
490         return (PROC)_mesa_GetColorTableParameterfvEXT;
491     if (strcmp(name, "glAddSwapHintRectWIN") == 0)
492         return (PROC)_swimpl_AddSwapHintRectWIN;
493 
494     WARN("Asking for proc address %s, returning NULL.\n", name);
495     return NULL;
496 }
497 
498 BOOL sw_CopyContext(DHGLRC dhglrcSrc, DHGLRC dhglrcDst, UINT mask)
499 {
500     FIXME("Software wglCopyContext is UNIMPLEMENTED, mask %lx.\n", mask);
501     return FALSE;
502 }
503 
504 BOOL sw_ShareLists(DHGLRC dhglrcSrc, DHGLRC dhglrcDst)
505 {
506 #if 0
507     struct sw_context* sw_ctx_src = (struct sw_context*)dhglrcSrc;
508     struct sw_context* sw_ctx_dst = (struct sw_context*)dhglrcDst;
509 
510     /* See if it was already shared */
511     if(sw_ctx_dst->gl_ctx->Shared->RefCount > 1)
512         return FALSE;
513 
514     /* Unreference the old, share the new */
515     gl_reference_shared_state(sw_ctx_dst->gl_ctx,
516         &sw_ctx_dst->gl_ctx->Shared,
517         sw_ctx_src->gl_ctx->Shared);
518 #endif
519     FIXME("Unimplemented!\n");
520     return TRUE;
521 }
522 
523 static
524 LRESULT CALLBACK
525 sw_call_window_proc(
526    int nCode,
527    WPARAM wParam,
528    LPARAM lParam )
529 {
530     struct wgl_dc_data* dc_data = IntGetCurrentDcData();
531     struct sw_context* ctx = (struct sw_context*)IntGetCurrentDHGLRC();
532     PCWPSTRUCT pParams = (PCWPSTRUCT)lParam;
533 
534     if((!dc_data) || (!ctx))
535         return 0;
536 
537     if(!(dc_data->flags & WGL_DC_OBJ_DC))
538         return 0;
539 
540     if((nCode < 0) || (dc_data->owner.hwnd != pParams->hwnd) || (dc_data->sw_data == NULL))
541         return CallNextHookEx(ctx->hook, nCode, wParam, lParam);
542 
543     if (pParams->message == WM_WINDOWPOSCHANGED)
544     {
545         /* We handle WM_WINDOWPOSCHANGED instead of WM_SIZE because according to
546          * http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx
547          * WM_SIZE is generated from WM_WINDOWPOSCHANGED by DefWindowProc so it
548          * can be masked out by the application. */
549         LPWINDOWPOS lpWindowPos = (LPWINDOWPOS)pParams->lParam;
550         if((lpWindowPos->flags & SWP_SHOWWINDOW) ||
551             !(lpWindowPos->flags & SWP_NOMOVE) ||
552             !(lpWindowPos->flags & SWP_NOSIZE))
553         {
554             /* Size in WINDOWPOS includes the window frame, so get the size
555              * of the client area via GetClientRect.  */
556             RECT client_rect;
557             UINT width, height;
558 
559             TRACE("Got WM_WINDOWPOSCHANGED\n");
560 
561             GetClientRect(pParams->hwnd, &client_rect);
562             width = client_rect.right - client_rect.left;
563             height = client_rect.bottom - client_rect.top;
564             /* Do not reallocate for minimized windows */
565             if(width <= 0 || height <= 0)
566                 goto end;
567             /* Propagate to mesa */
568             gl_ResizeBuffersMESA(ctx->gl_ctx);
569         }
570     }
571 
572 end:
573     return CallNextHookEx(ctx->hook, nCode, wParam, lParam);
574 }
575 
576 static const char* renderer_string(void)
577 {
578     return "ReactOS SW Implementation";
579 }
580 
581 static inline void PUT_PIXEL_8(BYTE* Buffer, BYTE Value)
582 {
583     *Buffer = Value;
584 }
585 static inline void PUT_PIXEL_16(USHORT* Buffer, USHORT Value)
586 {
587     *Buffer = Value;
588 }
589 static inline void PUT_PIXEL_24(ULONG* Buffer, ULONG Value)
590 {
591     *Buffer &= 0xFF000000ul;
592     *Buffer |= Value & 0x00FFFFFF;
593 }
594 static inline void PUT_PIXEL_32(ULONG* Buffer, ULONG Value)
595 {
596     *Buffer = Value;
597 }
598 
599 static inline BYTE GET_PIXEL_8(BYTE* Buffer)
600 {
601     return *Buffer;
602 }
603 
604 static inline USHORT GET_PIXEL_16(USHORT* Buffer)
605 {
606     return *Buffer;
607 }
608 
609 static inline ULONG GET_PIXEL_24(ULONG* Buffer)
610 {
611     return *Buffer & 0x00FFFFFF;
612 }
613 
614 static inline ULONG GET_PIXEL_32(ULONG* Buffer)
615 {
616     return *Buffer;
617 }
618 
619 static inline BYTE PACK_COLOR_8(GLubyte r, GLubyte g, GLubyte b)
620 {
621     return (r & 0x7) | ((g & 0x7) << 3) | ((b & 0x3) << 6);
622 }
623 
624 static inline USHORT PACK_COLOR_16(GLubyte r, GLubyte g, GLubyte b)
625 {
626     return ((r & 0x1F) << 11) | ((g & 0x3F) << 5) | (b & 0x1F);
627 }
628 
629 static inline ULONG PACK_COLOR_24(GLubyte r, GLubyte g, GLubyte b)
630 {
631     return (r << 16) | (g << 8) | (b);
632 }
633 
634 static inline ULONG PACK_COLOR_32(GLubyte r, GLubyte g, GLubyte b)
635 {
636     return (r << 16) | (g << 8) | (b);
637 }
638 
639 static inline COLORREF PACK_COLORREF_8(GLubyte r, GLubyte g, GLubyte b)
640 {
641     return RGB(r << 5, g << 5, b << 6);
642 }
643 
644 static inline COLORREF PACK_COLORREF_16(GLubyte r, GLubyte g, GLubyte b)
645 {
646     return RGB(r << 3, g << 2, b << 3);
647 }
648 
649 static inline COLORREF PACK_COLORREF_24(GLubyte r, GLubyte g, GLubyte b)
650 {
651     return RGB(r, g, b);
652 }
653 
654 static inline COLORREF PACK_COLORREF_32(GLubyte r, GLubyte g, GLubyte b)
655 {
656     return RGB(r, g, b);
657 }
658 
659 static inline void UNPACK_COLOR_8(BYTE Color, GLubyte* r, GLubyte* g, GLubyte* b)
660 {
661     *r = Color & 0x7;
662     *g = (Color >> 3) & 0x7;
663     *b = (Color >> 6) & 0x3;
664 }
665 
666 static inline void UNPACK_COLOR_16(USHORT Color, GLubyte* r, GLubyte* g, GLubyte* b)
667 {
668     *r = (Color >> 11) & 0x1F;
669     *g = (Color >> 5) & 0x3F;
670     *b = Color & 0x1F;
671 }
672 
673 static inline void UNPACK_COLOR_24(ULONG Color, GLubyte* r, GLubyte* g, GLubyte* b)
674 {
675     *r = (Color >> 16) & 0xFF;
676     *g = (Color >> 8) & 0xFF;
677     *b = Color & 0xFF;
678 }
679 
680 static inline void UNPACK_COLOR_32(ULONG Color, GLubyte* r, GLubyte* g, GLubyte* b)
681 {
682     *r = (Color >> 16) & 0xFF;
683     *g = (Color >> 8) & 0xFF;
684     *b = Color & 0xFF;
685 }
686 
687 static inline void UNPACK_COLORREF_8(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b)
688 {
689     *r = GetRValue(Color) >> 5;
690     *g = GetGValue(Color) >> 5;
691     *b = GetBValue(Color) >> 6;
692 }
693 
694 static inline void UNPACK_COLORREF_16(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b)
695 {
696     *r = GetRValue(Color) >> 3;
697     *g = GetGValue(Color) >> 2;
698     *b = GetBValue(Color) >> 3;
699 }
700 
701 static inline void UNPACK_COLORREF_24(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b)
702 {
703     *r = GetRValue(Color);
704     *g = GetGValue(Color);
705     *b = GetBValue(Color);
706 }
707 
708 static inline void UNPACK_COLORREF_32(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b)
709 {
710     *r = GetRValue(Color);
711     *g = GetGValue(Color);
712     *b = GetBValue(Color);
713 }
714 
715 #define MAKE_COLORREF(__bpp, __type)                                                            \
716 static inline COLORREF MAKE_COLORREF_##__bpp(const struct pixel_format *format, __type Color)   \
717 {                                                                                               \
718     GLubyte r,g,b;                                                                              \
719                                                                                                 \
720     if (format->iPixelType == PFD_TYPE_COLORINDEX)                                              \
721         return PALETTEINDEX(Color);                                                             \
722                                                                                                 \
723     UNPACK_COLOR_##__bpp(Color, &r, &g, &b);                                                    \
724                                                                                                 \
725     return PACK_COLORREF_##__bpp(r, g, b);                                                      \
726 }
727 MAKE_COLORREF(8, BYTE)
728 MAKE_COLORREF(16, USHORT)
729 MAKE_COLORREF(24, ULONG)
730 MAKE_COLORREF(32, ULONG)
731 #undef MAKE_COLORREF
732 
733 /*
734 * Set the color index used to clear the color buffer.
735 */
736 #define CLEAR_INDEX(__bpp, __type)                              \
737 static void clear_index_##__bpp(GLcontext* ctx, GLuint index)   \
738 {                                                               \
739     struct sw_context* sw_ctx = ctx->DriverCtx;                 \
740                                                                 \
741     sw_ctx->u##__bpp.ClearColor = (__type)index;                \
742 }
743 CLEAR_INDEX(8, BYTE)
744 CLEAR_INDEX(16, USHORT)
745 CLEAR_INDEX(24, ULONG)
746 CLEAR_INDEX(32, ULONG)
747 #undef CLEAR_INDEX
748 
749 /*
750 * Set the color used to clear the color buffer.
751 */
752 #define CLEAR_COLOR(__bpp)                                                                 \
753 static void clear_color_##__bpp( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )   \
754 {                                                                                               \
755     struct sw_context* sw_ctx = ctx->DriverCtx;                                                 \
756                                                                                                 \
757     sw_ctx->u##__bpp.ClearColor = PACK_COLOR_##__bpp(r, g, b);                                  \
758                                                                                                 \
759     TRACE("Set Clear color %u, %u, %u.\n", r, g, b);                                            \
760 }
761 CLEAR_COLOR(8)
762 CLEAR_COLOR(16)
763 CLEAR_COLOR(24)
764 CLEAR_COLOR(32)
765 #undef CLEAR_COLOR
766 
767 /*
768  * Clear the specified region of the color buffer using the clear color
769  * or index as specified by one of the two functions above.
770  */
771 static void clear_frontbuffer(
772     struct sw_context* sw_ctx,
773     struct sw_framebuffer* fb,
774     GLint x,
775     GLint y,
776     GLint width,
777     GLint height,
778     COLORREF ClearColor)
779 {
780     HBRUSH Brush;
781     BOOL ret;
782 
783     TRACE("Clearing front buffer (%u, %u, %u, %u), color 0x%08x.\n", x, y, width, height, ClearColor);
784 
785     Brush = CreateSolidBrush(ClearColor);
786     Brush = SelectObject(fb->Hdc, Brush);
787 
788     ret = PatBlt(fb->Hdc, x, fb->height - (y + height), width, height, PATCOPY);
789     if (!ret)
790     {
791         ERR("PatBlt failed. last Error %d.\n", GetLastError());
792     }
793 
794     Brush = SelectObject(fb->Hdc, Brush);
795     DeleteObject(Brush);
796 }
797 
798 #define CLEAR(__bpp, __type, __pixel_size)                                                          \
799 static void clear_##__bpp(GLcontext* ctx, GLboolean all,GLint x, GLint y, GLint width, GLint height)\
800 {                                                                                                   \
801     struct sw_context* sw_ctx = ctx->DriverCtx;                                                     \
802     struct sw_framebuffer* fb = sw_ctx->fb;                                                         \
803     BYTE* ScanLine;                                                                                 \
804                                                                                                     \
805     if (all)                                                                                        \
806     {                                                                                               \
807         x = y = 0;                                                                                  \
808         width = fb->width;                                                                          \
809         height = fb->height;                                                                        \
810     }                                                                                               \
811                                                                                                     \
812     if (sw_ctx->Mode == GL_FRONT)                                                                   \
813     {                                                                                               \
814         clear_frontbuffer(sw_ctx, fb, x, y, width, height,                                          \
815                 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.ClearColor));              \
816         return;                                                                                     \
817     }                                                                                               \
818                                                                                                     \
819     ScanLine = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp);                          \
820     while (height--)                                                                                \
821     {                                                                                               \
822         BYTE* Buffer = ScanLine + x * __pixel_size;                                                 \
823         UINT n = width;                                                                             \
824                                                                                                     \
825         while (n--)                                                                                 \
826         {                                                                                           \
827             PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.ClearColor);                        \
828             Buffer += __pixel_size;                                                                 \
829         }                                                                                           \
830                                                                                                     \
831         ScanLine += WIDTH_BYTES_ALIGN32(fb->width, __bpp);                                          \
832     }                                                                                               \
833 }
834 CLEAR(8, BYTE, 1)
835 CLEAR(16, USHORT, 2)
836 CLEAR(24, ULONG, 3)
837 CLEAR(32, ULONG, 4)
838 #undef CLEAR
839 
840 /* Set the current color index. */
841 #define SET_INDEX(__bpp)                                        \
842 static void set_index_##__bpp(GLcontext* ctx, GLuint index)     \
843 {                                                               \
844     struct sw_context* sw_ctx = ctx->DriverCtx;                 \
845                                                                 \
846     sw_ctx->u##__bpp.CurrentColor = index;                      \
847 }
848 SET_INDEX(8)
849 SET_INDEX(16)
850 SET_INDEX(24)
851 SET_INDEX(32)
852 #undef SET_INDEX
853 
854 /* Set the current RGBA color. */
855 #define SET_COLOR(__bpp)                                                                    \
856 static void set_color_##__bpp( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) \
857 {                                                                                           \
858     struct sw_context* sw_ctx = ctx->DriverCtx;                                             \
859                                                                                             \
860     sw_ctx->u##__bpp.CurrentColor = PACK_COLOR_##__bpp(r, g, b);                            \
861 }
862 SET_COLOR(8)
863 SET_COLOR(16)
864 SET_COLOR(24)
865 SET_COLOR(32)
866 #undef SET_COLOR
867 
868 /*
869  * Selects either the front or back color buffer for reading and writing.
870  * mode is either GL_FRONT or GL_BACK.
871  */
872 static GLboolean set_buffer( GLcontext* ctx, GLenum mode )
873 {
874     struct sw_context* sw_ctx = ctx->DriverCtx;
875     struct sw_framebuffer* fb = sw_ctx->fb;
876 
877     if (!fb->gl_visual->DBflag)
878         return GL_FALSE;
879 
880     if ((mode != GL_FRONT) && (mode != GL_BACK))
881         return GL_FALSE;
882 
883     sw_ctx->Mode = mode;
884     return GL_TRUE;
885 }
886 
887 /* Return characteristics of the output buffer. */
888 static void buffer_size(GLcontext* ctx, GLuint *width, GLuint *height)
889 {
890     struct sw_context* sw_ctx = ctx->DriverCtx;
891     struct sw_framebuffer* fb = sw_ctx->fb;
892     HWND Window = WindowFromDC(fb->Hdc);
893 
894     if (Window)
895     {
896         RECT client_rect;
897         GetClientRect(Window, &client_rect);
898         *width = client_rect.right - client_rect.left;
899         *height = client_rect.bottom - client_rect.top;
900     }
901     else
902     {
903         /* We are drawing to a bitmap */
904         BITMAP bm;
905         HBITMAP Hbm;
906 
907         Hbm = GetCurrentObject(fb->Hdc, OBJ_BITMAP);
908 
909         if (!GetObjectW(Hbm, sizeof(bm), &bm))
910             return;
911 
912         TRACE("Framebuffer size : %i, %i\n", bm.bmWidth, bm.bmHeight);
913 
914         *width = bm.bmWidth;
915         *height = bm.bmHeight;
916     }
917 
918     if ((*width != fb->width) || (*height != fb->height))
919     {
920         const struct pixel_format* pixel_format = fb->pixel_format;
921 
922         if (pixel_format->dwFlags & PFD_DOUBLEBUFFER)
923         {
924             /* Allocate a new backbuffer */
925             size_t BufferSize = *height * WIDTH_BYTES_ALIGN32(*width, pixel_format->cColorBits);
926             if (!fb->BackBuffer)
927             {
928                 fb->BackBuffer = HeapAlloc(GetProcessHeap(), 0, BufferSize);
929             }
930             else
931             {
932                 fb->BackBuffer = HeapReAlloc(GetProcessHeap(), 0, fb->BackBuffer, BufferSize);
933             }
934             if (!fb->BackBuffer)
935             {
936                 ERR("Failed allocating back buffer !.\n");
937                 return;
938             }
939         }
940 
941         fb->width = *width;
942         fb->height = *height;
943     }
944 }
945 
946 /* Write a horizontal span of color pixels with a boolean mask. */
947 #define WRITE_COLOR_SPAN_FRONTBUFFER(__bpp)                                     \
948 static void write_color_span_frontbuffer_##__bpp(struct sw_framebuffer* fb,     \
949         GLuint n, GLint x, GLint y,                                             \
950         const GLubyte red[], const GLubyte green[],                             \
951         const GLubyte blue[], const GLubyte mask[] )                            \
952 {                                                                               \
953     TRACE("Writing color span at %u, %u (%u)\n", x, y, n);                      \
954                                                                                 \
955     if (mask)                                                                   \
956     {                                                                           \
957         while (n--)                                                             \
958         {                                                                       \
959             if (mask[n])                                                        \
960             {                                                                   \
961                 SetPixel(fb->Hdc, x + n, fb->height - y,                        \
962                         PACK_COLORREF_##__bpp(red[n], green[n], blue[n]));      \
963             }                                                                   \
964         }                                                                       \
965     }                                                                           \
966     else                                                                        \
967     {                                                                           \
968         while (n--)                                                             \
969         {                                                                       \
970             SetPixel(fb->Hdc, x + n, fb->height - y,                            \
971                     PACK_COLORREF_##__bpp(red[n], green[n], blue[n]));          \
972         }                                                                       \
973     }                                                                           \
974 }
975 WRITE_COLOR_SPAN_FRONTBUFFER(8)
976 WRITE_COLOR_SPAN_FRONTBUFFER(16)
977 WRITE_COLOR_SPAN_FRONTBUFFER(24)
978 WRITE_COLOR_SPAN_FRONTBUFFER(32)
979 #undef WRITE_COLOR_SPAN_FRONTBUFFER
980 
981 #define WRITE_COLOR_SPAN(__bpp, __type, __pixel_size)                               \
982 static void write_color_span_##__bpp(GLcontext* ctx,                                \
983                                      GLuint n, GLint x, GLint y,                    \
984                                      const GLubyte red[], const GLubyte green[],    \
985                                      const GLubyte blue[], const GLubyte alpha[],   \
986                                      const GLubyte mask[] )                         \
987 {                                                                                   \
988     struct sw_context* sw_ctx = ctx->DriverCtx;                                     \
989     struct sw_framebuffer* fb = sw_ctx->fb;                                         \
990     BYTE* Buffer;                                                                   \
991                                                                                     \
992     if (sw_ctx->Mode == GL_FRONT)                                                   \
993     {                                                                               \
994         write_color_span_frontbuffer_##__bpp(fb, n, x, y, red, green, blue, mask);  \
995         return;                                                                     \
996     }                                                                               \
997                                                                                     \
998     Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp)             \
999             + (x + n) * __pixel_size;                                               \
1000     if (mask)                                                                       \
1001     {                                                                               \
1002         while (n--)                                                                 \
1003         {                                                                           \
1004             Buffer -= __pixel_size;                                                 \
1005             if (mask[n])                                                            \
1006             {                                                                       \
1007                 PUT_PIXEL_##__bpp((__type*)Buffer,                                  \
1008                         PACK_COLOR_##__bpp(red[n], green[n], blue[n]));             \
1009             }                                                                       \
1010         }                                                                           \
1011     }                                                                               \
1012     else                                                                            \
1013     {                                                                               \
1014         while (n--)                                                                 \
1015         {                                                                           \
1016             Buffer -= __pixel_size;                                                 \
1017             PUT_PIXEL_##__bpp((__type*)Buffer,                                      \
1018                     PACK_COLOR_##__bpp(red[n], green[n], blue[n]));                 \
1019         }                                                                           \
1020     }                                                                               \
1021 }
1022 WRITE_COLOR_SPAN(8, BYTE, 1)
1023 WRITE_COLOR_SPAN(16, USHORT, 2)
1024 WRITE_COLOR_SPAN(24, ULONG, 3)
1025 WRITE_COLOR_SPAN(32, ULONG, 4)
1026 #undef WRITE_COLOR_SPAN
1027 
1028 static void write_monocolor_span_frontbuffer(struct sw_framebuffer* fb, GLuint n, GLint x, GLint y,
1029         const GLubyte mask[], COLORREF Color)
1030 {
1031     TRACE("Writing monocolor span at %u %u (%u), Color 0x%08x\n", x, y, n, Color);
1032 
1033     if (mask)
1034     {
1035         while (n--)
1036         {
1037             if (mask[n])
1038                 SetPixel(fb->Hdc, x + n, y, Color);
1039         }
1040     }
1041     else
1042     {
1043         HBRUSH Brush = CreateSolidBrush(Color);
1044         Brush = SelectObject(fb->Hdc, Brush);
1045 
1046         PatBlt(fb->Hdc, x, fb->height - y, n, 1, PATCOPY);
1047 
1048         Brush = SelectObject(fb->Hdc, Brush);
1049         DeleteObject(Brush);
1050     }
1051 }
1052 
1053 #define WRITE_MONOCOLOR_SPAN(__bpp, __type, __pixel_size)                                           \
1054 static void write_monocolor_span_##__bpp(GLcontext* ctx,                                            \
1055                                  GLuint n, GLint x, GLint y,                                        \
1056                                  const GLubyte mask[])                                              \
1057 {                                                                                                   \
1058     struct sw_context* sw_ctx = ctx->DriverCtx;                                                     \
1059     struct sw_framebuffer* fb = sw_ctx->fb;                                                         \
1060     BYTE* Buffer;                                                                                   \
1061                                                                                                     \
1062     if (sw_ctx->Mode == GL_FRONT)                                                                   \
1063     {                                                                                               \
1064         write_monocolor_span_frontbuffer(fb, n, x, y, mask,                                         \
1065                 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.CurrentColor));            \
1066         return;                                                                                     \
1067     }                                                                                               \
1068                                                                                                     \
1069     Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp) + (x + n) * __pixel_size;   \
1070     if (mask)                                                                                       \
1071     {                                                                                               \
1072         while (n--)                                                                                 \
1073         {                                                                                           \
1074             Buffer -= __pixel_size;                                                                 \
1075             if (mask[n])                                                                            \
1076                 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.CurrentColor);                  \
1077         }                                                                                           \
1078     }                                                                                               \
1079     else                                                                                            \
1080     {                                                                                               \
1081         while(n--)                                                                                  \
1082         {                                                                                           \
1083             Buffer -= __pixel_size;                                                                 \
1084             PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.CurrentColor);                      \
1085         }                                                                                           \
1086     }                                                                                               \
1087 }
1088 WRITE_MONOCOLOR_SPAN(8, BYTE, 1)
1089 WRITE_MONOCOLOR_SPAN(16, USHORT, 2)
1090 WRITE_MONOCOLOR_SPAN(24, ULONG, 3)
1091 WRITE_MONOCOLOR_SPAN(32, ULONG, 4)
1092 #undef WRITE_MONOCOLOR_SPAN
1093 
1094 /* Write an array of pixels with a boolean mask. */
1095 #define WRITE_COLOR_PIXELS(__bpp, __type, __pixel_size)                                             \
1096 static void write_color_pixels_##__bpp(GLcontext* ctx,                                              \
1097                                GLuint n, const GLint x[], const GLint y[],                          \
1098                                const GLubyte r[], const GLubyte g[],                                \
1099                                const GLubyte b[], const GLubyte a[],                                \
1100                                const GLubyte mask[])                                                \
1101 {                                                                                                   \
1102     struct sw_context* sw_ctx = ctx->DriverCtx;                                                     \
1103     struct sw_framebuffer* fb = sw_ctx->fb;                                                         \
1104                                                                                                     \
1105     TRACE("Writing color pixels\n");                                                                \
1106                                                                                                     \
1107     if (sw_ctx->Mode == GL_FRONT)                                                                   \
1108     {                                                                                               \
1109         while (n--)                                                                                 \
1110         {                                                                                           \
1111             if (mask[n])                                                                            \
1112             {                                                                                       \
1113                 TRACE("Setting pixel %u, %u to 0x%08x.\n", x[n], fb->height - y[n],                 \
1114                         PACK_COLORREF_##__bpp(r[n], g[n], b[n]));                                   \
1115                 SetPixel(fb->Hdc, x[n], fb->height - y[n],                                          \
1116                         PACK_COLORREF_##__bpp(r[n], g[n], b[n]));                                   \
1117             }                                                                                       \
1118         }                                                                                           \
1119                                                                                                     \
1120         return;                                                                                     \
1121     }                                                                                               \
1122                                                                                                     \
1123     while (n--)                                                                                     \
1124     {                                                                                               \
1125         if (mask[n])                                                                                \
1126         {                                                                                           \
1127             BYTE* Buffer = fb->BackBuffer + y[n] * WIDTH_BYTES_ALIGN32(fb->width, __bpp)            \
1128                             + x[n] * __pixel_size;                                                  \
1129             PUT_PIXEL_##__bpp((__type*)Buffer, PACK_COLOR_##__bpp(r[n], g[n], b[n]));               \
1130         }                                                                                           \
1131     }                                                                                               \
1132 }
1133 WRITE_COLOR_PIXELS(8, BYTE, 1)
1134 WRITE_COLOR_PIXELS(16, USHORT, 2)
1135 WRITE_COLOR_PIXELS(24, ULONG, 3)
1136 WRITE_COLOR_PIXELS(32, ULONG, 4)
1137 #undef WRITE_COLOR_PIXELS
1138 
1139 static void write_monocolor_pixels_frontbuffer(
1140         struct sw_framebuffer* fb, GLuint n,
1141         const GLint x[], const GLint y[],
1142         const GLubyte mask[], COLORREF Color)
1143 {
1144     TRACE("Writing monocolor pixels to front buffer.\n");
1145 
1146     while (n--)
1147     {
1148         if (mask[n])
1149         {
1150             SetPixel(fb->Hdc, x[n], fb->height - y[n], Color);
1151         }
1152     }
1153 }
1154 
1155 /*
1156 * Write an array of pixels with a boolean mask.  The current color
1157 * is used for all pixels.
1158 */
1159 #define WRITE_MONOCOLOR_PIXELS(__bpp, __type, __pixel_size)                                 \
1160 static void write_monocolor_pixels_##__bpp(GLcontext* ctx, GLuint n,                        \
1161                                    const GLint x[], const GLint y[],                        \
1162                                    const GLubyte mask[] )                                   \
1163 {                                                                                           \
1164     struct sw_context* sw_ctx = ctx->DriverCtx;                                             \
1165     struct sw_framebuffer* fb = sw_ctx->fb;                                                 \
1166                                                                                             \
1167     if (sw_ctx->Mode == GL_FRONT)                                                           \
1168     {                                                                                       \
1169         write_monocolor_pixels_frontbuffer(fb, n, x, y, mask,                               \
1170                 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.CurrentColor));    \
1171                                                                                             \
1172         return;                                                                             \
1173     }                                                                                       \
1174                                                                                             \
1175     while (n--)                                                                             \
1176     {                                                                                       \
1177         if (mask[n])                                                                        \
1178         {                                                                                   \
1179             BYTE* Buffer = fb->BackBuffer + y[n] * WIDTH_BYTES_ALIGN32(fb->width, 32)       \
1180                     + x[n] * __pixel_size;                                                  \
1181             PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.CurrentColor);              \
1182         }                                                                                   \
1183     }                                                                                       \
1184 }
1185 WRITE_MONOCOLOR_PIXELS(8, BYTE, 1)
1186 WRITE_MONOCOLOR_PIXELS(16, USHORT, 2)
1187 WRITE_MONOCOLOR_PIXELS(24, ULONG, 3)
1188 WRITE_MONOCOLOR_PIXELS(32, ULONG, 4)
1189 #undef WRITE_MONOCOLOR_PIXELS
1190 
1191 /* Write a horizontal span of color pixels with a boolean mask. */
1192 static void write_index_span( GLcontext* ctx,
1193                              GLuint n, GLint x, GLint y,
1194                              const GLuint index[],
1195                              const GLubyte mask[] )
1196 {
1197     ERR("Not implemented yet !\n");
1198 }
1199 
1200 /* Write an array of pixels with a boolean mask. */
1201 static void write_index_pixels( GLcontext* ctx,
1202                                GLuint n, const GLint x[], const GLint y[],
1203                                const GLuint index[], const GLubyte mask[] )
1204 {
1205     ERR("Not implemented yet !\n");
1206 }
1207 
1208 /* Read a horizontal span of color-index pixels. */
1209 static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[])
1210 {
1211     ERR("Not implemented yet !\n");
1212 }
1213 
1214 /* Read a horizontal span of color pixels. */
1215 #define READ_COLOR_SPAN(__bpp, __type, __pixel_size)                            \
1216 static void read_color_span_##__bpp(GLcontext* ctx,                             \
1217                             GLuint n, GLint x, GLint y,                         \
1218                             GLubyte red[], GLubyte green[],                     \
1219                             GLubyte blue[], GLubyte alpha[] )                   \
1220 {                                                                               \
1221     struct sw_context* sw_ctx = ctx->DriverCtx;                                 \
1222     struct sw_framebuffer* fb = sw_ctx->fb;                                     \
1223     BYTE* Buffer;                                                               \
1224                                                                                 \
1225     if (sw_ctx->Mode == GL_FRONT)                                               \
1226     {                                                                           \
1227         COLORREF Color;                                                         \
1228         while (n--)                                                             \
1229         {                                                                       \
1230             Color = GetPixel(fb->Hdc, x + n, fb->height - y);                   \
1231             UNPACK_COLORREF_##__bpp(Color, &red[n], &green[n], &blue[n]);       \
1232             alpha[n] = 0;                                                       \
1233         }                                                                       \
1234                                                                                 \
1235         return;                                                                 \
1236     }                                                                           \
1237                                                                                 \
1238     Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp)         \
1239             + (x + n) * __pixel_size;                                           \
1240     while (n--)                                                                 \
1241     {                                                                           \
1242         Buffer -= __pixel_size;                                                 \
1243         UNPACK_COLOR_##__bpp(GET_PIXEL_##__bpp((__type*)Buffer),                \
1244                 &red[n], &green[n], &blue[n]);                                  \
1245         alpha[n] = 0;                                                           \
1246     }                                                                           \
1247 }
1248 READ_COLOR_SPAN(8, BYTE, 1)
1249 READ_COLOR_SPAN(16, USHORT, 2)
1250 READ_COLOR_SPAN(24, ULONG, 3)
1251 READ_COLOR_SPAN(32, ULONG, 4)
1252 #undef READ_COLOR_SPAN
1253 
1254 /* Read an array of color index pixels. */
1255 static void read_index_pixels(GLcontext* ctx,
1256                               GLuint n, const GLint x[], const GLint y[],
1257                               GLuint index[], const GLubyte mask[])
1258 {
1259 
1260     ERR("Not implemented yet !\n");
1261 }
1262 
1263 /* Read an array of color pixels. */
1264 #define READ_COLOR_PIXELS(__bpp, __type, __pixel_size)                                      \
1265 static void read_color_pixels_##__bpp(GLcontext* ctx,                                       \
1266                               GLuint n, const GLint x[], const GLint y[],                   \
1267                               GLubyte red[], GLubyte green[],                               \
1268                               GLubyte blue[], GLubyte alpha[],                              \
1269                               const GLubyte mask[] )                                        \
1270 {                                                                                           \
1271     struct sw_context* sw_ctx = ctx->DriverCtx;                                             \
1272     struct sw_framebuffer* fb = sw_ctx->fb;                                                 \
1273                                                                                             \
1274     if (sw_ctx->Mode == GL_FRONT)                                                           \
1275     {                                                                                       \
1276         COLORREF Color;                                                                     \
1277         while (n--)                                                                         \
1278         {                                                                                   \
1279             if (mask[n])                                                                    \
1280             {                                                                               \
1281                 Color = GetPixel(fb->Hdc, x[n], fb->height - y[n]);                         \
1282                 UNPACK_COLORREF_##__bpp(Color, &red[n], &green[n], &blue[n]);               \
1283                 alpha[n] = 0;                                                               \
1284             }                                                                               \
1285         }                                                                                   \
1286                                                                                             \
1287         return;                                                                             \
1288     }                                                                                       \
1289                                                                                             \
1290     while (n--)                                                                             \
1291     {                                                                                       \
1292         if (mask[n])                                                                        \
1293         {                                                                                   \
1294             BYTE *Buffer = fb->BackBuffer + y[n] * WIDTH_BYTES_ALIGN32(fb->width, __bpp)    \
1295                     + x[n] * __pixel_size;                                                  \
1296             UNPACK_COLOR_##__bpp(GET_PIXEL_##__bpp((__type*)Buffer),                        \
1297                     &red[n], &green[n], &blue[n]);                                          \
1298             alpha[n] = 0;                                                                   \
1299         }                                                                                   \
1300     }                                                                                       \
1301 }
1302 READ_COLOR_PIXELS(8, BYTE, 1)
1303 READ_COLOR_PIXELS(16, USHORT, 2)
1304 READ_COLOR_PIXELS(24, ULONG, 3)
1305 READ_COLOR_PIXELS(32, ULONG, 4)
1306 #undef READ_COLOR_PIXELS
1307 
1308 static void setup_DD_pointers( GLcontext* ctx )
1309 {
1310     struct sw_context* sw_ctx = ctx->DriverCtx;
1311 
1312     ctx->Driver.RendererString = renderer_string;
1313     ctx->Driver.UpdateState = setup_DD_pointers;
1314 
1315     switch (sw_ctx->fb->pixel_format->cColorBits)
1316     {
1317 #define HANDLE_BPP(__bpp)                                                   \
1318     case __bpp:                                                             \
1319         ctx->Driver.ClearIndex = clear_index_##__bpp;                       \
1320         ctx->Driver.ClearColor = clear_color_##__bpp;                       \
1321         ctx->Driver.Clear = clear_##__bpp;                                  \
1322         ctx->Driver.Index = set_index_##__bpp;                              \
1323         ctx->Driver.Color = set_color_##__bpp;                              \
1324         ctx->Driver.WriteColorSpan       = write_color_span_##__bpp;        \
1325         ctx->Driver.WriteMonocolorSpan   = write_monocolor_span_##__bpp;    \
1326         ctx->Driver.WriteMonoindexSpan   = write_monocolor_span_##__bpp;    \
1327         ctx->Driver.WriteColorPixels     = write_color_pixels_##__bpp;      \
1328         ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels_##__bpp;  \
1329         ctx->Driver.WriteMonoindexPixels = write_monocolor_pixels_##__bpp;  \
1330         ctx->Driver.ReadColorSpan = read_color_span_##__bpp;                \
1331         ctx->Driver.ReadColorPixels = read_color_pixels_##__bpp;            \
1332         break
1333 HANDLE_BPP(8);
1334 HANDLE_BPP(16);
1335 HANDLE_BPP(24);
1336 HANDLE_BPP(32);
1337 #undef HANDLE_BPP
1338     default:
1339         ERR("Unhandled bit depth %u, defaulting to 32bpp.\n", sw_ctx->fb->pixel_format->cColorBits);
1340         ctx->Driver.ClearIndex = clear_index_32;
1341         ctx->Driver.ClearColor = clear_color_32;
1342         ctx->Driver.Clear = clear_32;
1343         ctx->Driver.Index = set_index_32;
1344         ctx->Driver.Color = set_color_32;
1345         ctx->Driver.WriteColorSpan       = write_color_span_32;
1346         ctx->Driver.WriteMonocolorSpan   = write_monocolor_span_32;
1347         ctx->Driver.WriteMonoindexSpan   = write_monocolor_span_32;
1348         ctx->Driver.WriteColorPixels     = write_color_pixels_32;
1349         ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels_32;
1350         ctx->Driver.WriteMonoindexPixels = write_monocolor_pixels_32;
1351         ctx->Driver.ReadColorSpan = read_color_span_32;
1352         ctx->Driver.ReadColorPixels = read_color_pixels_32;
1353         break;
1354     }
1355 
1356     ctx->Driver.SetBuffer = set_buffer;
1357     ctx->Driver.GetBufferSize = buffer_size;
1358 
1359     /* Pixel/span writing functions: */
1360     ctx->Driver.WriteIndexSpan       = write_index_span;
1361     ctx->Driver.WriteIndexPixels     = write_index_pixels;
1362 
1363     /* Pixel/span reading functions: */
1364     ctx->Driver.ReadIndexSpan = read_index_span;
1365     ctx->Driver.ReadIndexPixels = read_index_pixels;
1366 }
1367 
1368 /* Declare API table */
1369 #define USE_GL_FUNC(name, proto_args, call_args, offset, stack) extern void WINAPI _mesa_##name proto_args ;
1370 #define USE_GL_FUNC_RET(name, ret_type, proto_args, call_args, offset, stack) extern ret_type WINAPI _mesa_##name proto_args ;
1371 #include "glfuncs.h"
1372 
1373 static GLCLTPROCTABLE sw_api_table =
1374 {
1375     OPENGL_VERSION_110_ENTRIES,
1376     {
1377 #define USE_GL_FUNC(name, proto_args, call_args, offset, stack) _mesa_##name,
1378 #include "glfuncs.h"
1379     }
1380 };
1381 
1382 /* Glue code */
1383 GLcontext* gl_get_thread_context(void)
1384 {
1385     struct sw_context* sw_ctx = (struct sw_context*)IntGetCurrentDHGLRC();
1386     return sw_ctx->gl_ctx;
1387 }
1388 
1389 
1390 BOOL sw_SetContext(struct wgl_dc_data* dc_data, DHGLRC dhglrc)
1391 {
1392     struct sw_context* sw_ctx = (struct sw_context*)dhglrc;
1393     struct sw_framebuffer* fb = dc_data->sw_data;
1394     UINT width, height;
1395 
1396     /* Get framebuffer size */
1397     if(dc_data->flags & WGL_DC_OBJ_DC)
1398     {
1399         HWND hwnd = dc_data->owner.hwnd;
1400         RECT client_rect;
1401         if(!hwnd)
1402         {
1403             ERR("Physical DC without a window!\n");
1404             return FALSE;
1405         }
1406         if(!GetClientRect(hwnd, &client_rect))
1407         {
1408             ERR("GetClientRect failed!\n");
1409             return FALSE;
1410         }
1411 
1412         /* This is a physical DC. Setup the hook */
1413         sw_ctx->hook = SetWindowsHookEx(WH_CALLWNDPROC,
1414                             sw_call_window_proc,
1415                             NULL,
1416                             GetCurrentThreadId());
1417 
1418         /* Calculate width & height */
1419         width  = client_rect.right  - client_rect.left;
1420         height = client_rect.bottom - client_rect.top;
1421     }
1422     else /* OBJ_MEMDC */
1423     {
1424         BITMAP bm;
1425         HBITMAP hbmp;
1426         HDC hdc = dc_data->owner.hdc;
1427 
1428         if(fb->gl_visual->DBflag)
1429         {
1430             ERR("Memory DC called with a double buffered format.\n");
1431             return FALSE;
1432         }
1433 
1434         hbmp = GetCurrentObject( hdc, OBJ_BITMAP );
1435         if(!hbmp)
1436         {
1437             ERR("No Bitmap!\n");
1438             return FALSE;
1439         }
1440         if(GetObject(hbmp, sizeof(bm), &bm) == 0)
1441         {
1442             ERR("GetObject failed!\n");
1443             return FALSE;
1444         }
1445         width = bm.bmWidth;
1446         height = bm.bmHeight;
1447     }
1448 
1449     if(!width) width = 1;
1450     if(!height) height = 1;
1451 
1452     /* Also make the mesa context current to mesa */
1453     gl_make_current(sw_ctx->gl_ctx, fb->gl_buffer);
1454 
1455     /* Setup our functions */
1456     setup_DD_pointers(sw_ctx->gl_ctx);
1457 
1458     /* Set the viewport if this is the first time we initialize this context */
1459     if(sw_ctx->gl_ctx->Viewport.X == 0 &&
1460        sw_ctx->gl_ctx->Viewport.Y == 0 &&
1461        sw_ctx->gl_ctx->Viewport.Width == 0 &&
1462        sw_ctx->gl_ctx->Viewport.Height == 0)
1463     {
1464         gl_Viewport(sw_ctx->gl_ctx, 0, 0, width, height);
1465     }
1466 
1467     /* update the framebuffer size */
1468     gl_ResizeBuffersMESA(sw_ctx->gl_ctx);
1469 
1470     /* Use our API table */
1471     IntSetCurrentDispatchTable(&sw_api_table.glDispatchTable);
1472 
1473    /* We're good */
1474    return TRUE;
1475 }
1476 
1477 void sw_ReleaseContext(DHGLRC dhglrc)
1478 {
1479     struct sw_context* sw_ctx = (struct sw_context*)dhglrc;
1480 
1481     /* Forward to mesa */
1482     gl_make_current(NULL, NULL);
1483 
1484     /* Unhook */
1485     if(sw_ctx->hook)
1486     {
1487         UnhookWindowsHookEx(sw_ctx->hook);
1488         sw_ctx->hook = NULL;
1489     }
1490 }
1491 
1492 BOOL sw_SwapBuffers(HDC hdc, struct wgl_dc_data* dc_data)
1493 {
1494     struct sw_framebuffer* fb = dc_data->sw_data;
1495     char Buffer[sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD)];
1496     BITMAPINFO *bmi = (BITMAPINFO*)Buffer;
1497     BYTE Bpp = fb->pixel_format->cColorBits;
1498 
1499     if (!fb->gl_visual->DBflag)
1500         return TRUE;
1501 
1502     if (!fb->BackBuffer)
1503         return FALSE;
1504 
1505     bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
1506     bmi->bmiHeader.biBitCount = Bpp;
1507     bmi->bmiHeader.biClrImportant = 0;
1508     bmi->bmiHeader.biClrUsed = 0;
1509     bmi->bmiHeader.biPlanes = 1;
1510     bmi->bmiHeader.biSizeImage = WIDTH_BYTES_ALIGN32(fb->width, Bpp) * fb->height;
1511     bmi->bmiHeader.biXPelsPerMeter = 0;
1512     bmi->bmiHeader.biYPelsPerMeter = 0;
1513     bmi->bmiHeader.biHeight = fb->height;
1514     bmi->bmiHeader.biWidth = fb->width;
1515     bmi->bmiHeader.biCompression = Bpp == 16 ? BI_BITFIELDS : BI_RGB;
1516 
1517     if (Bpp == 16)
1518     {
1519         DWORD* BitMasks = (DWORD*)(&bmi->bmiColors[0]);
1520         BitMasks[0] = 0x0000F800;
1521         BitMasks[1] = 0x000007E0;
1522         BitMasks[2] = 0x0000001F;
1523     }
1524 
1525     return SetDIBitsToDevice(fb->Hdc, 0, 0, fb->width, fb->height, 0, 0, 0, fb->height, fb->BackBuffer, bmi,
1526             fb->pixel_format->iPixelType == PFD_TYPE_COLORINDEX ? DIB_PAL_COLORS : DIB_RGB_COLORS) != 0;
1527 }
1528