]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkvisual-win32.c
applied patch from Andreas Persenius <ndap@swipnet.se> that updates the
[~andy/gtk] / gdk / win32 / gdkvisual-win32.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "config.h"
28
29 #include "gdkvisual.h"
30 #include "gdkprivate-win32.h"
31
32 static void  gdk_visual_decompose_mask (gulong     mask,
33                                         gint      *shift,
34                                         gint      *prec);
35
36 static GdkVisualPrivate *system_visual;
37
38 static gint available_depths[1];
39
40 static GdkVisualType available_types[1];
41
42 void
43 gdk_visual_init (void)
44 {
45   struct
46   {
47     BITMAPINFOHEADER bi;
48     union
49     {
50       RGBQUAD colors[256];
51       DWORD fields[256];
52     } u;
53   } bmi;
54   HBITMAP hbm;
55
56   int rastercaps, numcolors, sizepalette, bitspixel;
57
58   system_visual = g_new (GdkVisualPrivate, 1);
59
60   bitspixel = GetDeviceCaps (gdk_display_hdc, BITSPIXEL);
61   rastercaps = GetDeviceCaps (gdk_display_hdc, RASTERCAPS);
62   system_visual->xvisual = g_new (Visual, 1);
63   system_visual->xvisual->visualid = 0;
64   system_visual->xvisual->bitspixel = bitspixel;
65
66   if (rastercaps & RC_PALETTE)
67     {
68       system_visual->visual.type = GDK_VISUAL_PSEUDO_COLOR;
69       numcolors = GetDeviceCaps (gdk_display_hdc, NUMCOLORS);
70       sizepalette = GetDeviceCaps (gdk_display_hdc, SIZEPALETTE);
71       system_visual->xvisual->map_entries = sizepalette;
72     }
73   else if (bitspixel == 1)
74     {
75       system_visual->visual.type = GDK_VISUAL_STATIC_GRAY;
76       system_visual->xvisual->map_entries = 2;
77     }
78   else if (bitspixel == 4)
79     {
80       system_visual->visual.type = GDK_VISUAL_STATIC_COLOR;
81       system_visual->xvisual->map_entries = 16;
82     }
83   else if (bitspixel == 8)
84     {
85       system_visual->visual.type = GDK_VISUAL_STATIC_COLOR;
86       system_visual->xvisual->map_entries = 256;
87     }
88   else if (bitspixel == 16)
89     {
90       system_visual->visual.type = GDK_VISUAL_TRUE_COLOR;
91 #if 1
92       /* This code by Mike Enright,
93        * see http://www.users.cts.com/sd/m/menright/display.html
94        */
95       memset (&bmi, 0, sizeof (bmi));
96       bmi.bi.biSize = sizeof (bmi.bi);
97
98       hbm = CreateCompatibleBitmap (gdk_display_hdc, 1, 1);
99       GetDIBits (gdk_display_hdc, hbm, 0, 1, NULL,
100                  (BITMAPINFO *) &bmi, DIB_RGB_COLORS);
101       GetDIBits (gdk_display_hdc, hbm, 0, 1, NULL,
102                  (BITMAPINFO *) &bmi, DIB_RGB_COLORS);
103       DeleteObject (hbm);
104
105       if (bmi.bi.biCompression != BI_BITFIELDS)
106         {
107           /* Either BI_RGB or BI_RLE_something
108            * .... or perhaps (!!) something else.
109            * Theoretically biCompression might be
110            * mmioFourCC('c','v','i','d') but I doubt it.
111            */
112           if (bmi.bi.biCompression == BI_RGB)
113             {
114               /* It's 555 */
115               bitspixel = 15;
116               system_visual->visual.red_mask   = 0x00007C00;
117               system_visual->visual.green_mask = 0x000003E0;
118               system_visual->visual.blue_mask  = 0x0000001F;
119             }
120           else
121             {
122               g_assert_not_reached ();
123             }
124         }
125       else
126         {
127           DWORD allmasks =
128             bmi.u.fields[0] | bmi.u.fields[1] | bmi.u.fields[2];
129           int k = 0;
130           while (allmasks)
131             {
132               if (allmasks&1)
133                 k++;
134               allmasks/=2;
135             }
136           bitspixel = k;
137           system_visual->visual.red_mask = bmi.u.fields[0];
138           system_visual->visual.green_mask = bmi.u.fields[1];
139           system_visual->visual.blue_mask  = bmi.u.fields[2];
140         }
141 #else
142       /* Old, incorrect (but still working) code. */
143 #if 0
144       system_visual->visual.red_mask   = 0x0000F800;
145       system_visual->visual.green_mask = 0x000007E0;
146       system_visual->visual.blue_mask  = 0x0000001F;
147 #else
148       system_visual->visual.red_mask   = 0x00007C00;
149       system_visual->visual.green_mask = 0x000003E0;
150       system_visual->visual.blue_mask  = 0x0000001F;
151 #endif
152 #endif
153     }
154   else if (bitspixel == 24 || bitspixel == 32)
155     {
156       bitspixel = 24;
157       system_visual->visual.type = GDK_VISUAL_TRUE_COLOR;
158       system_visual->visual.red_mask   = 0x00FF0000;
159       system_visual->visual.green_mask = 0x0000FF00;
160       system_visual->visual.blue_mask  = 0x000000FF;
161     }
162   else
163     g_error ("gdk_visual_init: unsupported BITSPIXEL: %d\n", bitspixel);
164
165   system_visual->visual.depth = bitspixel;
166   system_visual->visual.byte_order = GDK_LSB_FIRST;
167   system_visual->visual.bits_per_rgb = 42; /* Not used? */
168
169   if ((system_visual->visual.type == GDK_VISUAL_TRUE_COLOR) ||
170       (system_visual->visual.type == GDK_VISUAL_DIRECT_COLOR))
171     {
172       gdk_visual_decompose_mask (system_visual->visual.red_mask,
173                                  &system_visual->visual.red_shift,
174                                  &system_visual->visual.red_prec);
175
176       gdk_visual_decompose_mask (system_visual->visual.green_mask,
177                                  &system_visual->visual.green_shift,
178                                  &system_visual->visual.green_prec);
179
180       gdk_visual_decompose_mask (system_visual->visual.blue_mask,
181                                  &system_visual->visual.blue_shift,
182                                  &system_visual->visual.blue_prec);
183       system_visual->xvisual->map_entries =
184         1 << (MAX (system_visual->visual.red_prec,
185                    MAX (system_visual->visual.green_prec,
186                         system_visual->visual.blue_prec)));
187     }
188   else
189     {
190       system_visual->visual.red_mask = 0;
191       system_visual->visual.red_shift = 0;
192       system_visual->visual.red_prec = 0;
193
194       system_visual->visual.green_mask = 0;
195       system_visual->visual.green_shift = 0;
196       system_visual->visual.green_prec = 0;
197
198       system_visual->visual.blue_mask = 0;
199       system_visual->visual.blue_shift = 0;
200       system_visual->visual.blue_prec = 0;
201     }
202   system_visual->visual.colormap_size = system_visual->xvisual->map_entries;
203
204   available_depths[0] = system_visual->visual.depth;
205   available_types[0] = system_visual->visual.type;
206 }
207
208 GdkVisual*
209 gdk_visual_ref (GdkVisual *visual)
210 {
211   return visual;
212 }
213
214 void
215 gdk_visual_unref (GdkVisual *visual)
216 {
217   return;
218 }
219
220 gint
221 gdk_visual_get_best_depth (void)
222 {
223   return available_depths[0];
224 }
225
226 GdkVisualType
227 gdk_visual_get_best_type (void)
228 {
229   return available_types[0];
230 }
231
232 GdkVisual*
233 gdk_visual_get_system (void)
234 {
235   return ((GdkVisual*) system_visual);
236 }
237
238 GdkVisual*
239 gdk_visual_get_best (void)
240 {
241   return ((GdkVisual*) system_visual);
242 }
243
244 GdkVisual*
245 gdk_visual_get_best_with_depth (gint depth)
246 {
247   if (depth == system_visual->visual.depth)
248     return (GdkVisual*) system_visual;
249   else
250     return NULL;
251 }
252
253 GdkVisual*
254 gdk_visual_get_best_with_type (GdkVisualType visual_type)
255 {
256   if (visual_type == system_visual->visual.type)
257     return (GdkVisual*) system_visual;
258   else
259     return NULL;
260 }
261
262 GdkVisual*
263 gdk_visual_get_best_with_both (gint          depth,
264                                GdkVisualType visual_type)
265 {
266   if ((depth == system_visual->visual.depth) &&
267       (visual_type == system_visual->visual.type))
268     return (GdkVisual*) system_visual;
269   else
270     return NULL;
271 }
272
273 void
274 gdk_query_depths  (gint **depths,
275                    gint  *count)
276 {
277   *count = 1;
278   *depths = available_depths;
279 }
280
281 void
282 gdk_query_visual_types (GdkVisualType **visual_types,
283                         gint           *count)
284 {
285   *count = 1;
286   *visual_types = available_types;
287 }
288
289 GList*
290 gdk_list_visuals (void)
291 {
292   return g_list_append (NULL, (gpointer) system_visual);
293 }
294
295 GdkVisual*
296 gdk_visual_lookup (Visual *xvisual)
297 {
298   if (system_visual->xvisual == xvisual)
299     return (GdkVisual *) system_visual;
300   else
301     return NULL;
302 }
303
304 static void
305 gdk_visual_decompose_mask (gulong  mask,
306                            gint   *shift,
307                            gint   *prec)
308 {
309   *shift = 0;
310   *prec = 0;
311
312   while (!(mask & 0x1))
313     {
314       (*shift)++;
315       mask >>= 1;
316     }
317
318   while (mask & 0x1)
319     {
320       (*prec)++;
321       mask >>= 1;
322     }
323 }