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