aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2011-10-28 11:54:02 +0200
committerEli Zaretskii2011-10-28 11:54:02 +0200
commitdb4f02f208c551982a54f6ea1fdf3d5577572ca3 (patch)
treebd87986140b27bd15eff69e001ed00f4ee8cc18f /src
parent7a6c0941742d41702fb56cd492d4897e476ebc25 (diff)
downloademacs-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/ChangeLog21
-rw-r--r--src/emacs.c1
-rw-r--r--src/w32.h1
-rw-r--r--src/w32font.c149
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 @@
12011-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
12011-10-27 Juanma Barranquero <lekktu@gmail.com> 222011-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 ();
diff --git a/src/w32.h b/src/w32.h
index f1915125c90..a3ca1130ce6 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -139,6 +139,7 @@ extern void term_w32select (void);
139extern void syms_of_w32menu (void); 139extern void syms_of_w32menu (void);
140extern void globals_of_w32menu (void); 140extern void globals_of_w32menu (void);
141extern void syms_of_fontset (void); 141extern void syms_of_fontset (void);
142extern void syms_of_w32font (void);
142 143
143extern int _sys_read_ahead (int fd); 144extern int _sys_read_ahead (int fd);
144extern int _sys_wait_accept (int fd); 145extern 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. */
146static void list_all_matching_fonts (struct font_callback_data *); 146static void list_all_matching_fonts (struct font_callback_data *);
147 147
148static BOOL g_b_init_is_w9x;
149static BOOL g_b_init_get_outline_metrics_w;
150static BOOL g_b_init_get_text_metrics_w;
151static BOOL g_b_init_get_glyph_outline_w;
152static BOOL g_b_init_get_glyph_outline_w;
153
154typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) (
155 HDC hdc,
156 UINT cbData,
157 LPOUTLINETEXTMETRICW lpotmw);
158typedef BOOL (WINAPI * GetTextMetricsW_Proc) (
159 HDC hdc,
160 LPTEXTMETRICW lptmw);
161typedef 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. */
178static HMODULE
179w32_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. */
224static UINT WINAPI
225get_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
242static BOOL WINAPI
243get_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
260static DWORD WINAPI
261get_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
149static int 280static int
150memq_no_quit (Lisp_Object elt, Lisp_Object list) 281memq_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
2716void
2717globals_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