]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkmain-win32.c
521d478fbae890769360586b043a12b71256f48a
[~andy/gtk] / gdk / win32 / gdkmain-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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
23  * file for a list of people on the GTK+ Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
26  */
27
28 #include "config.h"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <limits.h>
34 #include <io.h>
35
36 #include "gdk.h"
37 #include "gdkregion-generic.h"
38 #include "gdkkeysyms.h"
39 #include "gdkinternals.h"
40 #include "gdkprivate-win32.h"
41 #include "gdkinput-win32.h"
42
43 #include <objbase.h>
44
45 #if defined (__GNUC__) && defined (HAVE_DIMM_H)
46 /* The w32api imm.h clashes a bit with the IE5.5 dimm.h */
47 # define IMEMENUITEMINFOA hidden_IMEMENUITEMINFOA
48 # define IMEMENUITEMINFOW hidden_IMEMENUITEMINFOW
49 #endif
50
51 #include <imm.h>
52
53 static gboolean gdk_synchronize = FALSE;
54
55 GdkArgDesc _gdk_windowing_args[] = {
56   { "sync",          GDK_ARG_BOOL, &gdk_synchronize, (GdkArgFunc) NULL},
57   { "no-wintab",     GDK_ARG_BOOL, &_gdk_input_ignore_wintab,
58                                                      (GdkArgFunc) NULL},
59   { "ignore-wintab", GDK_ARG_BOOL, &_gdk_input_ignore_wintab,
60                                                      (GdkArgFunc) NULL},
61   { "max-colors",    GDK_ARG_INT,  &_gdk_max_colors,  (GdkArgFunc) NULL},
62   { NULL }
63 };
64
65 int __stdcall
66 DllMain (HINSTANCE hinstDLL,
67          DWORD     dwReason,
68          LPVOID    reserved)
69 {
70   _gdk_dll_hinstance = hinstDLL;
71
72   return TRUE;
73 }
74
75 void
76 _gdk_windowing_init (gint    *argc,
77                      gchar ***argv)
78 {
79   gchar buf[10];
80
81 #ifdef HAVE_WINTAB
82   if (getenv ("GDK_IGNORE_WINTAB") != NULL)
83     _gdk_input_ignore_wintab = TRUE;
84 #endif
85
86   if (gdk_synchronize)
87     GdiSetBatchLimit (1);
88
89   _gdk_app_hmodule = GetModuleHandle (NULL);
90   _gdk_display_hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
91   _gdk_root_window = GetDesktopWindow ();
92   _windows_version = GetVersion ();
93
94   if (getenv ("PRETEND_WIN9X"))
95     _windows_version = 0x80000004;
96
97   GDK_NOTE (MISC, g_print ("Windows version: %08x\n", (guint) _windows_version));
98
99   _gdk_input_locale = GetKeyboardLayout (0);
100   GetLocaleInfo (MAKELCID (LOWORD (_gdk_input_locale), SORT_DEFAULT),
101                  LOCALE_IDEFAULTANSICODEPAGE,
102                  buf, sizeof (buf));
103   _gdk_input_codepage = atoi (buf);
104   GDK_NOTE (EVENTS, g_print ("input_locale:%p, codepage:%d\n",
105                              _gdk_input_locale, _gdk_input_codepage));
106
107   CoInitialize (NULL);
108
109   _cf_rtf = RegisterClipboardFormat ("Rich Text Format");
110   _cf_utf8_string = RegisterClipboardFormat ("UTF8_STRING");
111
112   _utf8_string = gdk_atom_intern ("UTF8_STRING", FALSE);
113   _compound_text = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
114   _text_uri_list = gdk_atom_intern ("text/uri-list", FALSE);
115
116   _local_dnd = gdk_atom_intern ("LocalDndSelection", FALSE);
117   _gdk_win32_dropfiles = gdk_atom_intern ("DROPFILES_DND", FALSE);
118   _gdk_ole2_dnd = gdk_atom_intern ("OLE2_DND", FALSE);
119
120   _gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);
121
122   _gdk_win32_selection_init ();
123 }
124
125 void
126 _gdk_win32_api_failed (const gchar *where,
127                       gint         line,
128                       const gchar *api)
129 {
130   gchar *msg = g_win32_error_message (GetLastError ());
131   g_warning ("%s:%d: %s failed: %s", where, line, api, msg);
132   g_free (msg);
133 }
134
135 void
136 _gdk_other_api_failed (const gchar *where,
137                       gint         line,
138                       const gchar *api)
139 {
140   g_warning ("%s:%d: %s failed", where, line, api);
141 }
142
143 void
144 _gdk_win32_gdi_failed (const gchar *where,
145                       gint         line,
146                       const gchar *api)
147 {
148   /* On Win9x GDI calls are implemented in 16-bit code and thus
149    * don't set the 32-bit error code, sigh.
150    */
151   if (IS_WIN_NT ())
152     _gdk_win32_api_failed (where, line, api);
153   else
154     _gdk_other_api_failed (where, line, api);
155 }
156
157 void
158 gdk_set_use_xshm (gboolean use_xshm)
159 {
160   /* Always on */
161 }
162
163 gboolean
164 gdk_get_use_xshm (void)
165 {
166   return TRUE;
167 }
168
169 gint
170 gdk_screen_get_width (GdkScreen *screen)
171 {
172   return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_parent_root)->impl)->width;
173 }
174
175 gint
176 gdk_screen_get_height (GdkScreen *screen)
177 {
178   return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_parent_root)->impl)->height;
179 }
180 gint
181 gdk_screen_get_width_mm (GdkScreen *screen)
182 {
183   return (double) GetDeviceCaps (_gdk_display_hdc, HORZRES) / GetDeviceCaps (_gdk_display_hdc, LOGPIXELSX) * 25.4;
184 }
185
186 gint
187 gdk_screen_get_height_mm (GdkScreen *screen)
188 {
189   return (double) GetDeviceCaps (_gdk_display_hdc, VERTRES) / GetDeviceCaps (_gdk_display_hdc, LOGPIXELSY) * 25.4;
190 }
191
192 void
193 _gdk_windowing_display_set_sm_client_id (GdkDisplay  *display,
194                                          const gchar *sm_client_id)
195 {
196   g_warning("gdk_set_sm_client_id %s", sm_client_id ? sm_client_id : "NULL");
197 }
198
199 void
200 gdk_display_beep (GdkDisplay *display)
201 {
202   g_return_if_fail (display == gdk_display_get_default());
203   Beep(1000, 50);
204 }
205
206 void
207 _gdk_windowing_exit (void)
208 {
209   _gdk_win32_dnd_exit ();
210   CoUninitialize ();
211   DeleteDC (_gdk_display_hdc);
212   _gdk_display_hdc = NULL;
213 }
214
215 gchar *
216 gdk_get_display (void)
217 {
218   return g_strdup (gdk_display_get_name (gdk_display_get_default ()));
219 }
220
221 void
222 gdk_error_trap_push (void)
223 {
224 }
225
226 gint
227 gdk_error_trap_pop (void)
228 {
229   return 0;
230 }
231
232 void
233 gdk_notify_startup_complete (void)
234 {
235 }
236
237 #ifdef G_ENABLE_DEBUG
238
239 /*
240  * Like g_strdup_printf, but to a static buffer. Return value does not
241  * have to be g_free()d. The buffer is of bounded size and reused
242  * cyclically. Thus the return value is valid only until that part of
243  * the buffer happens to get reused. This doesn't matter as this
244  * function's return value is used in debugging output right after the call,
245  * and the return value isn't used after that.
246  */
247 static gchar *
248 static_printf (const gchar *format,
249                          ...)
250 {
251   static gchar buf[10000];
252   gchar *msg;
253   static gchar *bufp = buf;
254   gchar *retval;
255   va_list args;
256
257   va_start (args, format);
258   msg = g_strdup_vprintf (format, args);
259   va_end (args);
260
261   g_assert (strlen (msg) < sizeof (buf));
262
263   if (bufp + strlen (msg) + 1 > buf + sizeof (buf))
264     bufp = buf;
265   retval = bufp;
266
267   strcpy (bufp, msg);
268   bufp += strlen (msg) + 1;
269   g_free (msg);
270
271   return retval;
272 }
273
274 gchar *
275 _gdk_win32_color_to_string (const GdkColor *color)
276 {
277   return static_printf ("(%.04x,%.04x,%.04x):%.06x",
278                         color->red, color->green,
279                         color->blue, color->pixel);
280 }
281
282 void
283 _gdk_win32_print_paletteentries (const PALETTEENTRY *pep,
284                                 const int           nentries)
285 {
286   char buf[20];
287   int i;
288
289   for (i = 0; i < nentries; i++)
290     g_print ("  %3d %02x:  %02x %02x %02x%s\n",
291              i, i,
292              pep[i].peRed, pep[i].peGreen, pep[i].peBlue,
293              (pep[i].peFlags == 0 ? "" :
294               (pep[i].peFlags == PC_EXPLICIT ? " PC_EXPLICIT" :
295                (pep[i].peFlags == PC_NOCOLLAPSE ? " PC_NOCOLLAPSE" :
296                 (pep[i].peFlags == PC_RESERVED ? " PC_RESERVED" :
297                  (sprintf (buf, " %d", pep[i].peFlags), buf))))));
298 }
299
300 void
301 _gdk_win32_print_system_palette (void)
302 {
303   PALETTEENTRY *pe;
304   int k;
305
306   k = GetSystemPaletteEntries (_gdk_display_hdc, 0, 0, NULL);
307   pe = g_new (PALETTEENTRY, k);
308   k = GetSystemPaletteEntries (_gdk_display_hdc, 0, k, pe);
309
310   if (!k)
311     g_print ("GetSystemPaletteEntries failed: %s\n",
312              g_win32_error_message (GetLastError ()));
313   else
314     {
315       g_print ("System palette: %d entries\n", k);
316       _gdk_win32_print_paletteentries (pe, k);
317     }
318   g_free (pe);
319 }
320
321 static gint
322 palette_size (HPALETTE hpal)
323 {
324   WORD npal = 0;
325
326   if (!GetObject (hpal, sizeof (npal), &npal))
327     WIN32_GDI_FAILED ("GetObject (HPALETTE)");
328
329   return npal;
330 }
331
332 void
333 _gdk_win32_print_hpalette (HPALETTE hpal)
334 {
335   PALETTEENTRY *pe;
336   gint n, npal;
337
338   npal = palette_size (hpal);
339   pe = g_new (PALETTEENTRY, npal);
340   n = GetPaletteEntries (hpal, 0, npal, pe);
341
342   if (!n)
343     g_print ("HPALETTE %p: GetPaletteEntries failed: %s\n",
344              hpal, g_win32_error_message (GetLastError ()));
345   else
346     {
347       g_print ("HPALETTE %p: %d (%d) entries\n", hpal, n, npal);
348       _gdk_win32_print_paletteentries (pe, n);
349     }
350   g_free (pe);
351 }
352
353 void
354 _gdk_win32_print_dc (HDC hdc)
355 {
356   HGDIOBJ obj;
357   LOGBRUSH logbrush;
358   EXTLOGPEN extlogpen;
359   HRGN hrgn;
360   RECT rect;
361   int flag;
362
363   g_print ("%p:\n", hdc);
364   obj = GetCurrentObject (hdc, OBJ_BRUSH);
365   GetObject (obj, sizeof (LOGBRUSH), &logbrush);
366   g_print ("brush: %s color=%06lx hatch=%p\n",
367            _gdk_win32_lbstyle_to_string (logbrush.lbStyle),
368            logbrush.lbColor, (gpointer) logbrush.lbHatch);
369   obj = GetCurrentObject (hdc, OBJ_PEN);
370   GetObject (obj, sizeof (EXTLOGPEN), &extlogpen);
371   g_print ("pen: %s %s %s %s w=%d %s\n",
372            _gdk_win32_pstype_to_string (extlogpen.elpPenStyle),
373            _gdk_win32_psstyle_to_string (extlogpen.elpPenStyle),
374            _gdk_win32_psendcap_to_string (extlogpen.elpPenStyle),
375            _gdk_win32_psjoin_to_string (extlogpen.elpPenStyle),
376            extlogpen.elpWidth,
377            _gdk_win32_lbstyle_to_string (extlogpen.elpBrushStyle));
378   g_print ("rop2: %s textcolor=%06lx\n",
379            _gdk_win32_rop2_to_string (GetROP2 (hdc)),
380            GetTextColor (hdc));
381   hrgn = CreateRectRgn (0, 0, 0, 0);
382   if ((flag = GetClipRgn (hdc, hrgn)) == -1)
383     WIN32_API_FAILED ("GetClipRgn");
384   else if (flag == 0)
385     g_print ("no clip region\n");
386   else if (flag == 1)
387     {
388       GetRgnBox (hrgn, &rect);
389       g_print ("clip region: %p bbox: %s\n",
390                hrgn, _gdk_win32_rect_to_string (&rect));
391     }
392   DeleteObject (hrgn);
393 }
394
395 gchar *
396 _gdk_win32_cap_style_to_string (GdkCapStyle cap_style)
397 {
398   switch (cap_style)
399     {
400 #define CASE(x) case GDK_CAP_##x: return #x
401     CASE (NOT_LAST);
402     CASE (BUTT);
403     CASE (ROUND);
404     CASE (PROJECTING);
405 #undef CASE
406     default: return static_printf ("illegal_%d", cap_style);
407     }
408   /* NOTREACHED */
409   return NULL;
410 }
411
412 gchar *
413 _gdk_win32_fill_style_to_string (GdkFill fill)
414 {
415   switch (fill)
416     {
417 #define CASE(x) case GDK_##x: return #x
418     CASE (SOLID);
419     CASE (TILED);
420     CASE (STIPPLED);
421     CASE (OPAQUE_STIPPLED);
422 #undef CASE
423     default: return static_printf ("illegal_%d", fill);
424     }
425   /* NOTREACHED */
426   return NULL;
427 }
428
429 gchar *
430 _gdk_win32_function_to_string (GdkFunction function)
431 {
432   switch (function)
433     {
434 #define CASE(x) case GDK_##x: return #x
435     CASE (COPY);
436     CASE (INVERT);
437     CASE (XOR);
438     CASE (CLEAR);
439     CASE (AND);
440     CASE (AND_REVERSE);
441     CASE (AND_INVERT);
442     CASE (NOOP);
443     CASE (OR);
444     CASE (EQUIV);
445     CASE (OR_REVERSE);
446     CASE (COPY_INVERT);
447     CASE (OR_INVERT);
448     CASE (NAND);
449     CASE (SET);
450 #undef CASE
451     default: return static_printf ("illegal_%d", function);
452     }
453   /* NOTREACHED */
454   return NULL; 
455 }
456
457 gchar *
458 _gdk_win32_join_style_to_string (GdkJoinStyle join_style)
459 {
460   switch (join_style)
461     {
462 #define CASE(x) case GDK_JOIN_##x: return #x
463     CASE (MITER);
464     CASE (ROUND);
465     CASE (BEVEL);
466 #undef CASE
467     default: return static_printf ("illegal_%d", join_style);
468     }
469   /* NOTREACHED */
470   return NULL; 
471 }
472
473 gchar *
474 _gdk_win32_line_style_to_string (GdkLineStyle line_style)
475 {
476   switch (line_style)
477     {
478 #define CASE(x) case GDK_LINE_##x: return #x
479     CASE(SOLID);
480     CASE(ON_OFF_DASH);  
481     CASE(DOUBLE_DASH);  
482 #undef CASE
483     default: return static_printf ("illegal_%d", line_style);
484     }
485   /* NOTREACHED */
486   return NULL; 
487 }
488
489 gchar *
490 _gdk_win32_gcvalues_mask_to_string (GdkGCValuesMask mask)
491 {
492   gchar buf[400];
493   gchar *bufp = buf;
494   gchar *s = "";
495
496   buf[0] = '\0';
497
498 #define BIT(x)                                          \
499   if (mask & GDK_GC_##x)                                \
500     (bufp += sprintf (bufp, "%s" #x, s), s = "|")
501
502   BIT (FOREGROUND);
503   BIT (BACKGROUND);
504   BIT (FONT);
505   BIT (FUNCTION);
506   BIT (FILL);
507   BIT (TILE);
508   BIT (STIPPLE);
509   BIT (CLIP_MASK);
510   BIT (SUBWINDOW);
511   BIT (TS_X_ORIGIN);
512   BIT (TS_Y_ORIGIN);
513   BIT (CLIP_X_ORIGIN);
514   BIT (CLIP_Y_ORIGIN);
515   BIT (EXPOSURES);
516   BIT (LINE_WIDTH);
517   BIT (LINE_STYLE);
518   BIT (CAP_STYLE);
519   BIT (JOIN_STYLE);
520 #undef BIT
521
522   return static_printf ("%s", buf);  
523 }
524
525 gchar *
526 _gdk_win32_window_state_to_string (GdkWindowState state)
527 {
528   gchar buf[100];
529   gchar *bufp = buf;
530   gchar *s = "";
531
532   buf[0] = '\0';
533
534 #define BIT(x)                                          \
535   if (state & GDK_WINDOW_STATE_ ## x)                   \
536     (bufp += sprintf (bufp, "%s" #x, s), s = "|")
537
538   /* For clarity, also show the complement of WITHDRAWN, i.e. "MAPPED" */
539   if (!(state & GDK_WINDOW_STATE_WITHDRAWN))
540     (bufp += sprintf (bufp, "MAPPED"), s = "|");
541
542   BIT (WITHDRAWN);
543   BIT (ICONIFIED);
544   BIT (MAXIMIZED);
545   BIT (STICKY);
546 #undef BIT
547
548   return static_printf ("%s", buf);  
549 }
550
551 gchar *
552 _gdk_win32_rop2_to_string (int rop2)
553 {
554   switch (rop2)
555     {
556 #define CASE(x) case R2_##x: return #x
557       CASE (BLACK);
558       CASE (COPYPEN);
559       CASE (MASKNOTPEN);
560       CASE (MASKPEN);
561       CASE (MASKPENNOT);
562       CASE (MERGENOTPEN);
563       CASE (MERGEPEN);
564       CASE (MERGEPENNOT);
565       CASE (NOP);
566       CASE (NOT);
567       CASE (NOTCOPYPEN);
568       CASE (NOTMASKPEN);
569       CASE (NOTMERGEPEN);
570       CASE (NOTXORPEN);
571       CASE (WHITE);
572       CASE (XORPEN);
573 #undef CASE
574     default: return static_printf ("illegal_%x", rop2);
575     }
576   /* NOTREACHED */
577   return NULL;
578 }
579
580 gchar *
581 _gdk_win32_lbstyle_to_string (UINT brush_style)
582 {
583   switch (brush_style)
584     {
585 #define CASE(x) case BS_##x: return #x
586       CASE (DIBPATTERN);
587       CASE (DIBPATTERNPT);
588       CASE (HATCHED);
589       CASE (HOLLOW);
590       CASE (PATTERN);
591       CASE (SOLID);
592 #undef CASE
593     default: return static_printf ("illegal_%d", brush_style);
594     }
595   /* NOTREACHED */
596   return NULL;
597 }
598
599 gchar *
600 _gdk_win32_pstype_to_string (DWORD pen_style)
601 {
602   switch (pen_style & PS_TYPE_MASK)
603     {
604     case PS_GEOMETRIC: return "GEOMETRIC";
605     case PS_COSMETIC: return "COSMETIC";
606     default: return static_printf ("illegal_%d", pen_style & PS_TYPE_MASK);
607     }
608   /* NOTREACHED */
609   return NULL;
610 }
611
612 gchar *
613 _gdk_win32_psstyle_to_string (DWORD pen_style)
614 {
615   switch (pen_style & PS_STYLE_MASK)
616     {
617 #define CASE(x) case PS_##x: return #x
618       CASE (DASH);
619       CASE (DASHDOT);
620       CASE (DASHDOTDOT);
621       CASE (DOT);
622       CASE (INSIDEFRAME);
623       CASE (NULL);
624       CASE (SOLID);
625       CASE (USERSTYLE);
626 #undef CASE
627     default: return static_printf ("illegal_%d", pen_style & PS_STYLE_MASK);
628     }
629   /* NOTREACHED */
630   return NULL;
631 }
632
633 gchar *
634 _gdk_win32_psendcap_to_string (DWORD pen_style)
635 {
636   switch (pen_style & PS_ENDCAP_MASK)
637     {
638 #define CASE(x) case PS_ENDCAP_##x: return #x
639       CASE (FLAT);
640       CASE (ROUND);
641       CASE (SQUARE);
642 #undef CASE
643     default: return static_printf ("illegal_%d", pen_style & PS_ENDCAP_MASK);
644     }
645   /* NOTREACHED */
646   return NULL;
647 }
648
649 gchar *
650 _gdk_win32_psjoin_to_string (DWORD pen_style)
651 {
652   switch (pen_style & PS_JOIN_MASK)
653     {
654 #define CASE(x) case PS_JOIN_##x: return #x
655       CASE (BEVEL);
656       CASE (MITER);
657       CASE (ROUND);
658 #undef CASE
659     default: return static_printf ("illegal_%d", pen_style & PS_JOIN_MASK);
660     }
661   /* NOTREACHED */
662   return NULL;
663 }
664
665 gchar *
666 _gdk_win32_message_to_string (UINT msg)
667 {
668   switch (msg)
669     {
670 #define CASE(x) case x: return #x
671       CASE (WM_NULL);
672       CASE (WM_CREATE);
673       CASE (WM_DESTROY);
674       CASE (WM_MOVE);
675       CASE (WM_SIZE);
676       CASE (WM_ACTIVATE);
677       CASE (WM_SETFOCUS);
678       CASE (WM_KILLFOCUS);
679       CASE (WM_ENABLE);
680       CASE (WM_SETREDRAW);
681       CASE (WM_SETTEXT);
682       CASE (WM_GETTEXT);
683       CASE (WM_GETTEXTLENGTH);
684       CASE (WM_PAINT);
685       CASE (WM_CLOSE);
686       CASE (WM_QUERYENDSESSION);
687       CASE (WM_QUERYOPEN);
688       CASE (WM_ENDSESSION);
689       CASE (WM_QUIT);
690       CASE (WM_ERASEBKGND);
691       CASE (WM_SYSCOLORCHANGE);
692       CASE (WM_SHOWWINDOW);
693       CASE (WM_WININICHANGE);
694       CASE (WM_DEVMODECHANGE);
695       CASE (WM_ACTIVATEAPP);
696       CASE (WM_FONTCHANGE);
697       CASE (WM_TIMECHANGE);
698       CASE (WM_CANCELMODE);
699       CASE (WM_SETCURSOR);
700       CASE (WM_MOUSEACTIVATE);
701       CASE (WM_CHILDACTIVATE);
702       CASE (WM_QUEUESYNC);
703       CASE (WM_GETMINMAXINFO);
704       CASE (WM_PAINTICON);
705       CASE (WM_ICONERASEBKGND);
706       CASE (WM_NEXTDLGCTL);
707       CASE (WM_SPOOLERSTATUS);
708       CASE (WM_DRAWITEM);
709       CASE (WM_MEASUREITEM);
710       CASE (WM_DELETEITEM);
711       CASE (WM_VKEYTOITEM);
712       CASE (WM_CHARTOITEM);
713       CASE (WM_SETFONT);
714       CASE (WM_GETFONT);
715       CASE (WM_SETHOTKEY);
716       CASE (WM_GETHOTKEY);
717       CASE (WM_QUERYDRAGICON);
718       CASE (WM_COMPAREITEM);
719       CASE (WM_GETOBJECT);
720       CASE (WM_COMPACTING);
721       CASE (WM_WINDOWPOSCHANGING);
722       CASE (WM_WINDOWPOSCHANGED);
723       CASE (WM_POWER);
724       CASE (WM_COPYDATA);
725       CASE (WM_CANCELJOURNAL);
726       CASE (WM_NOTIFY);
727       CASE (WM_INPUTLANGCHANGEREQUEST);
728       CASE (WM_INPUTLANGCHANGE);
729       CASE (WM_TCARD);
730       CASE (WM_HELP);
731       CASE (WM_USERCHANGED);
732       CASE (WM_NOTIFYFORMAT);
733       CASE (WM_CONTEXTMENU);
734       CASE (WM_STYLECHANGING);
735       CASE (WM_STYLECHANGED);
736       CASE (WM_DISPLAYCHANGE);
737       CASE (WM_GETICON);
738       CASE (WM_SETICON);
739       CASE (WM_NCCREATE);
740       CASE (WM_NCDESTROY);
741       CASE (WM_NCCALCSIZE);
742       CASE (WM_NCHITTEST);
743       CASE (WM_NCPAINT);
744       CASE (WM_NCACTIVATE);
745       CASE (WM_GETDLGCODE);
746       CASE (WM_SYNCPAINT);
747       CASE (WM_NCMOUSEMOVE);
748       CASE (WM_NCLBUTTONDOWN);
749       CASE (WM_NCLBUTTONUP);
750       CASE (WM_NCLBUTTONDBLCLK);
751       CASE (WM_NCRBUTTONDOWN);
752       CASE (WM_NCRBUTTONUP);
753       CASE (WM_NCRBUTTONDBLCLK);
754       CASE (WM_NCMBUTTONDOWN);
755       CASE (WM_NCMBUTTONUP);
756       CASE (WM_NCMBUTTONDBLCLK);
757       CASE (WM_NCXBUTTONDOWN);
758       CASE (WM_NCXBUTTONUP);
759       CASE (WM_NCXBUTTONDBLCLK);
760       CASE (WM_KEYDOWN);
761       CASE (WM_KEYUP);
762       CASE (WM_CHAR);
763       CASE (WM_DEADCHAR);
764       CASE (WM_SYSKEYDOWN);
765       CASE (WM_SYSKEYUP);
766       CASE (WM_SYSCHAR);
767       CASE (WM_SYSDEADCHAR);
768       CASE (WM_KEYLAST);
769       CASE (WM_IME_STARTCOMPOSITION);
770       CASE (WM_IME_ENDCOMPOSITION);
771       CASE (WM_IME_COMPOSITION);
772       CASE (WM_INITDIALOG);
773       CASE (WM_COMMAND);
774       CASE (WM_SYSCOMMAND);
775       CASE (WM_TIMER);
776       CASE (WM_HSCROLL);
777       CASE (WM_VSCROLL);
778       CASE (WM_INITMENU);
779       CASE (WM_INITMENUPOPUP);
780       CASE (WM_MENUSELECT);
781       CASE (WM_MENUCHAR);
782       CASE (WM_ENTERIDLE);
783       CASE (WM_MENURBUTTONUP);
784       CASE (WM_MENUDRAG);
785       CASE (WM_MENUGETOBJECT);
786       CASE (WM_UNINITMENUPOPUP);
787       CASE (WM_MENUCOMMAND);
788       CASE (WM_CHANGEUISTATE);
789       CASE (WM_UPDATEUISTATE);
790       CASE (WM_QUERYUISTATE);
791       CASE (WM_CTLCOLORMSGBOX);
792       CASE (WM_CTLCOLOREDIT);
793       CASE (WM_CTLCOLORLISTBOX);
794       CASE (WM_CTLCOLORBTN);
795       CASE (WM_CTLCOLORDLG);
796       CASE (WM_CTLCOLORSCROLLBAR);
797       CASE (WM_CTLCOLORSTATIC);
798       CASE (WM_MOUSEMOVE);
799       CASE (WM_LBUTTONDOWN);
800       CASE (WM_LBUTTONUP);
801       CASE (WM_LBUTTONDBLCLK);
802       CASE (WM_RBUTTONDOWN);
803       CASE (WM_RBUTTONUP);
804       CASE (WM_RBUTTONDBLCLK);
805       CASE (WM_MBUTTONDOWN);
806       CASE (WM_MBUTTONUP);
807       CASE (WM_MBUTTONDBLCLK);
808       CASE (WM_MOUSEWHEEL);
809       CASE (WM_XBUTTONDOWN);
810       CASE (WM_XBUTTONUP);
811       CASE (WM_XBUTTONDBLCLK);
812       CASE (WM_PARENTNOTIFY);
813       CASE (WM_ENTERMENULOOP);
814       CASE (WM_EXITMENULOOP);
815       CASE (WM_NEXTMENU);
816       CASE (WM_SIZING);
817       CASE (WM_CAPTURECHANGED);
818       CASE (WM_MOVING);
819       CASE (WM_POWERBROADCAST);
820       CASE (WM_DEVICECHANGE);
821       CASE (WM_MDICREATE);
822       CASE (WM_MDIDESTROY);
823       CASE (WM_MDIACTIVATE);
824       CASE (WM_MDIRESTORE);
825       CASE (WM_MDINEXT);
826       CASE (WM_MDIMAXIMIZE);
827       CASE (WM_MDITILE);
828       CASE (WM_MDICASCADE);
829       CASE (WM_MDIICONARRANGE);
830       CASE (WM_MDIGETACTIVE);
831       CASE (WM_MDISETMENU);
832       CASE (WM_ENTERSIZEMOVE);
833       CASE (WM_EXITSIZEMOVE);
834       CASE (WM_DROPFILES);
835       CASE (WM_MDIREFRESHMENU);
836       CASE (WM_IME_SETCONTEXT);
837       CASE (WM_IME_NOTIFY);
838       CASE (WM_IME_CONTROL);
839       CASE (WM_IME_COMPOSITIONFULL);
840       CASE (WM_IME_SELECT);
841       CASE (WM_IME_CHAR);
842       CASE (WM_IME_REQUEST);
843       CASE (WM_IME_KEYDOWN);
844       CASE (WM_IME_KEYUP);
845       CASE (WM_MOUSEHOVER);
846       CASE (WM_MOUSELEAVE);
847       CASE (WM_NCMOUSEHOVER);
848       CASE (WM_NCMOUSELEAVE);
849       CASE (WM_CUT);
850       CASE (WM_COPY);
851       CASE (WM_PASTE);
852       CASE (WM_CLEAR);
853       CASE (WM_UNDO);
854       CASE (WM_RENDERFORMAT);
855       CASE (WM_RENDERALLFORMATS);
856       CASE (WM_DESTROYCLIPBOARD);
857       CASE (WM_DRAWCLIPBOARD);
858       CASE (WM_PAINTCLIPBOARD);
859       CASE (WM_VSCROLLCLIPBOARD);
860       CASE (WM_SIZECLIPBOARD);
861       CASE (WM_ASKCBFORMATNAME);
862       CASE (WM_CHANGECBCHAIN);
863       CASE (WM_HSCROLLCLIPBOARD);
864       CASE (WM_QUERYNEWPALETTE);
865       CASE (WM_PALETTEISCHANGING);
866       CASE (WM_PALETTECHANGED);
867       CASE (WM_HOTKEY);
868       CASE (WM_PRINT);
869       CASE (WM_PRINTCLIENT);
870       CASE (WM_APPCOMMAND);
871       CASE (WM_HANDHELDFIRST);
872       CASE (WM_HANDHELDLAST);
873       CASE (WM_AFXFIRST);
874       CASE (WM_AFXLAST);
875       CASE (WM_PENWINFIRST);
876       CASE (WM_PENWINLAST);
877       CASE (WM_APP);
878 #undef CASE
879     default:
880       if (msg >= WM_HANDHELDFIRST && msg <= WM_HANDHELDLAST)
881         return static_printf ("WM_HANDHELDFIRST+%d", msg - WM_HANDHELDFIRST);
882       else if (msg >= WM_AFXFIRST && msg <= WM_AFXLAST)
883         return static_printf ("WM_AFXFIRST+%d", msg - WM_AFXFIRST);
884       else if (msg >= WM_PENWINFIRST && msg <= WM_PENWINLAST)
885         return static_printf ("WM_PENWINFIRST+%d", msg - WM_PENWINFIRST);
886       else if (msg >= WM_USER && msg <= 0x7FFF)
887         return static_printf ("WM_USER+%d", msg - WM_USER);
888       else if (msg >= 0xC000 && msg <= 0xFFFF)
889         return static_printf ("reg-%#x", msg);
890       else
891         return static_printf ("unk-%#x", msg);
892     }
893   /* NOTREACHED */
894   return NULL;
895 }
896
897 gchar *
898 _gdk_win32_rect_to_string (const RECT *rect)
899 {
900   return static_printf ("%ldx%ld@+%ld+%ld",
901                         (rect->right - rect->left), (rect->bottom - rect->top),
902                         rect->left, rect->top);
903 }
904
905 gchar *
906 _gdk_win32_gdkrectangle_to_string (const GdkRectangle *rect)
907 {
908   return static_printf ("%dx%d@+%d+%d",
909                         rect->width, rect->height,
910                         rect->x, rect->y);
911 }
912
913 gchar *
914 _gdk_win32_gdkregion_to_string (const GdkRegion *rgn)
915 {
916   return static_printf ("%dx%d@+%d+%d",
917                         (rgn->extents.x2 - rgn->extents.x1),
918                         (rgn->extents.y2 - rgn->extents.y1),
919                         rgn->extents.x1, rgn->extents.y1);
920 }
921
922 gchar *
923 _gdk_win32_drawable_description (GdkDrawable *d)
924 {
925   GdkVisual *v;
926   gint width, height;
927
928   gdk_drawable_get_size (d, &width, &height);
929
930   return static_printf
931     ("%s:%p:%dx%dx%d",
932      G_OBJECT_TYPE_NAME (d),
933      GDK_DRAWABLE_HANDLE (d),
934      width, height,
935      (GDK_IS_PIXMAP (d) ? GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (d)->impl)->image->depth
936       : ((v = gdk_drawable_get_visual (d)) ? v->depth : gdk_visual_get_system ()->depth)));
937 }
938
939 #endif /* G_ENABLE_DEBUG */