diff options
| author | Eli Zaretskii | 2011-10-28 11:54:02 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2011-10-28 11:54:02 +0200 |
| commit | db4f02f208c551982a54f6ea1fdf3d5577572ca3 (patch) | |
| tree | bd87986140b27bd15eff69e001ed00f4ee8cc18f /src | |
| parent | 7a6c0941742d41702fb56cd492d4897e476ebc25 (diff) | |
| download | emacs-db4f02f208c551982a54f6ea1fdf3d5577572ca3.tar.gz emacs-db4f02f208c551982a54f6ea1fdf3d5577572ca3.zip | |
Fix bug #8562 with Emacs display on Windows 9X.
Thanks to oslsachem <oslsachem@gmail.com> for helping to debug this.
src/w32font.c (g_b_init_is_w9x, g_b_init_get_outline_metrics_w)
(g_b_init_get_text_metrics_w, g_b_init_get_glyph_outline_w)
(g_b_init_get_glyph_outline_w): New static variables.
(GetOutlineTextMetricsW_Proc, GetTextMetricsW_Proc)
(GetGlyphOutlineW_Proc): New typedefs.
(w32_load_unicows_or_gdi32, get_outline_metrics_w)
(get_text_metrics_w, get_glyph_outline_w, globals_of_w32font): New
functions.
(w32font_open_internal, compute_metrics): Call
get_outline_metrics_w, get_text_metrics_w, and get_glyph_outline_w
instead of calling the "wide" APIs directly.
src/emacs.c (main) [HAVE_NTGUI]: Call globals_of_w32font.
src/w32.h (syms_of_w32font): Add prototype.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 21 | ||||
| -rw-r--r-- | src/emacs.c | 1 | ||||
| -rw-r--r-- | src/w32.h | 1 | ||||
| -rw-r--r-- | src/w32font.c | 149 |
4 files changed, 168 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 0d421223228..a53c16e9da4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,24 @@ | |||
| 1 | 2011-10-28 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | Fix Emacs on Windows 9X (bug#8562). Thanks to oslsachem | ||
| 4 | <oslsachem@gmail.com> for helping to debug this. | ||
| 5 | |||
| 6 | * w32font.c (g_b_init_is_w9x, g_b_init_get_outline_metrics_w) | ||
| 7 | (g_b_init_get_text_metrics_w, g_b_init_get_glyph_outline_w) | ||
| 8 | (g_b_init_get_glyph_outline_w): New static variables. | ||
| 9 | (GetOutlineTextMetricsW_Proc, GetTextMetricsW_Proc) | ||
| 10 | (GetGlyphOutlineW_Proc): New typedefs. | ||
| 11 | (w32_load_unicows_or_gdi32, get_outline_metrics_w) | ||
| 12 | (get_text_metrics_w, get_glyph_outline_w, globals_of_w32font): New | ||
| 13 | functions. | ||
| 14 | (w32font_open_internal, compute_metrics): Call | ||
| 15 | get_outline_metrics_w, get_text_metrics_w, and get_glyph_outline_w | ||
| 16 | instead of calling the "wide" APIs directly. | ||
| 17 | |||
| 18 | * emacs.c (main) [HAVE_NTGUI]: Call globals_of_w32font. | ||
| 19 | |||
| 20 | * w32.h (syms_of_w32font): Add prototype. | ||
| 21 | |||
| 1 | 2011-10-27 Juanma Barranquero <lekktu@gmail.com> | 22 | 2011-10-27 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 23 | ||
| 3 | * window.c (Fframe_root_window, Fframe_first_window, Fwindow_end) | 24 | * window.c (Fframe_root_window, Fframe_first_window, Fwindow_end) |
diff --git a/src/emacs.c b/src/emacs.c index 073156bb0c9..12be7bc0808 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -1591,6 +1591,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1591 | /* Initialization that must be done even if the global variable | 1591 | /* Initialization that must be done even if the global variable |
| 1592 | initialized is non zero. */ | 1592 | initialized is non zero. */ |
| 1593 | #ifdef HAVE_NTGUI | 1593 | #ifdef HAVE_NTGUI |
| 1594 | globals_of_w32font (); | ||
| 1594 | globals_of_w32fns (); | 1595 | globals_of_w32fns (); |
| 1595 | globals_of_w32menu (); | 1596 | globals_of_w32menu (); |
| 1596 | globals_of_w32select (); | 1597 | globals_of_w32select (); |
| @@ -139,6 +139,7 @@ extern void term_w32select (void); | |||
| 139 | extern void syms_of_w32menu (void); | 139 | extern void syms_of_w32menu (void); |
| 140 | extern void globals_of_w32menu (void); | 140 | extern void globals_of_w32menu (void); |
| 141 | extern void syms_of_fontset (void); | 141 | extern void syms_of_fontset (void); |
| 142 | extern void syms_of_w32font (void); | ||
| 142 | 143 | ||
| 143 | extern int _sys_read_ahead (int fd); | 144 | extern int _sys_read_ahead (int fd); |
| 144 | extern int _sys_wait_accept (int fd); | 145 | extern int _sys_wait_accept (int fd); |
diff --git a/src/w32font.c b/src/w32font.c index f47b7a46b1e..fb41989caa7 100644 --- a/src/w32font.c +++ b/src/w32font.c | |||
| @@ -145,6 +145,137 @@ struct font_callback_data | |||
| 145 | style variations if the font name is not specified. */ | 145 | style variations if the font name is not specified. */ |
| 146 | static void list_all_matching_fonts (struct font_callback_data *); | 146 | static void list_all_matching_fonts (struct font_callback_data *); |
| 147 | 147 | ||
| 148 | static BOOL g_b_init_is_w9x; | ||
| 149 | static BOOL g_b_init_get_outline_metrics_w; | ||
| 150 | static BOOL g_b_init_get_text_metrics_w; | ||
| 151 | static BOOL g_b_init_get_glyph_outline_w; | ||
| 152 | static BOOL g_b_init_get_glyph_outline_w; | ||
| 153 | |||
| 154 | typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) ( | ||
| 155 | HDC hdc, | ||
| 156 | UINT cbData, | ||
| 157 | LPOUTLINETEXTMETRICW lpotmw); | ||
| 158 | typedef BOOL (WINAPI * GetTextMetricsW_Proc) ( | ||
| 159 | HDC hdc, | ||
| 160 | LPTEXTMETRICW lptmw); | ||
| 161 | typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) ( | ||
| 162 | HDC hdc, | ||
| 163 | UINT uChar, | ||
| 164 | UINT uFormat, | ||
| 165 | LPGLYPHMETRICS lpgm, | ||
| 166 | DWORD cbBuffer, | ||
| 167 | LPVOID lpvBuffer, | ||
| 168 | const MAT2 *lpmat2); | ||
| 169 | |||
| 170 | /* Several "wide" functions we use to support the font backends are | ||
| 171 | unavailable on Windows 9X, unless UNICOWS.DLL is installed (their | ||
| 172 | versions in the default libraries are non-functional stubs). On NT | ||
| 173 | and later systems, these functions are in GDI32.DLL. The following | ||
| 174 | helper function attempts to load UNICOWS.DLL on Windows 9X, and | ||
| 175 | refuses to let Emacs start up if that library is not found. On NT | ||
| 176 | and later versions, it simply loads GDI32.DLL, which should always | ||
| 177 | be available. */ | ||
| 178 | static HMODULE | ||
| 179 | w32_load_unicows_or_gdi32 (void) | ||
| 180 | { | ||
| 181 | static BOOL is_9x = 0; | ||
| 182 | OSVERSIONINFO os_ver; | ||
| 183 | HMODULE ret; | ||
| 184 | if (g_b_init_is_w9x == 0) | ||
| 185 | { | ||
| 186 | g_b_init_is_w9x = 1; | ||
| 187 | ZeroMemory (&os_ver, sizeof (OSVERSIONINFO)); | ||
| 188 | os_ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); | ||
| 189 | if (GetVersionEx (&os_ver)) | ||
| 190 | is_9x = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); | ||
| 191 | } | ||
| 192 | if (is_9x) | ||
| 193 | { | ||
| 194 | ret = LoadLibrary ("Unicows.dll"); | ||
| 195 | if (!ret) | ||
| 196 | { | ||
| 197 | int button; | ||
| 198 | |||
| 199 | button = MessageBox (NULL, | ||
| 200 | "Emacs cannot load the UNICOWS.DLL library.\n" | ||
| 201 | "This library is essential for using Emacs\n" | ||
| 202 | "on this system. You need to install it.\n\n" | ||
| 203 | "However, you can still use Emacs by invoking\n" | ||
| 204 | "it with the '-nw' command-line option.\n\n" | ||
| 205 | "Emacs will exit when you click OK.", | ||
| 206 | "Emacs cannot load UNICOWS.DLL", | ||
| 207 | MB_ICONERROR | MB_TASKMODAL | ||
| 208 | | MB_SETFOREGROUND | MB_OK); | ||
| 209 | switch (button) | ||
| 210 | { | ||
| 211 | case IDOK: | ||
| 212 | default: | ||
| 213 | exit (1); | ||
| 214 | } | ||
| 215 | } | ||
| 216 | } | ||
| 217 | else | ||
| 218 | ret = LoadLibrary ("Gdi32.dll"); | ||
| 219 | } | ||
| 220 | |||
| 221 | /* The following 3 functions call the problematic "wide" APIs via | ||
| 222 | function pointers, to avoid linking against the non-standard | ||
| 223 | libunicows on W9X. */ | ||
| 224 | static UINT WINAPI | ||
| 225 | get_outline_metrics_w(HDC hdc, UINT cbData, LPOUTLINETEXTMETRICW lpotmw) | ||
| 226 | { | ||
| 227 | static GetOutlineTextMetricsW_Proc s_pfn_Get_Outline_Text_MetricsW = NULL; | ||
| 228 | HMODULE hm_unicows = NULL; | ||
| 229 | if (g_b_init_get_outline_metrics_w == 0) | ||
| 230 | { | ||
| 231 | g_b_init_get_outline_metrics_w = 1; | ||
| 232 | hm_unicows = w32_load_unicows_or_gdi32 (); | ||
| 233 | if (hm_unicows) | ||
| 234 | s_pfn_Get_Outline_Text_MetricsW = (GetOutlineTextMetricsW_Proc) | ||
| 235 | GetProcAddress (hm_unicows, "GetOutlineTextMetricsW"); | ||
| 236 | } | ||
| 237 | if (s_pfn_Get_Outline_Text_MetricsW == NULL) | ||
| 238 | abort (); /* cannot happen */ | ||
| 239 | return s_pfn_Get_Outline_Text_MetricsW (hdc, cbData, lpotmw); | ||
| 240 | } | ||
| 241 | |||
| 242 | static BOOL WINAPI | ||
| 243 | get_text_metrics_w(HDC hdc, LPTEXTMETRICW lptmw) | ||
| 244 | { | ||
| 245 | static GetTextMetricsW_Proc s_pfn_Get_Text_MetricsW = NULL; | ||
| 246 | HMODULE hm_unicows = NULL; | ||
| 247 | if (g_b_init_get_text_metrics_w == 0) | ||
| 248 | { | ||
| 249 | g_b_init_get_text_metrics_w = 1; | ||
| 250 | hm_unicows = w32_load_unicows_or_gdi32 (); | ||
| 251 | if (hm_unicows) | ||
| 252 | s_pfn_Get_Text_MetricsW = (GetTextMetricsW_Proc) | ||
| 253 | GetProcAddress (hm_unicows, "GetTextMetricsW"); | ||
| 254 | } | ||
| 255 | if (s_pfn_Get_Text_MetricsW == NULL) | ||
| 256 | abort (); /* cannot happen */ | ||
| 257 | return s_pfn_Get_Text_MetricsW (hdc, lptmw); | ||
| 258 | } | ||
| 259 | |||
| 260 | static DWORD WINAPI | ||
| 261 | get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm, | ||
| 262 | DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2) | ||
| 263 | { | ||
| 264 | static GetGlyphOutlineW_Proc s_pfn_Get_Glyph_OutlineW = NULL; | ||
| 265 | HMODULE hm_unicows = NULL; | ||
| 266 | if (g_b_init_get_glyph_outline_w == 0) | ||
| 267 | { | ||
| 268 | g_b_init_get_glyph_outline_w = 1; | ||
| 269 | hm_unicows = w32_load_unicows_or_gdi32 (); | ||
| 270 | if (hm_unicows) | ||
| 271 | s_pfn_Get_Glyph_OutlineW = (GetGlyphOutlineW_Proc) | ||
| 272 | GetProcAddress (hm_unicows, "GetGlyphOutlineW"); | ||
| 273 | } | ||
| 274 | if (s_pfn_Get_Glyph_OutlineW == NULL) | ||
| 275 | abort (); /* cannot happen */ | ||
| 276 | return s_pfn_Get_Glyph_OutlineW (hdc, uChar, uFormat, lpgm, cbBuffer, | ||
| 277 | lpvBuffer, lpmat2); | ||
| 278 | } | ||
| 148 | 279 | ||
| 149 | static int | 280 | static int |
| 150 | memq_no_quit (Lisp_Object elt, Lisp_Object list) | 281 | memq_no_quit (Lisp_Object elt, Lisp_Object list) |
| @@ -816,11 +947,11 @@ w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity, | |||
| 816 | old_font = SelectObject (dc, hfont); | 947 | old_font = SelectObject (dc, hfont); |
| 817 | 948 | ||
| 818 | /* Try getting the outline metrics (only works for truetype fonts). */ | 949 | /* Try getting the outline metrics (only works for truetype fonts). */ |
| 819 | len = GetOutlineTextMetricsW (dc, 0, NULL); | 950 | len = get_outline_metrics_w (dc, 0, NULL); |
| 820 | if (len) | 951 | if (len) |
| 821 | { | 952 | { |
| 822 | metrics = (OUTLINETEXTMETRICW *) alloca (len); | 953 | metrics = (OUTLINETEXTMETRICW *) alloca (len); |
| 823 | if (GetOutlineTextMetricsW (dc, len, metrics)) | 954 | if (get_outline_metrics_w (dc, len, metrics)) |
| 824 | memcpy (&w32_font->metrics, &metrics->otmTextMetrics, | 955 | memcpy (&w32_font->metrics, &metrics->otmTextMetrics, |
| 825 | sizeof (TEXTMETRICW)); | 956 | sizeof (TEXTMETRICW)); |
| 826 | else | 957 | else |
| @@ -828,7 +959,7 @@ w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity, | |||
| 828 | } | 959 | } |
| 829 | 960 | ||
| 830 | if (!metrics) | 961 | if (!metrics) |
| 831 | GetTextMetricsW (dc, &w32_font->metrics); | 962 | get_text_metrics_w (dc, &w32_font->metrics); |
| 832 | 963 | ||
| 833 | w32_font->cached_metrics = NULL; | 964 | w32_font->cached_metrics = NULL; |
| 834 | w32_font->n_cache_blocks = 0; | 965 | w32_font->n_cache_blocks = 0; |
| @@ -2306,7 +2437,7 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code, | |||
| 2306 | transform.eM11.value = 1; | 2437 | transform.eM11.value = 1; |
| 2307 | transform.eM22.value = 1; | 2438 | transform.eM22.value = 1; |
| 2308 | 2439 | ||
| 2309 | if (GetGlyphOutlineW (dc, code, options, &gm, 0, NULL, &transform) | 2440 | if (get_glyph_outline_w (dc, code, options, &gm, 0, NULL, &transform) |
| 2310 | != GDI_ERROR) | 2441 | != GDI_ERROR) |
| 2311 | { | 2442 | { |
| 2312 | metrics->lbearing = gm.gmptGlyphOrigin.x; | 2443 | metrics->lbearing = gm.gmptGlyphOrigin.x; |
| @@ -2581,3 +2712,13 @@ versions of Windows) characters. */); | |||
| 2581 | w32font_driver.type = Qgdi; | 2712 | w32font_driver.type = Qgdi; |
| 2582 | register_font_driver (&w32font_driver, NULL); | 2713 | register_font_driver (&w32font_driver, NULL); |
| 2583 | } | 2714 | } |
| 2715 | |||
| 2716 | void | ||
| 2717 | globals_of_w32font (void) | ||
| 2718 | { | ||
| 2719 | g_b_init_is_w9x = 0; | ||
| 2720 | g_b_init_get_outline_metrics_w = 0; | ||
| 2721 | g_b_init_get_text_metrics_w = 0; | ||
| 2722 | g_b_init_get_glyph_outline_w = 0; | ||
| 2723 | } | ||
| 2724 | |||