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/.
37 #include "gdkregion-generic.h"
38 #include "gdkkeysyms.h"
39 #include "gdkinternals.h"
40 #include "gdkprivate-win32.h"
41 #include "gdkinput-win32.h"
45 #if defined (__GNUC__) && defined (HAVE_DIMM_H)
46 /* The w32api imm.h clashes a bit with the IE5.5 dimm.h */
47 # define IMEMENUITEMINFOA hidden_IMEMENUITEMINFOA
48 # define IMEMENUITEMINFOW hidden_IMEMENUITEMINFOW
53 static gboolean gdk_synchronize = FALSE;
55 GdkArgDesc _gdk_windowing_args[] = {
56 { "sync", GDK_ARG_BOOL, &gdk_synchronize, (GdkArgFunc) NULL},
57 { "no-wintab", GDK_ARG_BOOL, &_gdk_input_ignore_wintab,
59 { "ignore-wintab", GDK_ARG_BOOL, &_gdk_input_ignore_wintab,
61 { "max-colors", GDK_ARG_INT, &_gdk_max_colors, (GdkArgFunc) NULL},
66 DllMain (HINSTANCE hinstDLL,
70 _gdk_dll_hinstance = hinstDLL;
76 _gdk_windowing_init (gint *argc,
82 if (getenv ("GDK_IGNORE_WINTAB") != NULL)
83 _gdk_input_ignore_wintab = TRUE;
89 _gdk_app_hmodule = GetModuleHandle (NULL);
90 _gdk_display_hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
91 _gdk_root_window = GetDesktopWindow ();
92 _windows_version = GetVersion ();
94 if (getenv ("PRETEND_WIN9X"))
95 _windows_version = 0x80000004;
97 GDK_NOTE (MISC, g_print ("Windows version: %08x\n", (guint) _windows_version));
99 _gdk_input_locale = GetKeyboardLayout (0);
100 GetLocaleInfo (MAKELCID (LOWORD (_gdk_input_locale), SORT_DEFAULT),
101 LOCALE_IDEFAULTANSICODEPAGE,
103 _gdk_input_codepage = atoi (buf);
104 GDK_NOTE (EVENTS, g_print ("input_locale:%p, codepage:%d\n",
105 _gdk_input_locale, _gdk_input_codepage));
109 _cf_rtf = RegisterClipboardFormat ("Rich Text Format");
110 _cf_utf8_string = RegisterClipboardFormat ("UTF8_STRING");
112 _utf8_string = gdk_atom_intern ("UTF8_STRING", FALSE);
113 _compound_text = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
114 _text_uri_list = gdk_atom_intern ("text/uri-list", FALSE);
116 _local_dnd = gdk_atom_intern ("LocalDndSelection", FALSE);
117 _gdk_win32_dropfiles = gdk_atom_intern ("DROPFILES_DND", FALSE);
118 _gdk_ole2_dnd = gdk_atom_intern ("OLE2_DND", FALSE);
120 _gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);
122 _gdk_win32_selection_init ();
126 _gdk_win32_api_failed (const gchar *where,
130 gchar *msg = g_win32_error_message (GetLastError ());
131 g_warning ("%s:%d: %s failed: %s", where, line, api, msg);
136 _gdk_other_api_failed (const gchar *where,
140 g_warning ("%s:%d: %s failed", where, line, api);
144 _gdk_win32_gdi_failed (const gchar *where,
148 /* On Win9x GDI calls are implemented in 16-bit code and thus
149 * don't set the 32-bit error code, sigh.
152 _gdk_win32_api_failed (where, line, api);
154 _gdk_other_api_failed (where, line, api);
158 gdk_set_use_xshm (gboolean use_xshm)
164 gdk_get_use_xshm (void)
170 gdk_screen_get_width (GdkScreen *screen)
172 return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_parent_root)->impl)->width;
176 gdk_screen_get_height (GdkScreen *screen)
178 return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_parent_root)->impl)->height;
181 gdk_screen_get_width_mm (GdkScreen *screen)
183 return (double) GetDeviceCaps (_gdk_display_hdc, HORZRES) / GetDeviceCaps (_gdk_display_hdc, LOGPIXELSX) * 25.4;
187 gdk_screen_get_height_mm (GdkScreen *screen)
189 return (double) GetDeviceCaps (_gdk_display_hdc, VERTRES) / GetDeviceCaps (_gdk_display_hdc, LOGPIXELSY) * 25.4;
193 _gdk_windowing_display_set_sm_client_id (GdkDisplay *display,
194 const gchar *sm_client_id)
196 g_warning("gdk_set_sm_client_id %s", sm_client_id ? sm_client_id : "NULL");
200 gdk_display_beep (GdkDisplay *display)
202 g_return_if_fail (display == gdk_display_get_default());
207 _gdk_windowing_exit (void)
209 _gdk_win32_dnd_exit ();
211 DeleteDC (_gdk_display_hdc);
212 _gdk_display_hdc = NULL;
216 gdk_get_display (void)
218 return g_strdup (gdk_display_get_name (gdk_display_get_default ()));
222 gdk_error_trap_push (void)
227 gdk_error_trap_pop (void)
233 gdk_notify_startup_complete (void)
237 #ifdef G_ENABLE_DEBUG
240 * Like g_strdup_printf, but to a static buffer. Return value does not
241 * have to be g_free()d. The buffer is of bounded size and reused
242 * cyclically. Thus the return value is valid only until that part of
243 * the buffer happens to get reused. This doesn't matter as this
244 * function's return value is used in debugging output right after the call,
245 * and the return value isn't used after that.
248 static_printf (const gchar *format,
251 static gchar buf[10000];
253 static gchar *bufp = buf;
257 va_start (args, format);
258 msg = g_strdup_vprintf (format, args);
261 g_assert (strlen (msg) < sizeof (buf));
263 if (bufp + strlen (msg) + 1 > buf + sizeof (buf))
268 bufp += strlen (msg) + 1;
275 _gdk_win32_color_to_string (const GdkColor *color)
277 return static_printf ("(%.04x,%.04x,%.04x):%.06x",
278 color->red, color->green,
279 color->blue, color->pixel);
283 _gdk_win32_print_paletteentries (const PALETTEENTRY *pep,
289 for (i = 0; i < nentries; i++)
290 g_print (" %3d %02x: %02x %02x %02x%s\n",
292 pep[i].peRed, pep[i].peGreen, pep[i].peBlue,
293 (pep[i].peFlags == 0 ? "" :
294 (pep[i].peFlags == PC_EXPLICIT ? " PC_EXPLICIT" :
295 (pep[i].peFlags == PC_NOCOLLAPSE ? " PC_NOCOLLAPSE" :
296 (pep[i].peFlags == PC_RESERVED ? " PC_RESERVED" :
297 (sprintf (buf, " %d", pep[i].peFlags), buf))))));
301 _gdk_win32_print_system_palette (void)
306 k = GetSystemPaletteEntries (_gdk_display_hdc, 0, 0, NULL);
307 pe = g_new (PALETTEENTRY, k);
308 k = GetSystemPaletteEntries (_gdk_display_hdc, 0, k, pe);
311 g_print ("GetSystemPaletteEntries failed: %s\n",
312 g_win32_error_message (GetLastError ()));
315 g_print ("System palette: %d entries\n", k);
316 _gdk_win32_print_paletteentries (pe, k);
322 palette_size (HPALETTE hpal)
326 if (!GetObject (hpal, sizeof (npal), &npal))
327 WIN32_GDI_FAILED ("GetObject (HPALETTE)");
333 _gdk_win32_print_hpalette (HPALETTE hpal)
338 npal = palette_size (hpal);
339 pe = g_new (PALETTEENTRY, npal);
340 n = GetPaletteEntries (hpal, 0, npal, pe);
343 g_print ("HPALETTE %p: GetPaletteEntries failed: %s\n",
344 hpal, g_win32_error_message (GetLastError ()));
347 g_print ("HPALETTE %p: %d (%d) entries\n", hpal, n, npal);
348 _gdk_win32_print_paletteentries (pe, n);
354 _gdk_win32_print_dc (HDC hdc)
363 g_print ("%p:\n", hdc);
364 obj = GetCurrentObject (hdc, OBJ_BRUSH);
365 GetObject (obj, sizeof (LOGBRUSH), &logbrush);
366 g_print ("brush: %s color=%06lx hatch=%p\n",
367 _gdk_win32_lbstyle_to_string (logbrush.lbStyle),
368 logbrush.lbColor, (gpointer) logbrush.lbHatch);
369 obj = GetCurrentObject (hdc, OBJ_PEN);
370 GetObject (obj, sizeof (EXTLOGPEN), &extlogpen);
371 g_print ("pen: %s %s %s %s w=%d %s\n",
372 _gdk_win32_pstype_to_string (extlogpen.elpPenStyle),
373 _gdk_win32_psstyle_to_string (extlogpen.elpPenStyle),
374 _gdk_win32_psendcap_to_string (extlogpen.elpPenStyle),
375 _gdk_win32_psjoin_to_string (extlogpen.elpPenStyle),
377 _gdk_win32_lbstyle_to_string (extlogpen.elpBrushStyle));
378 g_print ("rop2: %s textcolor=%06lx\n",
379 _gdk_win32_rop2_to_string (GetROP2 (hdc)),
381 hrgn = CreateRectRgn (0, 0, 0, 0);
382 if ((flag = GetClipRgn (hdc, hrgn)) == -1)
383 WIN32_API_FAILED ("GetClipRgn");
385 g_print ("no clip region\n");
388 GetRgnBox (hrgn, &rect);
389 g_print ("clip region: %p bbox: %s\n",
390 hrgn, _gdk_win32_rect_to_string (&rect));
396 _gdk_win32_cap_style_to_string (GdkCapStyle cap_style)
400 #define CASE(x) case GDK_CAP_##x: return #x
406 default: return static_printf ("illegal_%d", cap_style);
413 _gdk_win32_fill_style_to_string (GdkFill fill)
417 #define CASE(x) case GDK_##x: return #x
421 CASE (OPAQUE_STIPPLED);
423 default: return static_printf ("illegal_%d", fill);
430 _gdk_win32_function_to_string (GdkFunction function)
434 #define CASE(x) case GDK_##x: return #x
451 default: return static_printf ("illegal_%d", function);
458 _gdk_win32_join_style_to_string (GdkJoinStyle join_style)
462 #define CASE(x) case GDK_JOIN_##x: return #x
467 default: return static_printf ("illegal_%d", join_style);
474 _gdk_win32_line_style_to_string (GdkLineStyle line_style)
478 #define CASE(x) case GDK_LINE_##x: return #x
483 default: return static_printf ("illegal_%d", line_style);
490 _gdk_win32_gcvalues_mask_to_string (GdkGCValuesMask mask)
499 if (mask & GDK_GC_##x) \
500 (bufp += sprintf (bufp, "%s" #x, s), s = "|")
522 return static_printf ("%s", buf);
526 _gdk_win32_window_state_to_string (GdkWindowState state)
535 if (state & GDK_WINDOW_STATE_ ## x) \
536 (bufp += sprintf (bufp, "%s" #x, s), s = "|")
538 /* For clarity, also show the complement of WITHDRAWN, i.e. "MAPPED" */
539 if (!(state & GDK_WINDOW_STATE_WITHDRAWN))
540 (bufp += sprintf (bufp, "MAPPED"), s = "|");
548 return static_printf ("%s", buf);
552 _gdk_win32_rop2_to_string (int rop2)
556 #define CASE(x) case R2_##x: return #x
574 default: return static_printf ("illegal_%x", rop2);
581 _gdk_win32_lbstyle_to_string (UINT brush_style)
585 #define CASE(x) case BS_##x: return #x
593 default: return static_printf ("illegal_%d", brush_style);
600 _gdk_win32_pstype_to_string (DWORD pen_style)
602 switch (pen_style & PS_TYPE_MASK)
604 case PS_GEOMETRIC: return "GEOMETRIC";
605 case PS_COSMETIC: return "COSMETIC";
606 default: return static_printf ("illegal_%d", pen_style & PS_TYPE_MASK);
613 _gdk_win32_psstyle_to_string (DWORD pen_style)
615 switch (pen_style & PS_STYLE_MASK)
617 #define CASE(x) case PS_##x: return #x
627 default: return static_printf ("illegal_%d", pen_style & PS_STYLE_MASK);
634 _gdk_win32_psendcap_to_string (DWORD pen_style)
636 switch (pen_style & PS_ENDCAP_MASK)
638 #define CASE(x) case PS_ENDCAP_##x: return #x
643 default: return static_printf ("illegal_%d", pen_style & PS_ENDCAP_MASK);
650 _gdk_win32_psjoin_to_string (DWORD pen_style)
652 switch (pen_style & PS_JOIN_MASK)
654 #define CASE(x) case PS_JOIN_##x: return #x
659 default: return static_printf ("illegal_%d", pen_style & PS_JOIN_MASK);
666 _gdk_win32_message_to_string (UINT msg)
670 #define CASE(x) case x: return #x
683 CASE (WM_GETTEXTLENGTH);
686 CASE (WM_QUERYENDSESSION);
688 CASE (WM_ENDSESSION);
690 CASE (WM_ERASEBKGND);
691 CASE (WM_SYSCOLORCHANGE);
692 CASE (WM_SHOWWINDOW);
693 CASE (WM_WININICHANGE);
694 CASE (WM_DEVMODECHANGE);
695 CASE (WM_ACTIVATEAPP);
696 CASE (WM_FONTCHANGE);
697 CASE (WM_TIMECHANGE);
698 CASE (WM_CANCELMODE);
700 CASE (WM_MOUSEACTIVATE);
701 CASE (WM_CHILDACTIVATE);
703 CASE (WM_GETMINMAXINFO);
705 CASE (WM_ICONERASEBKGND);
706 CASE (WM_NEXTDLGCTL);
707 CASE (WM_SPOOLERSTATUS);
709 CASE (WM_MEASUREITEM);
710 CASE (WM_DELETEITEM);
711 CASE (WM_VKEYTOITEM);
712 CASE (WM_CHARTOITEM);
717 CASE (WM_QUERYDRAGICON);
718 CASE (WM_COMPAREITEM);
720 CASE (WM_COMPACTING);
721 CASE (WM_WINDOWPOSCHANGING);
722 CASE (WM_WINDOWPOSCHANGED);
725 CASE (WM_CANCELJOURNAL);
727 CASE (WM_INPUTLANGCHANGEREQUEST);
728 CASE (WM_INPUTLANGCHANGE);
731 CASE (WM_USERCHANGED);
732 CASE (WM_NOTIFYFORMAT);
733 CASE (WM_CONTEXTMENU);
734 CASE (WM_STYLECHANGING);
735 CASE (WM_STYLECHANGED);
736 CASE (WM_DISPLAYCHANGE);
741 CASE (WM_NCCALCSIZE);
744 CASE (WM_NCACTIVATE);
745 CASE (WM_GETDLGCODE);
747 CASE (WM_NCMOUSEMOVE);
748 CASE (WM_NCLBUTTONDOWN);
749 CASE (WM_NCLBUTTONUP);
750 CASE (WM_NCLBUTTONDBLCLK);
751 CASE (WM_NCRBUTTONDOWN);
752 CASE (WM_NCRBUTTONUP);
753 CASE (WM_NCRBUTTONDBLCLK);
754 CASE (WM_NCMBUTTONDOWN);
755 CASE (WM_NCMBUTTONUP);
756 CASE (WM_NCMBUTTONDBLCLK);
757 CASE (WM_NCXBUTTONDOWN);
758 CASE (WM_NCXBUTTONUP);
759 CASE (WM_NCXBUTTONDBLCLK);
764 CASE (WM_SYSKEYDOWN);
767 CASE (WM_SYSDEADCHAR);
769 CASE (WM_IME_STARTCOMPOSITION);
770 CASE (WM_IME_ENDCOMPOSITION);
771 CASE (WM_IME_COMPOSITION);
772 CASE (WM_INITDIALOG);
774 CASE (WM_SYSCOMMAND);
779 CASE (WM_INITMENUPOPUP);
780 CASE (WM_MENUSELECT);
783 CASE (WM_MENURBUTTONUP);
785 CASE (WM_MENUGETOBJECT);
786 CASE (WM_UNINITMENUPOPUP);
787 CASE (WM_MENUCOMMAND);
788 CASE (WM_CHANGEUISTATE);
789 CASE (WM_UPDATEUISTATE);
790 CASE (WM_QUERYUISTATE);
791 CASE (WM_CTLCOLORMSGBOX);
792 CASE (WM_CTLCOLOREDIT);
793 CASE (WM_CTLCOLORLISTBOX);
794 CASE (WM_CTLCOLORBTN);
795 CASE (WM_CTLCOLORDLG);
796 CASE (WM_CTLCOLORSCROLLBAR);
797 CASE (WM_CTLCOLORSTATIC);
799 CASE (WM_LBUTTONDOWN);
801 CASE (WM_LBUTTONDBLCLK);
802 CASE (WM_RBUTTONDOWN);
804 CASE (WM_RBUTTONDBLCLK);
805 CASE (WM_MBUTTONDOWN);
807 CASE (WM_MBUTTONDBLCLK);
808 CASE (WM_MOUSEWHEEL);
809 CASE (WM_XBUTTONDOWN);
811 CASE (WM_XBUTTONDBLCLK);
812 CASE (WM_PARENTNOTIFY);
813 CASE (WM_ENTERMENULOOP);
814 CASE (WM_EXITMENULOOP);
817 CASE (WM_CAPTURECHANGED);
819 CASE (WM_POWERBROADCAST);
820 CASE (WM_DEVICECHANGE);
822 CASE (WM_MDIDESTROY);
823 CASE (WM_MDIACTIVATE);
824 CASE (WM_MDIRESTORE);
826 CASE (WM_MDIMAXIMIZE);
828 CASE (WM_MDICASCADE);
829 CASE (WM_MDIICONARRANGE);
830 CASE (WM_MDIGETACTIVE);
831 CASE (WM_MDISETMENU);
832 CASE (WM_ENTERSIZEMOVE);
833 CASE (WM_EXITSIZEMOVE);
835 CASE (WM_MDIREFRESHMENU);
836 CASE (WM_IME_SETCONTEXT);
837 CASE (WM_IME_NOTIFY);
838 CASE (WM_IME_CONTROL);
839 CASE (WM_IME_COMPOSITIONFULL);
840 CASE (WM_IME_SELECT);
842 CASE (WM_IME_REQUEST);
843 CASE (WM_IME_KEYDOWN);
845 CASE (WM_MOUSEHOVER);
846 CASE (WM_MOUSELEAVE);
847 CASE (WM_NCMOUSEHOVER);
848 CASE (WM_NCMOUSELEAVE);
854 CASE (WM_RENDERFORMAT);
855 CASE (WM_RENDERALLFORMATS);
856 CASE (WM_DESTROYCLIPBOARD);
857 CASE (WM_DRAWCLIPBOARD);
858 CASE (WM_PAINTCLIPBOARD);
859 CASE (WM_VSCROLLCLIPBOARD);
860 CASE (WM_SIZECLIPBOARD);
861 CASE (WM_ASKCBFORMATNAME);
862 CASE (WM_CHANGECBCHAIN);
863 CASE (WM_HSCROLLCLIPBOARD);
864 CASE (WM_QUERYNEWPALETTE);
865 CASE (WM_PALETTEISCHANGING);
866 CASE (WM_PALETTECHANGED);
869 CASE (WM_PRINTCLIENT);
870 CASE (WM_APPCOMMAND);
871 CASE (WM_HANDHELDFIRST);
872 CASE (WM_HANDHELDLAST);
875 CASE (WM_PENWINFIRST);
876 CASE (WM_PENWINLAST);
880 if (msg >= WM_HANDHELDFIRST && msg <= WM_HANDHELDLAST)
881 return static_printf ("WM_HANDHELDFIRST+%d", msg - WM_HANDHELDFIRST);
882 else if (msg >= WM_AFXFIRST && msg <= WM_AFXLAST)
883 return static_printf ("WM_AFXFIRST+%d", msg - WM_AFXFIRST);
884 else if (msg >= WM_PENWINFIRST && msg <= WM_PENWINLAST)
885 return static_printf ("WM_PENWINFIRST+%d", msg - WM_PENWINFIRST);
886 else if (msg >= WM_USER && msg <= 0x7FFF)
887 return static_printf ("WM_USER+%d", msg - WM_USER);
888 else if (msg >= 0xC000 && msg <= 0xFFFF)
889 return static_printf ("reg-%#x", msg);
891 return static_printf ("unk-%#x", msg);
898 _gdk_win32_rect_to_string (const RECT *rect)
900 return static_printf ("%ldx%ld@+%ld+%ld",
901 (rect->right - rect->left), (rect->bottom - rect->top),
902 rect->left, rect->top);
906 _gdk_win32_gdkrectangle_to_string (const GdkRectangle *rect)
908 return static_printf ("%dx%d@+%d+%d",
909 rect->width, rect->height,
914 _gdk_win32_gdkregion_to_string (const GdkRegion *rgn)
916 return static_printf ("%dx%d@+%d+%d",
917 (rgn->extents.x2 - rgn->extents.x1),
918 (rgn->extents.y2 - rgn->extents.y1),
919 rgn->extents.x1, rgn->extents.y1);
923 _gdk_win32_drawable_description (GdkDrawable *d)
928 gdk_drawable_get_size (d, &width, &height);
932 G_OBJECT_TYPE_NAME (d),
933 GDK_DRAWABLE_HANDLE (d),
935 (GDK_IS_PIXMAP (d) ? GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (d)->impl)->image->depth
936 : ((v = gdk_drawable_get_visual (d)) ? v->depth : gdk_visual_get_system ()->depth)));
939 #endif /* G_ENABLE_DEBUG */