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