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