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