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
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.
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.
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.
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/.
30 #include <glib/gprintf.h>
37 #include "gdkkeysyms.h"
38 #include "gdkinternals.h"
40 #include "gdkprivate-win32.h"
49 static gboolean gdk_synchronize = FALSE;
51 static gboolean dummy;
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") },
69 DllMain (HINSTANCE hinstDLL,
73 _gdk_dll_hinstance = hinstDLL;
79 _gdk_win32_windowing_init (void)
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;
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,
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));
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");
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");
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.
128 _cf_png = RegisterClipboardFormat ("PNG");
129 _cf_jfif = RegisterClipboardFormat ("JFIF");
130 _cf_gif = RegisterClipboardFormat ("GIF");
132 _cf_url = RegisterClipboardFormat ("UniformResourceLocatorW");
133 _cf_html_format = RegisterClipboardFormat ("HTML Format");
134 _cf_text_html = RegisterClipboardFormat ("text/html");
136 _gdk_win32_selection_init ();
140 _gdk_win32_api_failed (const gchar *where,
143 gchar *msg = g_win32_error_message (GetLastError ());
144 g_warning ("%s: %s failed: %s", where, api, msg);
149 _gdk_other_api_failed (const gchar *where,
152 g_warning ("%s: %s failed", where, api);
156 #ifdef G_ENABLE_DEBUG
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.
167 static_printf (const gchar *format,
170 static gchar buf[10000];
172 static gchar *bufp = buf;
176 va_start (args, format);
177 msg = g_strdup_vprintf (format, args);
180 g_assert (strlen (msg) < sizeof (buf));
182 if (bufp + strlen (msg) + 1 > buf + sizeof (buf))
187 bufp += strlen (msg) + 1;
194 _gdk_win32_color_to_string (const GdkColor *color)
196 return static_printf ("(%.04x,%.04x,%.04x):%.06x",
197 color->red, color->green,
198 color->blue, color->pixel);
202 _gdk_win32_print_paletteentries (const PALETTEENTRY *pep,
208 for (i = 0; i < nentries; i++)
209 g_print (" %3d %02x: %02x %02x %02x%s\n",
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))))));
220 _gdk_win32_print_system_palette (void)
225 k = GetSystemPaletteEntries (_gdk_display_hdc, 0, 0, NULL);
226 pe = g_new (PALETTEENTRY, k);
227 k = GetSystemPaletteEntries (_gdk_display_hdc, 0, k, pe);
230 g_print ("GetSystemPaletteEntries failed: %s\n",
231 g_win32_error_message (GetLastError ()));
234 g_print ("System palette: %d entries\n", k);
235 _gdk_win32_print_paletteentries (pe, k);
241 palette_size (HPALETTE hpal)
245 if (!GetObject (hpal, sizeof (npal), &npal))
246 WIN32_GDI_FAILED ("GetObject (HPALETTE)");
252 _gdk_win32_print_hpalette (HPALETTE hpal)
257 npal = palette_size (hpal);
258 pe = g_new (PALETTEENTRY, npal);
259 n = GetPaletteEntries (hpal, 0, npal, pe);
262 g_print ("HPALETTE %p: GetPaletteEntries failed: %s\n",
263 hpal, g_win32_error_message (GetLastError ()));
266 g_print ("HPALETTE %p: %d (%d) entries\n", hpal, n, npal);
267 _gdk_win32_print_paletteentries (pe, n);
273 _gdk_win32_print_dc (HDC hdc)
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)),
300 hrgn = CreateRectRgn (0, 0, 0, 0);
301 if ((flag = GetClipRgn (hdc, hrgn)) == -1)
302 WIN32_API_FAILED ("GetClipRgn");
304 g_print ("no clip region\n");
307 GetRgnBox (hrgn, &rect);
308 g_print ("clip region: %p bbox: %s\n",
309 hrgn, _gdk_win32_rect_to_string (&rect));
315 _gdk_win32_drag_protocol_to_string (GdkDragProtocol protocol)
319 #define CASE(x) case GDK_DRAG_PROTO_##x: return #x
324 CASE (WIN32_DROPFILES);
328 default: return static_printf ("illegal_%d", protocol);
335 _gdk_win32_window_state_to_string (GdkWindowState state)
344 if (state & GDK_WINDOW_STATE_ ## x) \
345 (bufp += sprintf (bufp, "%s" #x, s), s = "|")
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 = "|");
357 return static_printf ("%s", buf);
361 _gdk_win32_window_style_to_string (LONG style)
370 if (style & WS_ ## x) \
371 (bufp += sprintf (bufp, "%s" #x, s), s = "|")
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
399 return static_printf ("%s", buf);
403 _gdk_win32_window_exstyle_to_string (LONG style)
412 if (style & WS_EX_ ## x) \
413 (bufp += sprintf (bufp, "%s" #x, s), s = "|")
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
422 #ifndef WS_EX_COMPOSITED
423 # define WS_EX_COMPOSITED 0x02000000L
434 BIT (NOINHERITLAYOUT);
435 BIT (NOPARENTNOTIFY);
445 return static_printf ("%s", buf);
449 _gdk_win32_window_pos_bits_to_string (UINT flags)
458 if (flags & SWP_ ## x) \
459 (bufp += sprintf (bufp, "%s" #x, s), s = "|")
472 BIT (NOSENDCHANGING);
474 BIT (ASYNCWINDOWPOS);
477 return static_printf ("%s", buf);
481 _gdk_win32_drag_action_to_string (GdkDragAction actions)
490 if (actions & GDK_ACTION_ ## x) \
491 (bufp += sprintf (bufp, "%s" #x, s), s = "|")
501 return static_printf ("%s", buf);
505 _gdk_win32_rop2_to_string (int rop2)
509 #define CASE(x) case R2_##x: return #x
527 default: return static_printf ("illegal_%x", rop2);
534 _gdk_win32_lbstyle_to_string (UINT brush_style)
538 #define CASE(x) case BS_##x: return #x
546 default: return static_printf ("illegal_%d", brush_style);
553 _gdk_win32_pstype_to_string (DWORD pen_style)
555 switch (pen_style & PS_TYPE_MASK)
557 case PS_GEOMETRIC: return "GEOMETRIC";
558 case PS_COSMETIC: return "COSMETIC";
559 default: return static_printf ("illegal_%d", pen_style & PS_TYPE_MASK);
566 _gdk_win32_psstyle_to_string (DWORD pen_style)
568 switch (pen_style & PS_STYLE_MASK)
570 #define CASE(x) case PS_##x: return #x
581 default: return static_printf ("illegal_%d", pen_style & PS_STYLE_MASK);
588 _gdk_win32_psendcap_to_string (DWORD pen_style)
590 switch (pen_style & PS_ENDCAP_MASK)
592 #define CASE(x) case PS_ENDCAP_##x: return #x
597 default: return static_printf ("illegal_%d", pen_style & PS_ENDCAP_MASK);
604 _gdk_win32_psjoin_to_string (DWORD pen_style)
606 switch (pen_style & PS_JOIN_MASK)
608 #define CASE(x) case PS_JOIN_##x: return #x
613 default: return static_printf ("illegal_%d", pen_style & PS_JOIN_MASK);
620 _gdk_win32_message_to_string (UINT msg)
624 #define CASE(x) case x: return #x
637 CASE (WM_GETTEXTLENGTH);
640 CASE (WM_QUERYENDSESSION);
642 CASE (WM_ENDSESSION);
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);
654 CASE (WM_MOUSEACTIVATE);
655 CASE (WM_CHILDACTIVATE);
657 CASE (WM_GETMINMAXINFO);
659 CASE (WM_ICONERASEBKGND);
660 CASE (WM_NEXTDLGCTL);
661 CASE (WM_SPOOLERSTATUS);
663 CASE (WM_MEASUREITEM);
664 CASE (WM_DELETEITEM);
665 CASE (WM_VKEYTOITEM);
666 CASE (WM_CHARTOITEM);
671 CASE (WM_QUERYDRAGICON);
672 CASE (WM_COMPAREITEM);
674 CASE (WM_COMPACTING);
675 CASE (WM_WINDOWPOSCHANGING);
676 CASE (WM_WINDOWPOSCHANGED);
679 CASE (WM_CANCELJOURNAL);
681 CASE (WM_INPUTLANGCHANGEREQUEST);
682 CASE (WM_INPUTLANGCHANGE);
685 CASE (WM_USERCHANGED);
686 CASE (WM_NOTIFYFORMAT);
687 CASE (WM_CONTEXTMENU);
688 CASE (WM_STYLECHANGING);
689 CASE (WM_STYLECHANGED);
690 CASE (WM_DISPLAYCHANGE);
695 CASE (WM_NCCALCSIZE);
698 CASE (WM_NCACTIVATE);
699 CASE (WM_GETDLGCODE);
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);
718 CASE (WM_SYSKEYDOWN);
721 CASE (WM_SYSDEADCHAR);
723 CASE (WM_IME_STARTCOMPOSITION);
724 CASE (WM_IME_ENDCOMPOSITION);
725 CASE (WM_IME_COMPOSITION);
726 CASE (WM_INITDIALOG);
728 CASE (WM_SYSCOMMAND);
733 CASE (WM_INITMENUPOPUP);
734 CASE (WM_MENUSELECT);
737 CASE (WM_MENURBUTTONUP);
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);
753 CASE (WM_LBUTTONDOWN);
755 CASE (WM_LBUTTONDBLCLK);
756 CASE (WM_RBUTTONDOWN);
758 CASE (WM_RBUTTONDBLCLK);
759 CASE (WM_MBUTTONDOWN);
761 CASE (WM_MBUTTONDBLCLK);
762 CASE (WM_MOUSEWHEEL);
763 CASE (WM_XBUTTONDOWN);
765 CASE (WM_XBUTTONDBLCLK);
766 CASE (WM_PARENTNOTIFY);
767 CASE (WM_ENTERMENULOOP);
768 CASE (WM_EXITMENULOOP);
771 CASE (WM_CAPTURECHANGED);
773 CASE (WM_POWERBROADCAST);
774 CASE (WM_DEVICECHANGE);
776 CASE (WM_MDIDESTROY);
777 CASE (WM_MDIACTIVATE);
778 CASE (WM_MDIRESTORE);
780 CASE (WM_MDIMAXIMIZE);
782 CASE (WM_MDICASCADE);
783 CASE (WM_MDIICONARRANGE);
784 CASE (WM_MDIGETACTIVE);
785 CASE (WM_MDISETMENU);
786 CASE (WM_ENTERSIZEMOVE);
787 CASE (WM_EXITSIZEMOVE);
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);
796 CASE (WM_IME_REQUEST);
797 CASE (WM_IME_KEYDOWN);
799 CASE (WM_MOUSEHOVER);
800 CASE (WM_MOUSELEAVE);
801 CASE (WM_NCMOUSEHOVER);
802 CASE (WM_NCMOUSELEAVE);
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);
823 CASE (WM_PRINTCLIENT);
824 CASE (WM_APPCOMMAND);
825 CASE (WM_HANDHELDFIRST);
826 CASE (WM_HANDHELDLAST);
829 CASE (WM_PENWINFIRST);
830 CASE (WM_PENWINLAST);
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);
848 return static_printf ("unk-%#x", msg);
855 _gdk_win32_key_to_string (LONG lParam)
860 if (GetKeyNameText (lParam, buf, sizeof (buf)) &&
861 (keyname_utf8 = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL)) != NULL)
863 gchar *retval = static_printf ("%s", keyname_utf8);
865 g_free (keyname_utf8);
870 return static_printf ("unk-%#lx", lParam);
874 _gdk_win32_cf_to_string (UINT format)
880 #define CASE(x) case CF_##x: return "CF_" #x
886 CASE (DSPENHMETAFILE);
887 CASE (DSPMETAFILEPICT);
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);
913 return static_printf ("unk-%#lx", format);
918 _gdk_win32_data_to_string (const guchar *data,
921 GString *s = g_string_new ("");
925 for (i = 0; i < nbytes; i++)
926 if (data[i] >=' ' && data[i] <= '~')
927 g_string_append_printf (s, "%c ", data[i]);
929 g_string_append_printf (s, "%02X ", data[i]);
931 retval = static_printf ("%s", s->str);
932 g_string_free (s, TRUE);
938 _gdk_win32_rect_to_string (const RECT *rect)
940 return static_printf ("%ldx%ld@%+ld%+ld",
941 (rect->right - rect->left), (rect->bottom - rect->top),
942 rect->left, rect->top);
946 _gdk_win32_gdkrectangle_to_string (const GdkRectangle *rect)
948 return static_printf ("%dx%d@%+d%+d",
949 rect->width, rect->height,
954 _gdk_win32_cairo_region_to_string (const cairo_region_t *rgn)
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);
964 _gdk_win32_window_description (GdkWindow *d)
966 g_return_val_if_fail (GDK_IS_WINDOW (d), NULL);
968 return static_printf ("%s:%p:%dx%dx%d",
969 G_OBJECT_TYPE_NAME (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))));
976 #endif /* G_ENABLE_DEBUG */