]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkmain-win32.c
Fix win32 build
[~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 "gdkkeysyms.h"
38 #include "gdkinternals.h"
39 #include "gdkintl.h"
40 #include "gdkprivate-win32.h"
41 #include "gdkwin32.h"
42
43 #include <objbase.h>
44
45 #include <windows.h>
46 #include <wintab.h>
47 #include <imm.h>
48
49 static gboolean gdk_synchronize = FALSE;
50
51 static gboolean dummy;
52
53 const GOptionEntry _gdk_windowing_args[] = {
54   { "sync", 0, 0, G_OPTION_ARG_NONE, &gdk_synchronize, 
55     /* Description of --sync in --help output */              N_("Don't batch GDI requests"), NULL },
56   { "no-wintab", 0, 0, G_OPTION_ARG_NONE, &_gdk_input_ignore_wintab, 
57     /* Description of --no-wintab in --help output */         N_("Don't use the Wintab API for tablet support"), NULL },
58   { "ignore-wintab", 0, 0, G_OPTION_ARG_NONE, &_gdk_input_ignore_wintab, 
59     /* Description of --ignore-wintab in --help output */     N_("Same as --no-wintab"), NULL },
60   { "use-wintab", 0, 0, G_OPTION_ARG_NONE, &dummy,
61     /* Description of --use-wintab in --help output */     N_("Do use the Wintab API [default]"), NULL },
62   { "max-colors", 0, 0, G_OPTION_ARG_INT, &_gdk_max_colors, 
63     /* Description of --max-colors=COLORS in --help output */ N_("Size of the palette in 8 bit mode"), 
64     /* Placeholder in --max-colors=COLORS in --help output */ N_("COLORS") },
65   { NULL }
66 };
67
68 BOOL WINAPI
69 DllMain (HINSTANCE hinstDLL,
70          DWORD     dwReason,
71          LPVOID    reserved)
72 {
73   _gdk_dll_hinstance = hinstDLL;
74
75   return TRUE;
76 }
77
78 void
79 _gdk_win32_windowing_init (void)
80 {
81   gchar buf[10];
82
83   if (getenv ("GDK_IGNORE_WINTAB") != NULL)
84     _gdk_input_ignore_wintab = TRUE;
85   else if (getenv ("GDK_USE_WINTAB") != NULL)
86     _gdk_input_ignore_wintab = FALSE;
87
88   if (gdk_synchronize)
89     GdiSetBatchLimit (1);
90
91   _gdk_app_hmodule = GetModuleHandle (NULL);
92   _gdk_display_hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
93   _gdk_input_locale = GetKeyboardLayout (0);
94   _gdk_input_locale_is_ime = ImmIsIME (_gdk_input_locale);
95   GetLocaleInfo (MAKELCID (LOWORD (_gdk_input_locale), SORT_DEFAULT),
96                  LOCALE_IDEFAULTANSICODEPAGE,
97                  buf, sizeof (buf));
98   _gdk_input_codepage = atoi (buf);
99   GDK_NOTE (EVENTS, g_print ("input_locale:%p, codepage:%d\n",
100                              _gdk_input_locale, _gdk_input_codepage));
101
102   CoInitialize (NULL);
103
104   _gdk_selection = gdk_atom_intern_static_string ("GDK_SELECTION");
105   _wm_transient_for = gdk_atom_intern_static_string ("WM_TRANSIENT_FOR");
106   _targets = gdk_atom_intern_static_string ("TARGETS");
107   _delete = gdk_atom_intern_static_string ("DELETE");
108   _save_targets = gdk_atom_intern_static_string ("SAVE_TARGETS");
109   _utf8_string = gdk_atom_intern_static_string ("UTF8_STRING");
110   _text = gdk_atom_intern_static_string ("TEXT");
111   _compound_text = gdk_atom_intern_static_string ("COMPOUND_TEXT");
112   _text_uri_list = gdk_atom_intern_static_string ("text/uri-list");
113   _text_html = gdk_atom_intern_static_string ("text/html");
114   _image_png = gdk_atom_intern_static_string ("image/png");
115   _image_jpeg = gdk_atom_intern_static_string ("image/jpeg");
116   _image_bmp = gdk_atom_intern_static_string ("image/bmp");
117   _image_gif = gdk_atom_intern_static_string ("image/gif");
118
119   _local_dnd = gdk_atom_intern_static_string ("LocalDndSelection");
120   _gdk_win32_dropfiles = gdk_atom_intern_static_string ("DROPFILES_DND");
121   _gdk_ole2_dnd = gdk_atom_intern_static_string ("OLE2_DND");
122
123   /* MS Office 2007, at least, offers images in common file formats
124    * using clipboard format names like "PNG" and "JFIF". So we follow
125    * the lead and map the GDK target name "image/png" to the clipboard
126    * format name "PNG" etc.
127    */
128   _cf_png = RegisterClipboardFormat ("PNG");
129   _cf_jfif = RegisterClipboardFormat ("JFIF");
130   _cf_gif = RegisterClipboardFormat ("GIF");
131
132   _cf_url = RegisterClipboardFormat ("UniformResourceLocatorW");
133   _cf_html_format = RegisterClipboardFormat ("HTML Format");
134   _cf_text_html = RegisterClipboardFormat ("text/html");
135
136   _gdk_win32_selection_init ();
137 }
138
139 void
140 _gdk_win32_api_failed (const gchar *where,
141                       const gchar *api)
142 {
143   gchar *msg = g_win32_error_message (GetLastError ());
144   g_warning ("%s: %s failed: %s", where, api, msg);
145   g_free (msg);
146 }
147
148 void
149 _gdk_other_api_failed (const gchar *where,
150                       const gchar *api)
151 {
152   g_warning ("%s: %s failed", where, api);
153 }
154
155
156 #ifdef G_ENABLE_DEBUG
157
158 /*
159  * Like g_strdup_printf, but to a static buffer. Return value does not
160  * have to be g_free()d. The buffer is of bounded size and reused
161  * cyclically. Thus the return value is valid only until that part of
162  * the buffer happens to get reused. This doesn't matter as this
163  * function's return value is used in debugging output right after the call,
164  * and the return value isn't used after that.
165  */
166 static gchar *
167 static_printf (const gchar *format,
168                ...)
169 {
170   static gchar buf[10000];
171   gchar *msg;
172   static gchar *bufp = buf;
173   gchar *retval;
174   va_list args;
175
176   va_start (args, format);
177   msg = g_strdup_vprintf (format, args);
178   va_end (args);
179
180   g_assert (strlen (msg) < sizeof (buf));
181
182   if (bufp + strlen (msg) + 1 > buf + sizeof (buf))
183     bufp = buf;
184   retval = bufp;
185
186   strcpy (bufp, msg);
187   bufp += strlen (msg) + 1;
188   g_free (msg);
189
190   return retval;
191 }
192
193 gchar *
194 _gdk_win32_color_to_string (const GdkColor *color)
195 {
196   return static_printf ("(%.04x,%.04x,%.04x):%.06x",
197                         color->red, color->green,
198                         color->blue, color->pixel);
199 }
200
201 void
202 _gdk_win32_print_paletteentries (const PALETTEENTRY *pep,
203                                 const int           nentries)
204 {
205   char buf[20];
206   int i;
207
208   for (i = 0; i < nentries; i++)
209     g_print ("  %3d %02x:  %02x %02x %02x%s\n",
210              i, i,
211              pep[i].peRed, pep[i].peGreen, pep[i].peBlue,
212              (pep[i].peFlags == 0 ? "" :
213               (pep[i].peFlags == PC_EXPLICIT ? " PC_EXPLICIT" :
214                (pep[i].peFlags == PC_NOCOLLAPSE ? " PC_NOCOLLAPSE" :
215                 (pep[i].peFlags == PC_RESERVED ? " PC_RESERVED" :
216                  (g_sprintf (buf, " %d", pep[i].peFlags), buf))))));
217 }
218
219 void
220 _gdk_win32_print_system_palette (void)
221 {
222   PALETTEENTRY *pe;
223   int k;
224
225   k = GetSystemPaletteEntries (_gdk_display_hdc, 0, 0, NULL);
226   pe = g_new (PALETTEENTRY, k);
227   k = GetSystemPaletteEntries (_gdk_display_hdc, 0, k, pe);
228
229   if (!k)
230     g_print ("GetSystemPaletteEntries failed: %s\n",
231              g_win32_error_message (GetLastError ()));
232   else
233     {
234       g_print ("System palette: %d entries\n", k);
235       _gdk_win32_print_paletteentries (pe, k);
236     }
237   g_free (pe);
238 }
239
240 static gint
241 palette_size (HPALETTE hpal)
242 {
243   WORD npal = 0;
244
245   if (!GetObject (hpal, sizeof (npal), &npal))
246     WIN32_GDI_FAILED ("GetObject (HPALETTE)");
247
248   return npal;
249 }
250
251 void
252 _gdk_win32_print_hpalette (HPALETTE hpal)
253 {
254   PALETTEENTRY *pe;
255   gint n, npal;
256
257   npal = palette_size (hpal);
258   pe = g_new (PALETTEENTRY, npal);
259   n = GetPaletteEntries (hpal, 0, npal, pe);
260
261   if (!n)
262     g_print ("HPALETTE %p: GetPaletteEntries failed: %s\n",
263              hpal, g_win32_error_message (GetLastError ()));
264   else
265     {
266       g_print ("HPALETTE %p: %d (%d) entries\n", hpal, n, npal);
267       _gdk_win32_print_paletteentries (pe, n);
268     }
269   g_free (pe);
270 }
271
272 void
273 _gdk_win32_print_dc (HDC hdc)
274 {
275   HGDIOBJ obj;
276   LOGBRUSH logbrush;
277   EXTLOGPEN extlogpen;
278   HRGN hrgn;
279   RECT rect;
280   int flag;
281
282   g_print ("%p:\n", hdc);
283   obj = GetCurrentObject (hdc, OBJ_BRUSH);
284   GetObject (obj, sizeof (LOGBRUSH), &logbrush);
285   g_print ("brush: %s color=%06lx hatch=%p\n",
286            _gdk_win32_lbstyle_to_string (logbrush.lbStyle),
287            logbrush.lbColor, (gpointer) logbrush.lbHatch);
288   obj = GetCurrentObject (hdc, OBJ_PEN);
289   GetObject (obj, sizeof (EXTLOGPEN), &extlogpen);
290   g_print ("pen: %s %s %s %s w=%d %s\n",
291            _gdk_win32_pstype_to_string (extlogpen.elpPenStyle),
292            _gdk_win32_psstyle_to_string (extlogpen.elpPenStyle),
293            _gdk_win32_psendcap_to_string (extlogpen.elpPenStyle),
294            _gdk_win32_psjoin_to_string (extlogpen.elpPenStyle),
295            (int) extlogpen.elpWidth,
296            _gdk_win32_lbstyle_to_string (extlogpen.elpBrushStyle));
297   g_print ("rop2: %s textcolor=%06lx\n",
298            _gdk_win32_rop2_to_string (GetROP2 (hdc)),
299            GetTextColor (hdc));
300   hrgn = CreateRectRgn (0, 0, 0, 0);
301   if ((flag = GetClipRgn (hdc, hrgn)) == -1)
302     WIN32_API_FAILED ("GetClipRgn");
303   else if (flag == 0)
304     g_print ("no clip region\n");
305   else if (flag == 1)
306     {
307       GetRgnBox (hrgn, &rect);
308       g_print ("clip region: %p bbox: %s\n",
309                hrgn, _gdk_win32_rect_to_string (&rect));
310     }
311   DeleteObject (hrgn);
312 }
313
314 gchar *
315 _gdk_win32_drag_protocol_to_string (GdkDragProtocol protocol)
316 {
317   switch (protocol)
318     {
319 #define CASE(x) case GDK_DRAG_PROTO_##x: return #x
320       CASE (MOTIF);
321       CASE (XDND);
322       CASE (ROOTWIN);
323       CASE (NONE);
324       CASE (WIN32_DROPFILES);
325       CASE (OLE2);
326       CASE (LOCAL);
327 #undef CASE
328     default: return static_printf ("illegal_%d", protocol);
329     }
330   /* NOTREACHED */
331   return NULL; 
332 }
333
334 gchar *
335 _gdk_win32_window_state_to_string (GdkWindowState state)
336 {
337   gchar buf[100];
338   gchar *bufp = buf;
339   gchar *s = "";
340
341   buf[0] = '\0';
342
343 #define BIT(x)                                          \
344   if (state & GDK_WINDOW_STATE_ ## x)                   \
345     (bufp += sprintf (bufp, "%s" #x, s), s = "|")
346
347   /* For clarity, also show the complement of WITHDRAWN, i.e. "MAPPED" */
348   if (!(state & GDK_WINDOW_STATE_WITHDRAWN))
349     (bufp += sprintf (bufp, "MAPPED"), s = "|");
350
351   BIT (WITHDRAWN);
352   BIT (ICONIFIED);
353   BIT (MAXIMIZED);
354   BIT (STICKY);
355 #undef BIT
356
357   return static_printf ("%s", buf);  
358 }
359
360 gchar *
361 _gdk_win32_window_style_to_string (LONG style)
362 {
363   gchar buf[1000];
364   gchar *bufp = buf;
365   gchar *s = "";
366
367   buf[0] = '\0';
368
369 #define BIT(x)                                          \
370   if (style & WS_ ## x)                                 \
371     (bufp += sprintf (bufp, "%s" #x, s), s = "|")
372
373   /* Note that many of the WS_* macros are in face several bits.
374    * Handle just the individual bits here. Sort as in w32api's
375    * winuser.h.
376    */
377   BIT (BORDER);
378   BIT (CHILD);
379   BIT (CLIPCHILDREN);
380   BIT (CLIPSIBLINGS);
381   BIT (DISABLED);
382   BIT (DLGFRAME);
383   BIT (GROUP);
384   BIT (HSCROLL);
385   BIT (ICONIC);
386   BIT (MAXIMIZE);
387   BIT (MAXIMIZEBOX);
388   BIT (MINIMIZE);
389   BIT (MINIMIZEBOX);
390   BIT (POPUP);
391   BIT (SIZEBOX);
392   BIT (SYSMENU);
393   BIT (TABSTOP);
394   BIT (THICKFRAME);
395   BIT (VISIBLE);
396   BIT (VSCROLL);
397 #undef BIT
398
399   return static_printf ("%s", buf);  
400 }
401
402 gchar *
403 _gdk_win32_window_exstyle_to_string (LONG style)
404 {
405   gchar buf[1000];
406   gchar *bufp = buf;
407   gchar *s = "";
408
409   buf[0] = '\0';
410
411 #define BIT(x)                                          \
412   if (style & WS_EX_ ## x)                              \
413     (bufp += sprintf (bufp, "%s" #x, s), s = "|")
414
415   /* Note that many of the WS_EX_* macros are in face several bits.
416    * Handle just the individual bits here. Sort as in w32api's
417    * winuser.h.
418    */
419   BIT (ACCEPTFILES);
420   BIT (APPWINDOW);
421   BIT (CLIENTEDGE);
422 #ifndef WS_EX_COMPOSITED
423 #  define WS_EX_COMPOSITED 0x02000000L
424 #endif
425   BIT (COMPOSITED);
426   BIT (CONTEXTHELP);
427   BIT (CONTROLPARENT);
428   BIT (DLGMODALFRAME);
429   BIT (LAYERED);
430   BIT (LAYOUTRTL);
431   BIT (LEFTSCROLLBAR);
432   BIT (MDICHILD);
433   BIT (NOACTIVATE);
434   BIT (NOINHERITLAYOUT);
435   BIT (NOPARENTNOTIFY);
436   BIT (RIGHT);
437   BIT (RTLREADING);
438   BIT (STATICEDGE);
439   BIT (TOOLWINDOW);
440   BIT (TOPMOST);
441   BIT (TRANSPARENT);
442   BIT (WINDOWEDGE);
443 #undef BIT
444
445   return static_printf ("%s", buf);  
446 }
447
448 gchar *
449 _gdk_win32_window_pos_bits_to_string (UINT flags)
450 {
451   gchar buf[1000];
452   gchar *bufp = buf;
453   gchar *s = "";
454
455   buf[0] = '\0';
456
457 #define BIT(x)                                          \
458   if (flags & SWP_ ## x)                                \
459     (bufp += sprintf (bufp, "%s" #x, s), s = "|")
460
461   BIT (DRAWFRAME);
462   BIT (FRAMECHANGED);
463   BIT (HIDEWINDOW);
464   BIT (NOACTIVATE);
465   BIT (NOCOPYBITS);
466   BIT (NOMOVE);
467   BIT (NOSIZE);
468   BIT (NOREDRAW);
469   BIT (NOZORDER);
470   BIT (SHOWWINDOW);
471   BIT (NOOWNERZORDER);
472   BIT (NOSENDCHANGING);
473   BIT (DEFERERASE);
474   BIT (ASYNCWINDOWPOS);
475 #undef BIT
476
477   return static_printf ("%s", buf);  
478 }
479
480 gchar *
481 _gdk_win32_drag_action_to_string (GdkDragAction actions)
482 {
483   gchar buf[100];
484   gchar *bufp = buf;
485   gchar *s = "";
486
487   buf[0] = '\0';
488
489 #define BIT(x)                                          \
490   if (actions & GDK_ACTION_ ## x)                               \
491     (bufp += sprintf (bufp, "%s" #x, s), s = "|")
492
493   BIT (DEFAULT);
494   BIT (COPY);
495   BIT (MOVE);
496   BIT (LINK);
497   BIT (PRIVATE);
498   BIT (ASK);
499 #undef BIT
500
501   return static_printf ("%s", buf);  
502 }
503
504 gchar *
505 _gdk_win32_rop2_to_string (int rop2)
506 {
507   switch (rop2)
508     {
509 #define CASE(x) case R2_##x: return #x
510       CASE (BLACK);
511       CASE (COPYPEN);
512       CASE (MASKNOTPEN);
513       CASE (MASKPEN);
514       CASE (MASKPENNOT);
515       CASE (MERGENOTPEN);
516       CASE (MERGEPEN);
517       CASE (MERGEPENNOT);
518       CASE (NOP);
519       CASE (NOT);
520       CASE (NOTCOPYPEN);
521       CASE (NOTMASKPEN);
522       CASE (NOTMERGEPEN);
523       CASE (NOTXORPEN);
524       CASE (WHITE);
525       CASE (XORPEN);
526 #undef CASE
527     default: return static_printf ("illegal_%x", rop2);
528     }
529   /* NOTREACHED */
530   return NULL;
531 }
532
533 gchar *
534 _gdk_win32_lbstyle_to_string (UINT brush_style)
535 {
536   switch (brush_style)
537     {
538 #define CASE(x) case BS_##x: return #x
539       CASE (DIBPATTERN);
540       CASE (DIBPATTERNPT);
541       CASE (HATCHED);
542       CASE (HOLLOW);
543       CASE (PATTERN);
544       CASE (SOLID);
545 #undef CASE
546     default: return static_printf ("illegal_%d", brush_style);
547     }
548   /* NOTREACHED */
549   return NULL;
550 }
551
552 gchar *
553 _gdk_win32_pstype_to_string (DWORD pen_style)
554 {
555   switch (pen_style & PS_TYPE_MASK)
556     {
557     case PS_GEOMETRIC: return "GEOMETRIC";
558     case PS_COSMETIC: return "COSMETIC";
559     default: return static_printf ("illegal_%d", pen_style & PS_TYPE_MASK);
560     }
561   /* NOTREACHED */
562   return NULL;
563 }
564
565 gchar *
566 _gdk_win32_psstyle_to_string (DWORD pen_style)
567 {
568   switch (pen_style & PS_STYLE_MASK)
569     {
570 #define CASE(x) case PS_##x: return #x
571       CASE (ALTERNATE);
572       CASE (SOLID);
573       CASE (DASH);
574       CASE (DOT);
575       CASE (DASHDOT);
576       CASE (DASHDOTDOT);
577       CASE (NULL);
578       CASE (USERSTYLE);
579       CASE (INSIDEFRAME);
580 #undef CASE
581     default: return static_printf ("illegal_%d", pen_style & PS_STYLE_MASK);
582     }
583   /* NOTREACHED */
584   return NULL;
585 }
586
587 gchar *
588 _gdk_win32_psendcap_to_string (DWORD pen_style)
589 {
590   switch (pen_style & PS_ENDCAP_MASK)
591     {
592 #define CASE(x) case PS_ENDCAP_##x: return #x
593       CASE (ROUND);
594       CASE (SQUARE);
595       CASE (FLAT);
596 #undef CASE
597     default: return static_printf ("illegal_%d", pen_style & PS_ENDCAP_MASK);
598     }
599   /* NOTREACHED */
600   return NULL;
601 }
602
603 gchar *
604 _gdk_win32_psjoin_to_string (DWORD pen_style)
605 {
606   switch (pen_style & PS_JOIN_MASK)
607     {
608 #define CASE(x) case PS_JOIN_##x: return #x
609       CASE (ROUND);
610       CASE (BEVEL);
611       CASE (MITER);
612 #undef CASE
613     default: return static_printf ("illegal_%d", pen_style & PS_JOIN_MASK);
614     }
615   /* NOTREACHED */
616   return NULL;
617 }
618
619 gchar *
620 _gdk_win32_message_to_string (UINT msg)
621 {
622   switch (msg)
623     {
624 #define CASE(x) case x: return #x
625       CASE (WM_NULL);
626       CASE (WM_CREATE);
627       CASE (WM_DESTROY);
628       CASE (WM_MOVE);
629       CASE (WM_SIZE);
630       CASE (WM_ACTIVATE);
631       CASE (WM_SETFOCUS);
632       CASE (WM_KILLFOCUS);
633       CASE (WM_ENABLE);
634       CASE (WM_SETREDRAW);
635       CASE (WM_SETTEXT);
636       CASE (WM_GETTEXT);
637       CASE (WM_GETTEXTLENGTH);
638       CASE (WM_PAINT);
639       CASE (WM_CLOSE);
640       CASE (WM_QUERYENDSESSION);
641       CASE (WM_QUERYOPEN);
642       CASE (WM_ENDSESSION);
643       CASE (WM_QUIT);
644       CASE (WM_ERASEBKGND);
645       CASE (WM_SYSCOLORCHANGE);
646       CASE (WM_SHOWWINDOW);
647       CASE (WM_WININICHANGE);
648       CASE (WM_DEVMODECHANGE);
649       CASE (WM_ACTIVATEAPP);
650       CASE (WM_FONTCHANGE);
651       CASE (WM_TIMECHANGE);
652       CASE (WM_CANCELMODE);
653       CASE (WM_SETCURSOR);
654       CASE (WM_MOUSEACTIVATE);
655       CASE (WM_CHILDACTIVATE);
656       CASE (WM_QUEUESYNC);
657       CASE (WM_GETMINMAXINFO);
658       CASE (WM_PAINTICON);
659       CASE (WM_ICONERASEBKGND);
660       CASE (WM_NEXTDLGCTL);
661       CASE (WM_SPOOLERSTATUS);
662       CASE (WM_DRAWITEM);
663       CASE (WM_MEASUREITEM);
664       CASE (WM_DELETEITEM);
665       CASE (WM_VKEYTOITEM);
666       CASE (WM_CHARTOITEM);
667       CASE (WM_SETFONT);
668       CASE (WM_GETFONT);
669       CASE (WM_SETHOTKEY);
670       CASE (WM_GETHOTKEY);
671       CASE (WM_QUERYDRAGICON);
672       CASE (WM_COMPAREITEM);
673       CASE (WM_GETOBJECT);
674       CASE (WM_COMPACTING);
675       CASE (WM_WINDOWPOSCHANGING);
676       CASE (WM_WINDOWPOSCHANGED);
677       CASE (WM_POWER);
678       CASE (WM_COPYDATA);
679       CASE (WM_CANCELJOURNAL);
680       CASE (WM_NOTIFY);
681       CASE (WM_INPUTLANGCHANGEREQUEST);
682       CASE (WM_INPUTLANGCHANGE);
683       CASE (WM_TCARD);
684       CASE (WM_HELP);
685       CASE (WM_USERCHANGED);
686       CASE (WM_NOTIFYFORMAT);
687       CASE (WM_CONTEXTMENU);
688       CASE (WM_STYLECHANGING);
689       CASE (WM_STYLECHANGED);
690       CASE (WM_DISPLAYCHANGE);
691       CASE (WM_GETICON);
692       CASE (WM_SETICON);
693       CASE (WM_NCCREATE);
694       CASE (WM_NCDESTROY);
695       CASE (WM_NCCALCSIZE);
696       CASE (WM_NCHITTEST);
697       CASE (WM_NCPAINT);
698       CASE (WM_NCACTIVATE);
699       CASE (WM_GETDLGCODE);
700       CASE (WM_SYNCPAINT);
701       CASE (WM_NCMOUSEMOVE);
702       CASE (WM_NCLBUTTONDOWN);
703       CASE (WM_NCLBUTTONUP);
704       CASE (WM_NCLBUTTONDBLCLK);
705       CASE (WM_NCRBUTTONDOWN);
706       CASE (WM_NCRBUTTONUP);
707       CASE (WM_NCRBUTTONDBLCLK);
708       CASE (WM_NCMBUTTONDOWN);
709       CASE (WM_NCMBUTTONUP);
710       CASE (WM_NCMBUTTONDBLCLK);
711       CASE (WM_NCXBUTTONDOWN);
712       CASE (WM_NCXBUTTONUP);
713       CASE (WM_NCXBUTTONDBLCLK);
714       CASE (WM_KEYDOWN);
715       CASE (WM_KEYUP);
716       CASE (WM_CHAR);
717       CASE (WM_DEADCHAR);
718       CASE (WM_SYSKEYDOWN);
719       CASE (WM_SYSKEYUP);
720       CASE (WM_SYSCHAR);
721       CASE (WM_SYSDEADCHAR);
722       CASE (WM_KEYLAST);
723       CASE (WM_IME_STARTCOMPOSITION);
724       CASE (WM_IME_ENDCOMPOSITION);
725       CASE (WM_IME_COMPOSITION);
726       CASE (WM_INITDIALOG);
727       CASE (WM_COMMAND);
728       CASE (WM_SYSCOMMAND);
729       CASE (WM_TIMER);
730       CASE (WM_HSCROLL);
731       CASE (WM_VSCROLL);
732       CASE (WM_INITMENU);
733       CASE (WM_INITMENUPOPUP);
734       CASE (WM_MENUSELECT);
735       CASE (WM_MENUCHAR);
736       CASE (WM_ENTERIDLE);
737       CASE (WM_MENURBUTTONUP);
738       CASE (WM_MENUDRAG);
739       CASE (WM_MENUGETOBJECT);
740       CASE (WM_UNINITMENUPOPUP);
741       CASE (WM_MENUCOMMAND);
742       CASE (WM_CHANGEUISTATE);
743       CASE (WM_UPDATEUISTATE);
744       CASE (WM_QUERYUISTATE);
745       CASE (WM_CTLCOLORMSGBOX);
746       CASE (WM_CTLCOLOREDIT);
747       CASE (WM_CTLCOLORLISTBOX);
748       CASE (WM_CTLCOLORBTN);
749       CASE (WM_CTLCOLORDLG);
750       CASE (WM_CTLCOLORSCROLLBAR);
751       CASE (WM_CTLCOLORSTATIC);
752       CASE (WM_MOUSEMOVE);
753       CASE (WM_LBUTTONDOWN);
754       CASE (WM_LBUTTONUP);
755       CASE (WM_LBUTTONDBLCLK);
756       CASE (WM_RBUTTONDOWN);
757       CASE (WM_RBUTTONUP);
758       CASE (WM_RBUTTONDBLCLK);
759       CASE (WM_MBUTTONDOWN);
760       CASE (WM_MBUTTONUP);
761       CASE (WM_MBUTTONDBLCLK);
762       CASE (WM_MOUSEWHEEL);
763       CASE (WM_XBUTTONDOWN);
764       CASE (WM_XBUTTONUP);
765       CASE (WM_XBUTTONDBLCLK);
766       CASE (WM_PARENTNOTIFY);
767       CASE (WM_ENTERMENULOOP);
768       CASE (WM_EXITMENULOOP);
769       CASE (WM_NEXTMENU);
770       CASE (WM_SIZING);
771       CASE (WM_CAPTURECHANGED);
772       CASE (WM_MOVING);
773       CASE (WM_POWERBROADCAST);
774       CASE (WM_DEVICECHANGE);
775       CASE (WM_MDICREATE);
776       CASE (WM_MDIDESTROY);
777       CASE (WM_MDIACTIVATE);
778       CASE (WM_MDIRESTORE);
779       CASE (WM_MDINEXT);
780       CASE (WM_MDIMAXIMIZE);
781       CASE (WM_MDITILE);
782       CASE (WM_MDICASCADE);
783       CASE (WM_MDIICONARRANGE);
784       CASE (WM_MDIGETACTIVE);
785       CASE (WM_MDISETMENU);
786       CASE (WM_ENTERSIZEMOVE);
787       CASE (WM_EXITSIZEMOVE);
788       CASE (WM_DROPFILES);
789       CASE (WM_MDIREFRESHMENU);
790       CASE (WM_IME_SETCONTEXT);
791       CASE (WM_IME_NOTIFY);
792       CASE (WM_IME_CONTROL);
793       CASE (WM_IME_COMPOSITIONFULL);
794       CASE (WM_IME_SELECT);
795       CASE (WM_IME_CHAR);
796       CASE (WM_IME_REQUEST);
797       CASE (WM_IME_KEYDOWN);
798       CASE (WM_IME_KEYUP);
799       CASE (WM_MOUSEHOVER);
800       CASE (WM_MOUSELEAVE);
801       CASE (WM_NCMOUSEHOVER);
802       CASE (WM_NCMOUSELEAVE);
803       CASE (WM_CUT);
804       CASE (WM_COPY);
805       CASE (WM_PASTE);
806       CASE (WM_CLEAR);
807       CASE (WM_UNDO);
808       CASE (WM_RENDERFORMAT);
809       CASE (WM_RENDERALLFORMATS);
810       CASE (WM_DESTROYCLIPBOARD);
811       CASE (WM_DRAWCLIPBOARD);
812       CASE (WM_PAINTCLIPBOARD);
813       CASE (WM_VSCROLLCLIPBOARD);
814       CASE (WM_SIZECLIPBOARD);
815       CASE (WM_ASKCBFORMATNAME);
816       CASE (WM_CHANGECBCHAIN);
817       CASE (WM_HSCROLLCLIPBOARD);
818       CASE (WM_QUERYNEWPALETTE);
819       CASE (WM_PALETTEISCHANGING);
820       CASE (WM_PALETTECHANGED);
821       CASE (WM_HOTKEY);
822       CASE (WM_PRINT);
823       CASE (WM_PRINTCLIENT);
824       CASE (WM_APPCOMMAND);
825       CASE (WM_HANDHELDFIRST);
826       CASE (WM_HANDHELDLAST);
827       CASE (WM_AFXFIRST);
828       CASE (WM_AFXLAST);
829       CASE (WM_PENWINFIRST);
830       CASE (WM_PENWINLAST);
831       CASE (WM_APP);
832       CASE (WT_PACKET);
833       CASE (WT_CSRCHANGE);
834       CASE (WT_PROXIMITY);
835 #undef CASE
836     default:
837       if (msg >= WM_HANDHELDFIRST && msg <= WM_HANDHELDLAST)
838         return static_printf ("WM_HANDHELDFIRST+%d", msg - WM_HANDHELDFIRST);
839       else if (msg >= WM_AFXFIRST && msg <= WM_AFXLAST)
840         return static_printf ("WM_AFXFIRST+%d", msg - WM_AFXFIRST);
841       else if (msg >= WM_PENWINFIRST && msg <= WM_PENWINLAST)
842         return static_printf ("WM_PENWINFIRST+%d", msg - WM_PENWINFIRST);
843       else if (msg >= WM_USER && msg <= 0x7FFF)
844         return static_printf ("WM_USER+%d", msg - WM_USER);
845       else if (msg >= 0xC000 && msg <= 0xFFFF)
846         return static_printf ("reg-%#x", msg);
847       else
848         return static_printf ("unk-%#x", msg);
849     }
850   /* NOTREACHED */
851   return NULL;
852 }
853
854 gchar *
855 _gdk_win32_key_to_string (LONG lParam)
856 {
857   char buf[100];
858   gchar *keyname_utf8;
859
860   if (GetKeyNameText (lParam, buf, sizeof (buf)) &&
861       (keyname_utf8 = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL)) != NULL)
862     {
863       gchar *retval = static_printf ("%s", keyname_utf8);
864
865       g_free (keyname_utf8);
866
867       return retval;
868     }
869
870   return static_printf ("unk-%#lx", lParam);
871 }
872       
873 gchar *
874 _gdk_win32_cf_to_string (UINT format)
875 {
876   char buf[100];
877
878   switch (format)
879     {
880 #define CASE(x) case CF_##x: return "CF_" #x
881       CASE (BITMAP);
882       CASE (DIB);
883       CASE (DIBV5);
884       CASE (DIF);
885       CASE (DSPBITMAP);
886       CASE (DSPENHMETAFILE);
887       CASE (DSPMETAFILEPICT);
888       CASE (DSPTEXT);
889       CASE (ENHMETAFILE);
890       CASE (HDROP);
891       CASE (LOCALE);
892       CASE (METAFILEPICT);
893       CASE (OEMTEXT);
894       CASE (OWNERDISPLAY);
895       CASE (PALETTE);
896       CASE (PENDATA);
897       CASE (RIFF);
898       CASE (SYLK);
899       CASE (TEXT);
900       CASE (WAVE);
901       CASE (TIFF);
902       CASE (UNICODETEXT);
903     default:
904       if (format >= CF_GDIOBJFIRST &&
905           format <= CF_GDIOBJLAST)
906         return static_printf ("CF_GDIOBJ%d", format - CF_GDIOBJFIRST);
907       if (format >= CF_PRIVATEFIRST &&
908           format <= CF_PRIVATELAST)
909         return static_printf ("CF_PRIVATE%d", format - CF_PRIVATEFIRST);
910       if (GetClipboardFormatName (format, buf, sizeof (buf)))
911         return static_printf ("'%s'", buf);
912       else
913         return static_printf ("unk-%#lx", format);
914     }
915 }
916       
917 gchar *
918 _gdk_win32_data_to_string (const guchar *data,
919                            int           nbytes)
920 {
921   GString *s = g_string_new ("");
922   int i;
923   gchar *retval;
924
925   for (i = 0; i < nbytes; i++)
926     if (data[i] >=' ' && data[i] <= '~')
927       g_string_append_printf (s, "%c  ", data[i]);
928     else
929       g_string_append_printf (s, "%02X ", data[i]);
930
931   retval = static_printf ("%s", s->str);
932   g_string_free (s, TRUE);
933
934   return retval;
935 }
936
937 gchar *
938 _gdk_win32_rect_to_string (const RECT *rect)
939 {
940   return static_printf ("%ldx%ld@%+ld%+ld",
941                         (rect->right - rect->left), (rect->bottom - rect->top),
942                         rect->left, rect->top);
943 }
944
945 gchar *
946 _gdk_win32_gdkrectangle_to_string (const GdkRectangle *rect)
947 {
948   return static_printf ("%dx%d@%+d%+d",
949                         rect->width, rect->height,
950                         rect->x, rect->y);
951 }
952
953 gchar *
954 _gdk_win32_cairo_region_to_string (const cairo_region_t *rgn)
955 {
956   cairo_rectangle_int_t extents;
957   cairo_region_get_extents (rgn, &extents);
958   return static_printf ("%dx%d@%+d%+d",
959                         extents.width, extents.height,
960                         extents.x, extents.y);
961 }
962
963 gchar *
964 _gdk_win32_window_description (GdkWindow *d)
965 {
966   g_return_val_if_fail (GDK_IS_WINDOW (d), NULL);
967
968   return static_printf ("%s:%p:%dx%dx%d",
969                         G_OBJECT_TYPE_NAME (d),
970                         GDK_WINDOW_HWND (d),
971                         gdk_window_get_width (GDK_WINDOW (d)),
972                         gdk_window_get_height (GDK_WINDOW (d)),
973                         gdk_visual_get_depth (gdk_window_get_visual (GDK_WINDOW (d))));
974 }
975
976 #endif /* G_ENABLE_DEBUG */