From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#8562: Emacs 23.1 and later don't work in windows 98 Date: Sat, 01 Oct 2011 14:03:11 +0300 Message-ID: <83ehyxc6ts.fsf@gnu.org> References: <83d3k88k6o.fsf@gnu.org> <83wri4kpwb.fsf@gnu.org> <83d3j9e2pn.fsf@gnu.org> <8339k3esws.fsf@gnu.org> <83wrhed91s.fsf@gnu.org> <838vtscbeu.fsf@gnu.org> <83vcwvc1eq.fsf@gnu.org> <83vcwsf2ra.fsf@gnu.org> <83k4d6fuph.fsf@gnu.org> <83pqmve2s2.fsf@gnu.org> <837h92dqai.fsf@gnu.org> <83r579c6wn.fsf@gnu.org> <8362ohcrht.fsf@gnu.org> Reply-To: Eli Zaretskii NNTP-Posting-Host: lo.gmane.org X-Trace: dough.gmane.org 1317467107 7260 80.91.229.12 (1 Oct 2011 11:05:07 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 1 Oct 2011 11:05:07 +0000 (UTC) Cc: 8562@debbugs.gnu.org To: oslsachem@gmail.com Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Oct 01 13:05:01 2011 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1R9xNL-0006sw-7G for geb-bug-gnu-emacs@m.gmane.org; Sat, 01 Oct 2011 13:04:59 +0200 Original-Received: from localhost ([::1]:53687 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R9xNK-00088f-B8 for geb-bug-gnu-emacs@m.gmane.org; Sat, 01 Oct 2011 07:04:58 -0400 Original-Received: from eggs.gnu.org ([140.186.70.92]:34138) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R9xNG-00088V-GL for bug-gnu-emacs@gnu.org; Sat, 01 Oct 2011 07:04:56 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R9xNE-0007Eb-4m for bug-gnu-emacs@gnu.org; Sat, 01 Oct 2011 07:04:54 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:56415) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R9xNE-0007EJ-2v for bug-gnu-emacs@gnu.org; Sat, 01 Oct 2011 07:04:52 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.69) (envelope-from ) id 1R9xOM-0002L4-CR for bug-gnu-emacs@gnu.org; Sat, 01 Oct 2011 07:06:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 01 Oct 2011 11:06:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 8562 X-GNU-PR-Package: emacs,w32 X-GNU-PR-Keywords: Original-Received: via spool by 8562-submit@debbugs.gnu.org id=B8562.13174671228946 (code B ref 8562); Sat, 01 Oct 2011 11:06:02 +0000 Original-Received: (at 8562) by debbugs.gnu.org; 1 Oct 2011 11:05:22 +0000 Original-Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1R9xNh-0002KF-Jv for submit@debbugs.gnu.org; Sat, 01 Oct 2011 07:05:22 -0400 Original-Received: from mtaout20.012.net.il ([80.179.55.166]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1R9xNd-0002K4-Tc for 8562@debbugs.gnu.org; Sat, 01 Oct 2011 07:05:20 -0400 Original-Received: from conversion-daemon.a-mtaout20.012.net.il by a-mtaout20.012.net.il (HyperSendmail v2007.08) id <0LSD00700W07F800@a-mtaout20.012.net.il> for 8562@debbugs.gnu.org; Sat, 01 Oct 2011 14:03:10 +0300 (IDT) Original-Received: from HOME-C4E4A596F7 ([77.126.229.231]) by a-mtaout20.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0LSD0073UW17EW10@a-mtaout20.012.net.il>; Sat, 01 Oct 2011 14:03:09 +0300 (IDT) In-reply-to: <8362ohcrht.fsf@gnu.org> X-012-Sender: halo1@inter.net.il X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Resent-Date: Sat, 01 Oct 2011 07:06:02 -0400 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 1) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:52038 Archived-At: > Date: Tue, 07 Jun 2011 23:32:14 +0300 > From: Eli Zaretskii > Cc: 8562@debbugs.gnu.org > > > The binary works without any noticeable problem. > > Thank you. I will prepare an official patch for that, which should > work both on Windows 9X and on the NT family of Windows, and will ask > you to test it. Sorry for such a long delay, I got distracted by issues that needed to be resolved before Emacs 24 enters the pretest. Please find below a patch that should let Emacs work correctly on Windows 9X systems that have UNICOWS.DLL installed. If UNICOWS.DLL is not installed, Emacs should pop up an error dialog to that effect, and refuse to start up. "emacs -nw" should be possible even if that DLL is not available. Please give this a try, both with and without UNICOWS.DLL available, and see if the results are good. I will then install this in the development trunk, and this will be available as part of Emacs 24.1. It is best to try this in the current development code, or with the emacs-24.0.90 pretest (which you can find on alpha.gnu.org). Thanks again for your great help in resolving this issue. Here's the patch to apply: === modified file 'src/ChangeLog' --- src/ChangeLog 2011-09-30 20:22:01 +0000 +++ src/ChangeLog 2011-10-01 10:55:28 +0000 @@ -1,3 +1,24 @@ +2011-10-01 Eli Zaretskii + + Fix Emacs on Windows 9X (bug#8562). + Thanks to oslsachem for debugging this. + + * 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. + + * emacs.c (main) [HAVE_NTGUI]: Call globals_of_w32font. + + * w32.h (syms_of_w32font): Add prototype. + 2011-09-30 Paul Eggert * buffer.h (struct buffer): Use time_t, not int, for a time stamp. === modified file 'src/emacs.c' --- src/emacs.c 2011-09-24 09:22:06 +0000 +++ src/emacs.c 2011-10-01 10:06:12 +0000 @@ -1591,6 +1591,7 @@ Using an Emacs configured with --with-x- /* Initialization that must be done even if the global variable initialized is non zero. */ #ifdef HAVE_NTGUI + globals_of_w32font (); globals_of_w32fns (); globals_of_w32menu (); globals_of_w32select (); === modified file 'src/w32.h' --- src/w32.h 2011-05-04 14:03:16 +0000 +++ src/w32.h 2011-10-01 10:11:20 +0000 @@ -139,6 +139,7 @@ extern void term_w32select (void); extern void syms_of_w32menu (void); extern void globals_of_w32menu (void); extern void syms_of_fontset (void); +extern void syms_of_w32font (void); extern int _sys_read_ahead (int fd); extern int _sys_wait_accept (int fd); === modified file 'src/w32font.c' --- src/w32font.c 2011-05-12 07:07:06 +0000 +++ src/w32font.c 2011-10-01 10:43:40 +0000 @@ -145,6 +145,137 @@ struct font_callback_data style variations if the font name is not specified. */ static void list_all_matching_fonts (struct font_callback_data *); +static BOOL g_b_init_is_w9x; +static BOOL g_b_init_get_outline_metrics_w; +static BOOL g_b_init_get_text_metrics_w; +static BOOL g_b_init_get_glyph_outline_w; +static BOOL g_b_init_get_glyph_outline_w; + +typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) ( + HDC hdc, + UINT cbData, + LPOUTLINETEXTMETRICW lpotmw); +typedef BOOL (WINAPI * GetTextMetricsW_Proc) ( + HDC hdc, + LPTEXTMETRICW lptmw); +typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) ( + HDC hdc, + UINT uChar, + UINT uFormat, + LPGLYPHMETRICS lpgm, + DWORD cbBuffer, + LPVOID lpvBuffer, + const MAT2 *lpmat2); + +/* Several "wide" functions we use to support the font backends are + unavailable on Windows 9X, unless UNICOWS.DLL is installed (their + versions in the default libraries are non-functional stubs). On NT + and later systems, these functions are in GDI32.DLL. The following + helper function attempts to load UNICOWS.DLL on Windows 9X, and + refuses to let Emacs start up if that library is not found. On NT + and later versions, it simply loads GDI32.DLL, which should always + be available. */ +static HMODULE +w32_load_unicows_or_gdi32 (void) +{ + static BOOL is_9x = 0; + OSVERSIONINFO os_ver; + HMODULE ret; + if (g_b_init_is_w9x == 0) + { + g_b_init_is_w9x = 1; + ZeroMemory (&os_ver, sizeof (OSVERSIONINFO)); + os_ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + if (GetVersionEx (&os_ver)) + is_9x = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); + } + if (is_9x) + { + ret = LoadLibrary ("Unicows.dll"); + if (!ret) + { + int button; + + button = MessageBox (NULL, + "Emacs cannot load the UNICOWS.DLL library.\n" + "This library is essential for using Emacs\n" + "on this system. You need to install it.\n\n" + "However, you can still use Emacs by invoking\n" + "it with the '-nw' command-line option.\n\n" + "Emacs will exit when you click OK.", + "Emacs cannot load UNICOWS.DLL", + MB_ICONERROR | MB_TASKMODAL + | MB_SETFOREGROUND | MB_OK); + switch (button) + { + case IDOK: + default: + exit (1); + } + } + } + else + ret = LoadLibrary ("Gdi32.dll"); +} + +/* The following 3 functions call the problematic "wide" APIs via + function pointers, to avoid linking against the non-standard + libunicows on W9X. */ +static UINT WINAPI +get_outline_metrics_w(HDC hdc, UINT cbData, LPOUTLINETEXTMETRICW lpotmw) +{ + static GetOutlineTextMetricsW_Proc s_pfn_Get_Outline_Text_MetricsW = NULL; + HMODULE hm_unicows = NULL; + if (g_b_init_get_outline_metrics_w == 0) + { + g_b_init_get_outline_metrics_w = 1; + hm_unicows = w32_load_unicows_or_gdi32 (); + if (hm_unicows) + s_pfn_Get_Outline_Text_MetricsW = (GetOutlineTextMetricsW_Proc) + GetProcAddress (hm_unicows, "GetOutlineTextMetricsW"); + } + if (s_pfn_Get_Outline_Text_MetricsW == NULL) + abort (); /* cannot happen */ + return s_pfn_Get_Outline_Text_MetricsW (hdc, cbData, lpotmw); +} + +static BOOL WINAPI +get_text_metrics_w(HDC hdc, LPTEXTMETRICW lptmw) +{ + static GetTextMetricsW_Proc s_pfn_Get_Text_MetricsW = NULL; + HMODULE hm_unicows = NULL; + if (g_b_init_get_text_metrics_w == 0) + { + g_b_init_get_text_metrics_w = 1; + hm_unicows = w32_load_unicows_or_gdi32 (); + if (hm_unicows) + s_pfn_Get_Text_MetricsW = (GetTextMetricsW_Proc) + GetProcAddress (hm_unicows, "GetTextMetricsW"); + } + if (s_pfn_Get_Text_MetricsW == NULL) + abort (); /* cannot happen */ + return s_pfn_Get_Text_MetricsW (hdc, lptmw); +} + +static DWORD WINAPI +get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm, + DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2) +{ + static GetGlyphOutlineW_Proc s_pfn_Get_Glyph_OutlineW = NULL; + HMODULE hm_unicows = NULL; + if (g_b_init_get_glyph_outline_w == 0) + { + g_b_init_get_glyph_outline_w = 1; + hm_unicows = w32_load_unicows_or_gdi32 (); + if (hm_unicows) + s_pfn_Get_Glyph_OutlineW = (GetGlyphOutlineW_Proc) + GetProcAddress (hm_unicows, "GetGlyphOutlineW"); + } + if (s_pfn_Get_Glyph_OutlineW == NULL) + abort (); /* cannot happen */ + return s_pfn_Get_Glyph_OutlineW (hdc, uChar, uFormat, lpgm, cbBuffer, + lpvBuffer, lpmat2); +} static int memq_no_quit (Lisp_Object elt, Lisp_Object list) @@ -816,11 +947,11 @@ w32font_open_internal (FRAME_PTR f, Lisp old_font = SelectObject (dc, hfont); /* Try getting the outline metrics (only works for truetype fonts). */ - len = GetOutlineTextMetricsW (dc, 0, NULL); + len = get_outline_metrics_w (dc, 0, NULL); if (len) { metrics = (OUTLINETEXTMETRICW *) alloca (len); - if (GetOutlineTextMetricsW (dc, len, metrics)) + if (get_outline_metrics_w (dc, len, metrics)) memcpy (&w32_font->metrics, &metrics->otmTextMetrics, sizeof (TEXTMETRICW)); else @@ -828,7 +959,7 @@ w32font_open_internal (FRAME_PTR f, Lisp } if (!metrics) - GetTextMetricsW (dc, &w32_font->metrics); + get_text_metrics_w (dc, &w32_font->metrics); w32_font->cached_metrics = NULL; w32_font->n_cache_blocks = 0; @@ -2306,7 +2437,7 @@ compute_metrics (HDC dc, struct w32font_ transform.eM11.value = 1; transform.eM22.value = 1; - if (GetGlyphOutlineW (dc, code, options, &gm, 0, NULL, &transform) + if (get_glyph_outline_w (dc, code, options, &gm, 0, NULL, &transform) != GDI_ERROR) { metrics->lbearing = gm.gmptGlyphOrigin.x; @@ -2581,3 +2712,13 @@ versions of Windows) characters. */); w32font_driver.type = Qgdi; register_font_driver (&w32font_driver, NULL); } + +void +globals_of_w32font (void) +{ + g_b_init_is_w9x = 0; + g_b_init_get_outline_metrics_w = 0; + g_b_init_get_text_metrics_w = 0; + g_b_init_get_glyph_outline_w = 0; +} +