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