]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkvisual-win32.c
Large changes to the Win32 backend, partially made necessary by 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 Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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-1999.  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 #ifdef G_ENABLE_DEBUG
43
44 static const gchar* visual_names[] =
45 {
46   "static gray",
47   "grayscale",
48   "static color",
49   "pseudo color",
50   "true color",
51   "direct color",
52 };
53
54 #endif /* G_ENABLE_DEBUG */
55
56 void
57 gdk_visual_init (void)
58 {
59   struct
60   {
61     BITMAPINFOHEADER bi;
62     union
63     {
64       RGBQUAD colors[256];
65       DWORD fields[256];
66     } u;
67   } bmi;
68   HBITMAP hbm;
69
70   int rastercaps, numcolors, sizepalette, bitspixel;
71
72   system_visual = g_new (GdkVisualPrivate, 1);
73
74   bitspixel = GetDeviceCaps (gdk_DC, BITSPIXEL);
75   rastercaps = GetDeviceCaps (gdk_DC, RASTERCAPS);
76   system_visual->xvisual = g_new (Visual, 1);
77   system_visual->xvisual->visualid = 0;
78   system_visual->xvisual->bitspixel = bitspixel;
79
80   if (rastercaps & RC_PALETTE)
81     {
82       system_visual->visual.type = GDK_VISUAL_PSEUDO_COLOR;
83       numcolors = GetDeviceCaps (gdk_DC, NUMCOLORS);
84       sizepalette = GetDeviceCaps (gdk_DC, SIZEPALETTE);
85       system_visual->xvisual->map_entries = sizepalette;
86     }
87   else if (bitspixel == 1)
88     {
89       system_visual->visual.type = GDK_VISUAL_STATIC_GRAY;
90       system_visual->xvisual->map_entries = 2;
91     }
92   else if (bitspixel == 4)
93     {
94       system_visual->visual.type = GDK_VISUAL_STATIC_COLOR;
95       system_visual->xvisual->map_entries = 16;
96     }
97   else if (bitspixel == 8)
98     {
99       system_visual->visual.type = GDK_VISUAL_STATIC_COLOR;
100       system_visual->xvisual->map_entries = 256;
101     }
102   else if (bitspixel == 16)
103     {
104       system_visual->visual.type = GDK_VISUAL_TRUE_COLOR;
105 #if 1
106       /* This code by Mike Enright,
107        * see http://www.users.cts.com/sd/m/menright/display.html
108        */
109       memset (&bmi, 0, sizeof (bmi));
110       bmi.bi.biSize = sizeof (bmi.bi);
111
112       hbm = CreateCompatibleBitmap (gdk_DC, 1, 1);
113       GetDIBits (gdk_DC, hbm, 0, 1, NULL,
114                  (BITMAPINFO *) &bmi, DIB_RGB_COLORS);
115       GetDIBits (gdk_DC, hbm, 0, 1, NULL,
116                  (BITMAPINFO *) &bmi, DIB_RGB_COLORS);
117       DeleteObject (hbm);
118
119       if (bmi.bi.biCompression != BI_BITFIELDS)
120         {
121           /* Either BI_RGB or BI_RLE_something
122            * .... or perhaps (!!) something else.
123            * Theoretically biCompression might be
124            * mmioFourCC('c','v','i','d') but I doubt it.
125            */
126           if (bmi.bi.biCompression == BI_RGB)
127             {
128               /* It's 555 */
129               bitspixel = 15;
130               system_visual->visual.red_mask   = 0x00007C00;
131               system_visual->visual.green_mask = 0x000003E0;
132               system_visual->visual.blue_mask  = 0x0000001F;
133             }
134           else
135             {
136               g_assert_not_reached ();
137             }
138         }
139       else
140         {
141           DWORD allmasks =
142             bmi.u.fields[0] | bmi.u.fields[1] | bmi.u.fields[2];
143           int k = 0;
144           while (allmasks)
145             {
146               if (allmasks&1)
147                 k++;
148               allmasks/=2;
149             }
150           bitspixel = k;
151           system_visual->visual.red_mask = bmi.u.fields[0];
152           system_visual->visual.green_mask = bmi.u.fields[1];
153           system_visual->visual.blue_mask  = bmi.u.fields[2];
154         }
155 #else
156       /* Old, incorrect (but still working) code. */
157 #if 0
158       system_visual->visual.red_mask   = 0x0000F800;
159       system_visual->visual.green_mask = 0x000007E0;
160       system_visual->visual.blue_mask  = 0x0000001F;
161 #else
162       system_visual->visual.red_mask   = 0x00007C00;
163       system_visual->visual.green_mask = 0x000003E0;
164       system_visual->visual.blue_mask  = 0x0000001F;
165 #endif
166 #endif
167     }
168   else if (bitspixel == 24 || bitspixel == 32)
169     {
170       bitspixel = 24;
171       system_visual->visual.type = GDK_VISUAL_TRUE_COLOR;
172       system_visual->visual.red_mask   = 0x00FF0000;
173       system_visual->visual.green_mask = 0x0000FF00;
174       system_visual->visual.blue_mask  = 0x000000FF;
175     }
176   else
177     g_error ("gdk_visual_init: unsupported BITSPIXEL: %d\n", bitspixel);
178
179   system_visual->visual.depth = bitspixel;
180   system_visual->visual.byte_order = GDK_LSB_FIRST;
181   system_visual->visual.bits_per_rgb = 42; /* Not used? */
182
183   if ((system_visual->visual.type == GDK_VISUAL_TRUE_COLOR) ||
184       (system_visual->visual.type == GDK_VISUAL_DIRECT_COLOR))
185     {
186       gdk_visual_decompose_mask (system_visual->visual.red_mask,
187                                  &system_visual->visual.red_shift,
188                                  &system_visual->visual.red_prec);
189
190       gdk_visual_decompose_mask (system_visual->visual.green_mask,
191                                  &system_visual->visual.green_shift,
192                                  &system_visual->visual.green_prec);
193
194       gdk_visual_decompose_mask (system_visual->visual.blue_mask,
195                                  &system_visual->visual.blue_shift,
196                                  &system_visual->visual.blue_prec);
197       system_visual->xvisual->map_entries =
198         1 << (MAX (system_visual->visual.red_prec,
199                    MAX (system_visual->visual.green_prec,
200                         system_visual->visual.blue_prec)));
201     }
202   else
203     {
204       system_visual->visual.red_mask = 0;
205       system_visual->visual.red_shift = 0;
206       system_visual->visual.red_prec = 0;
207
208       system_visual->visual.green_mask = 0;
209       system_visual->visual.green_shift = 0;
210       system_visual->visual.green_prec = 0;
211
212       system_visual->visual.blue_mask = 0;
213       system_visual->visual.blue_shift = 0;
214       system_visual->visual.blue_prec = 0;
215     }
216   system_visual->visual.colormap_size = system_visual->xvisual->map_entries;
217
218   available_depths[0] = system_visual->visual.depth;
219   available_types[0] = system_visual->visual.type;
220 }
221
222 GdkVisual*
223 gdk_visual_ref (GdkVisual *visual)
224 {
225   return visual;
226 }
227
228 void
229 gdk_visual_unref (GdkVisual *visual)
230 {
231   return;
232 }
233
234 gint
235 gdk_visual_get_best_depth (void)
236 {
237   return available_depths[0];
238 }
239
240 GdkVisualType
241 gdk_visual_get_best_type (void)
242 {
243   return available_types[0];
244 }
245
246 GdkVisual*
247 gdk_visual_get_system (void)
248 {
249   return ((GdkVisual*) system_visual);
250 }
251
252 GdkVisual*
253 gdk_visual_get_best (void)
254 {
255   return ((GdkVisual*) system_visual);
256 }
257
258 GdkVisual*
259 gdk_visual_get_best_with_depth (gint depth)
260 {
261   if (depth == system_visual->visual.depth)
262     return (GdkVisual*) system_visual;
263   else
264     return NULL;
265 }
266
267 GdkVisual*
268 gdk_visual_get_best_with_type (GdkVisualType visual_type)
269 {
270   if (visual_type == system_visual->visual.type)
271     return (GdkVisual*) system_visual;
272   else
273     return NULL;
274 }
275
276 GdkVisual*
277 gdk_visual_get_best_with_both (gint          depth,
278                                GdkVisualType visual_type)
279 {
280   if ((depth == system_visual->visual.depth) &&
281       (visual_type == system_visual->visual.type))
282     return (GdkVisual*) system_visual;
283   else
284     return NULL;
285 }
286
287 void
288 gdk_query_depths  (gint **depths,
289                    gint  *count)
290 {
291   *count = 1;
292   *depths = available_depths;
293 }
294
295 void
296 gdk_query_visual_types (GdkVisualType **visual_types,
297                         gint           *count)
298 {
299   *count = 1;
300   *visual_types = available_types;
301 }
302
303 GList*
304 gdk_list_visuals (void)
305 {
306   return g_list_append (NULL, (gpointer) system_visual);
307 }
308
309 GdkVisual*
310 gdk_visual_lookup (Visual *xvisual)
311 {
312   if (system_visual->xvisual == xvisual)
313     return (GdkVisual *) system_visual;
314   else
315     return NULL;
316 }
317
318 static void
319 gdk_visual_decompose_mask (gulong  mask,
320                            gint   *shift,
321                            gint   *prec)
322 {
323   *shift = 0;
324   *prec = 0;
325
326   while (!(mask & 0x1))
327     {
328       (*shift)++;
329       mask >>= 1;
330     }
331
332   while (mask & 0x1)
333     {
334       (*prec)++;
335       mask >>= 1;
336     }
337 }