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