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